zoukankan      html  css  js  c++  java
  • java 验证码图片处理类,为验证码识别做准备

    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package snailocr.util;

    import java.awt.Color;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.imageio.ImageIO;

    /**
     *
     * @author Administrator
     */
    public class ImageTool {

        private BufferedImage image;
        private int width;
        private int height;

        /**
         * 变图像为黑白色 提示: 黑白化之前最好灰色化以便得到好的灰度平均值,利于获得好的黑白效果
         *
         * @return
         */
        public ImageTool changeToBlackWhiteImage() {
            int avgGrayValue = getAvgValue();
            int whitePoint = getWhitePoint(), blackPoint = getBlackPoint();

            Color point;
            for (int i = 0; i < height; i++) {
                for (int j = 0; j < width; j++) {
                    point = new Color(image.getRGB(j, i));
                    image.setRGB(j, i, (point.getRed() < avgGrayValue ? blackPoint : whitePoint));
                }
            }
            return this;
        }

        /**
         *
         *
         * @param whiteAreaPercent 过滤之后白色区域面积占整个图片面积的最小百分比
         * @param removeLighter true:过滤比中值颜色轻的,false:过滤比中值颜色重的,一般都是true
         * @return
         */
        public ImageTool midddleValueFilter(int whiteAreaMinPercent, boolean removeLighter) {
            int modify = 0;
            int avg = getAvgValue();
            Color point;
            while (getWhitePercent() < whiteAreaMinPercent) {
                for (int i = 0; i < height; i++) {
                    for (int j = 0; j < width; j++) {
                        point = new Color(image.getRGB(j, i));
                        if (removeLighter) {
                            if (((point.getRed() + point.getGreen() + point.getBlue()) / 3) > avg - modify) {
    //                         System.out.println(((point.getRed() + point.getGreen() + point.getBlue()) / 3)+"--"+(avg - modify));
                                image.setRGB(j, i, getWhitePoint());
                            }
                        } else {
                            if (((point.getRed() + point.getGreen() + point.getBlue()) / 3) < avg + modify) {
    //                         System.out.println(((point.getRed() + point.getGreen() + point.getBlue()) / 3)+"--"+(avg - modify));
                                image.setRGB(j, i, getWhitePoint());
                            }
                        }

                    }
                }
                modify++;
            }
    //        System.out.println(getWhitePercent());
            return this;
        }

        private int getWhitePercent() {
            Color point;
            int white = 0;
            for (int i = 0; i < height; i++) {
                for (int j = 0; j < width; j++) {
                    point = new Color(image.getRGB(j, i));
                    if (((point.getRed() + point.getGreen() + point.getBlue()) / 3) == 255) {
                        white++;
                    }
                }
            }
            return (int) Math.ceil(((float) white * 100 / (width * height)));
        }

        /**
         * @param 变图像为灰色 取像素点的rgb三色平均值作为灰度值
         *
         * @return
         */
        public ImageTool changeToGrayImage() {
            int gray;
            Color point;
            for (int i = 0; i < height; i++) {
                for (int j = 0; j < width; j++) {
                    point = new Color(image.getRGB(j, i));
                    gray = (point.getRed() + point.getGreen() + point.getBlue()) / 3;
                    image.setRGB(j, i, new Color(gray, gray, gray).getRGB());
                }
            }
            return this;
        }

        /**
         *
         * 去除噪点和单点组成的干扰线 注意: 去除噪点之前应该对图像黑白化
         *
         * @param neighborhoodMinCount 每个点最少的邻居数
         * @return
         */
        public ImageTool removeBadBlock(int blockWidth, int blockHeight, int neighborhoodMinCount) {
            int val;
            int whitePoint = getWhitePoint();
            int counter, topLeftXIndex, topLeftYIndex;
            for (int y = 0; y < height; y++) {
                for (int x = 0; x < width; x++) {
                    //初始化邻居数为0
                    counter = 0;
                    topLeftXIndex = x - 1;
                    topLeftYIndex = y - 1;
                    //x1 y1是以x,y左上角点为顶点的矩形,该矩形包围在传入的矩形的外围,计算传入的矩形的有效邻居数目
                    if (isBlackBlock(x, y, blockWidth, blockHeight)) {//只有当块是全黑色才计算
                        for (int x1 = topLeftXIndex; x1 <= topLeftXIndex + blockWidth + 1; x1++) {
                            for (int y1 = topLeftYIndex; y1 <= topLeftYIndex + blockHeight + 1; y1++) {
                                //判断这个点是否存在
                                if (x1 < width && x1 >= 0 && y1 < height && y1 >= 0) {
                                    //判断这个点是否是传入矩形的外围点
                                    if (x1 == topLeftXIndex || x1 == topLeftXIndex + blockWidth + 1
                                            || y1 == topLeftYIndex || y1 == topLeftYIndex + blockHeight + 1) {
                                        //这里假定图像已经被黑白化,取Red值认为不是0就是255
                                        val = new Color(image.getRGB(x1, y1)).getRed();
    //                                System.out.println(val + "--" + (centerVal));
                                        //如果这个邻居是黑色,就把中心点的有效邻居数目加一
                                        if (val == 0) {
                                            counter++;
                                        }
                                    }
                                }
                            }
                        }
    //                    System.out.println("-------------------");
    //                System.out.println(x+"-"+y+"-"+counter);
                        if (counter < neighborhoodMinCount) {
                            image.setRGB(x, y, whitePoint);
                        }
                    }
                }
            }
            return this;
        }

        /**
         * 如果点周围的黑点数达到补偿值就把这个点变为黑色
         *
         * @param addFlag 补偿阀值,通过观察处理过的图像确定,一般为2即可
         * @return
         */
        public ImageTool modifyBlank(int addFlag) {
            int val, counter = 0, topLeftXIndex, topLeftYIndex, blackPoint = getBlackPoint();
            Color point;
            for (int y = 0; y < height; y++) {
                for (int x = 0; x < width; x++) {
                    //初始化邻居数为0
                    counter = 0;
                    topLeftXIndex = x - 1;
                    topLeftYIndex = y - 1;
                    point = new Color(image.getRGB(x, y));
                    //这里假定图像已经被黑白化,取Red值认为不是0就是255
                    val = point.getRed();
                    //只有白点才进行补偿
                    if (val == 255) {
                        for (int x1 = topLeftXIndex; x1 <= topLeftXIndex + 2; x1++) {
                            for (int y1 = topLeftYIndex; y1 <= topLeftYIndex + 2; y1++) {
                                //判断这个点是否存在
                                if (x1 < width && x1 >= 0 && y1 < height && y1 >= 0) {
                                    //判断这个点是否是传入点的外围点
                                    if (x1 == topLeftXIndex || x1 == topLeftXIndex + 2
                                            || y1 == topLeftYIndex || y1 == topLeftYIndex + 2) {
                                        //这里假定图像已经被黑白化,取Red值认为不是0就是255
                                        val = new Color(image.getRGB(x1, y1)).getRed();
    //                                System.out.println(val + "--" + (centerVal));
                                        //如果这个邻居是黑色,就把中心点的补偿数目加一
                                        if (val == 0) {
                                            counter++;
                                        }
                                    }
                                }
                            }
                        }
                        //如果这个点周围的黑点数达到补偿值就把这个点变为黑色
                        if (counter >= addFlag) {
                            image.setRGB(x, y, blackPoint);
                        }
                    }
                }
            }
            return this;
        }

        public BufferedImage getBufferedImage(String filename) {
            File file = new File(filename);
            try {
                return ImageIO.read(file);
            } catch (IOException ex) {
                Logger.getLogger(ImageTool.class.getName()).log(Level.SEVERE, null, ex);
                return null;
            }
        }

        private boolean isBlackBlock(int startX, int startY, int blockWidth, int blockHeight) {
            int counter = 0;//统计黑色像素点的个数
            int total = 0;//统计有效像素点的个数
            int val;
            for (int x1 = startX; x1 <= startX + blockWidth - 1; x1++) {
                for (int y1 = startY; y1 <= startY + blockHeight - 1; y1++) {
                    //判断这个点是否存在
                    if (x1 < width && x1 >= 0 && y1 < height && y1 >= 0) {
                        total++;//有效像素点的个数
                        //这里假定图像已经被黑白化,取Red值认为不是0就是255
                        val = new Color(image.getRGB(x1, y1)).getRed();
                        //如果这个点是黑色,就把黑色像素点的数目加一
                        if (val == 0) {
                            counter++;
                        }
                    }
                }
            }
    //        System.out.println(startX + "--" + startY + "" + (counter == total&&total!=0));
            return counter == total && total != 0;
        }

        private int getWhitePoint() {
            return (new Color(255, 255, 255).getRGB() & 0xffffffff);
        }

        private int getBlackPoint() {
            return (new Color(0, 0, 0).getRGB() & 0xffffffff);
        }

        private int getAvgValue() {
            Color point;
            int total = 0;
            for (int i = 0; i < height; i++) {
                for (int j = 0; j < width; j++) {
                    point = new Color(image.getRGB(j, i));
                    total += (point.getRed() + point.getGreen() + point.getBlue()) / 3;
                }
            }
            return total / (width * height);
        }

        public void saveToFile(String filePath) {
            try {
                String ext = filePath.substring(filePath.lastIndexOf(".") + 1);
                File newFile = new File(filePath);
                ImageIO.write(image, ext, newFile);
            } catch (IOException ex) {
                Logger.getLogger(ImageTool.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        public BufferedImage getImage() {
            return image;
        }

        public void setImage(BufferedImage image) {
            this.image = image;
            width = image.getWidth();
            height = image.getHeight();
        }
    }

  • 相关阅读:
    再谈TextField
    IOS-TextField知多少
    leftBarButtonItems
    LeftBarButtonItems,定制导航栏返回按钮
    Apple Mach-O Linker (id) Error "_OBJC_CLASS...错误解决办法 Apple Mach-O Linker (id) Error "_OBJC_CLASS...错误解决办法
    Unrecognized Selector Sent to Instance问题之诱敌深入关门打狗解决办法
    UNRECOGNIZED SELECTOR SENT TO INSTANCE 问题快速定位的方法
    Present ViewController,模态详解
    UILABEL AUTOLAYOUT自动换行 版本区别
    iOS自动布局解决警告Automatic Preferred Max Layout Width is not available on iOS versions prior to 8.0
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/3531919.html
Copyright © 2011-2022 走看看