Java圖片比對

 在自動化測試中,除了普通的值驗證,常常還有一些圖片驗證,好比圖片的匹配率,輸出圖片的差別圖片等。本文主要用到了BufferedImage類來操做圖片比對和輸出差別圖片,大致的思路以下:java

1. 經過ImageIO讀入圖片,生成相應的BufferedImage實例(Image操做流)測試

2. 修改目標圖片的尺寸大小,以適應指望圖片的大小(爲像素比對作準備)orm

3. 獲取每個(width,height)的ARGB,並獲取相應的Red, Green,Blue的值blog

4. 按照每一個像素點的R,G,B進行比較(須要定義容許的R,G,B的偏差)圖片

5. 統計不一樣的像素點,生成diff圖片ci

 

代碼以下:get

 

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");
    }
}
相關文章
相關標籤/搜索