zoukankan      html  css  js  c++  java
  • Java图片比对

     在自动化测试中,除了普通的值验证,经常还有一些图片验证,比如图片的匹配率,输出图片的差异图片等。本文主要用到了BufferedImage类来操作图片比对和输出差异图片,大体的思路如下:

    1. 通过ImageIO读入图片,生成相应的BufferedImage实例(Image操作流)

    2. 修改目标图片的尺寸大小,以适应期望图片的大小(为像素比对做准备)

    3. 获取每一个(width,height)的ARGB,并获取相应的Red, Green,Blue的值

    4. 按照每个像素点的R,G,B进行比较(需要定义允许的R,G,B的误差)

    5. 统计不同的像素点,生成diff图片

    代码如下:

    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.text.DecimalFormat;
    
    
    public class ImageDiff {
    
        //不同的像素标记为红色
        public static final int RGB_RED = 16711680;
    
        //允许的Red,Green,Blue单个维度的像素差值
        public static final int DIFF_ALLOW_RANGE = 5;
    
        //不同像素点统计值
        public static int diffPointCount = 0;
    
        //从rgb值中抽取red
        public static int getRed(int rgbValue){
            return rgbValue & 0xff0000 >> 16;
        }
    
        //从rgb值中抽取green
        public static int getGreen(int rgbValue){
            return rgbValue & 0xff00 >> 8;
        }
    
        //从rgb值中抽取blue
        public static int getBlue(int rgbValue){
            return rgbValue & 0xff;
        }
    
        /**
         * 比较两图片,并用红色标出不同的像素点,然后保存差异图片到本地,打印匹配率
         * @param srcImgPath
         * @param targetImgPath
         */
        public static void compareImages(String srcImgPath,String targetImgPath){
            try {
                BufferedImage srcImg = ImageIO.read(new File(srcImgPath));
                BufferedImage targetImg = ImageIO.read(new File(targetImgPath));
    
                diffPointCount = 0;
                BufferedImage diffImg = srcImg;
    
                int srcHeight = srcImg.getHeight();
                int srcWidth = srcImg.getWidth();
    
                //修改待比较图片的尺寸以适应源图片的尺寸
                targetImg = changeImageSize(targetImg,srcHeight,srcWidth);
    
                int srcRgb;
                int targetRgb;
    
                for(int h = 0;h<srcHeight;h++){
                    for(int w=0;w<srcWidth;w++){
                        srcRgb = srcImg.getRGB(w,h);
                        targetRgb = targetImg.getRGB(w,h);
                        if( Math.abs(getRed(srcRgb) - getRed(targetRgb))>DIFF_ALLOW_RANGE ||
                                Math.abs(getGreen(srcRgb) - getGreen(targetRgb))>DIFF_ALLOW_RANGE||
                                Math.abs(getBlue(srcRgb) - getBlue(targetRgb))>DIFF_ALLOW_RANGE){
                            diffImg.setRGB(w,h, RGB_RED);
                            diffPointCount++;
                        }
                    }
                }
    
                //保存差异图片
                ImageIO.write(diffImg,"jpg",new File("diffImg.jpg"));
                System.out.println("保存差异图片成功!");
    
                //计算相似度(保留小数点后四位)
                int totalPixel = srcHeight*srcWidth;
                DecimalFormat decimalFormat = new DecimalFormat("#.####");
                double matchRate = (totalPixel-diffPointCount)/(totalPixel*1.0);
    
                System.out.println("图片相似度为: "+decimalFormat.format(matchRate)+"%");
    
            }catch (Exception ex){
                ex.printStackTrace();
            }
        }
    
    
        /**
         * 修改BufferedImage中的图片尺寸,以便和源图片进行比较
         * @param image
         * @param newHeight
         * @param newWidth
         * @return
         */
        public static BufferedImage changeImageSize(BufferedImage image,int newHeight,int newWidth){
            Image img = image.getScaledInstance(newWidth,newHeight,Image.SCALE_SMOOTH);
            int width = img.getWidth(null);
            int height = img.getHeight(null);
    
            //获取新图片的BufferedImage实例
            BufferedImage newBufferedImage = new BufferedImage(width, height,
                    BufferedImage.TYPE_INT_ARGB);
            Graphics g = newBufferedImage.getGraphics();
            g.drawImage(img, 0, 0, null);
            g.dispose();
            return newBufferedImage;
        }
    
        public static void main(String[] args){
            compareImages("1.jpg","2.jpg");
        }
    }
    

      

  • 相关阅读:
    [LeetCode][SQL]Rising Temperature
    google API的.NET库
    Google Reader的另一个开源的替代品Go Read
    C#中反射接受的字符串需要满足的Backus-Naur Form语法
    Windows的应用管理工具 PortableApps,Chocolatey和Ninite
    如何定制Windows系统右键菜单
    另一个有趣的Captcha 网站
    .gitignore模板
    遇到sql server的问题时如何排查
    如何传播你的代码
  • 原文地址:https://www.cnblogs.com/AlwinXu/p/7103493.html
Copyright © 2011-2022 走看看