whycxzp
2024-01-12 0ecc15ba6ec8b0b21a0f7df159a814a58c0feda9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
package com.whyc.util;
 
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
 
public class ImageDiff {
 
//不同的像素标记为红色
 
    public static final int RGB_RED = 16711680;
    //public static final int RGB2 = 02550;
 
    //允许的Red,Green,Blue单个维度的像素差值
 
    public static final int DIFF_ALLOW_RANGE = 0;
    //public static final int DIFF_ALLOW_RANGE = 125;
 
//不同像素点统计值
 
    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;
 
    }
 
    /**
     * 修改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;
 
    }
 
    /**
     * 比较两图片,并用红色标出不同的像素点,然后保存差异图片到本地,打印匹配率
     *
     * @param srcImgPath
     * @param targetImgPath
     */
 
    public static ByteArrayOutputStream compareImages(String srcImgPath, String targetImgPath) throws IOException {
 
        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 w2 = 554;
            int h2 = 487;
            int srcRgb2;
 
            int targetRgb2;
 
            srcRgb2 = srcImg.getRGB(w2, h2);
 
            targetRgb2 = targetImg.getRGB(w2, h2);
            int red = getRed(srcRgb2);
            int red1 = getRed(targetRgb2);
            int green = getGreen(srcRgb2);
            int green1 = getGreen(targetRgb2);
            int blue = getBlue(srcRgb2);
            int blue1 = getBlue(targetRgb2);
 
            if (Math.abs(red - red1) > DIFF_ALLOW_RANGE ||
 
                    Math.abs(green - green1) > DIFF_ALLOW_RANGE ||
 
                    Math.abs(blue - blue1) > DIFF_ALLOW_RANGE) {
                diffImg.setRGB(w2, h2, RGB_RED);
            }*/
            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++;
                    }
                }*/
                if (Math.abs(targetRgb - srcRgb) > DIFF_ALLOW_RANGE) {
                    diffImg.setRGB(w, h, RGB_RED);
                }
                diffPointCount++;
            }
        }
        //保存差异图片
        ByteArrayOutputStream bs = new ByteArrayOutputStream();
        //ImageOutputStream imOut = ImageIO.createImageOutputStream(bs);
        //ImageIO.write(diffImg, "png", new File("diffImg.png"));
        ImageIO.write(diffImg,"png",bs);
 
        /*//计算相似度(保留小数点后四位)
        int totalPixel = srcHeight * srcWidth;
        DecimalFormat decimalFormat = new DecimalFormat("#.####");
        double matchRate = (totalPixel - diffPointCount) / (totalPixel * 1.0);
        System.out.println("图片相似度为: " + decimalFormat.format(matchRate) + "%");*/
        return bs;
 
    } catch(Exception ex){
        ex.printStackTrace();
        return null;
    }
 
}
 
 
    public static void main(String[] args) throws IOException {
 
        compareImages("C:\\\\Users\\\\29550\\\\Desktop\\\\当前项目\\\\202207图纸管理\\\\图纸升级\\\\fbo-60010nt-t-j-002_a11-dwg.png",
                "C:\\\\Users\\\\29550\\\\Desktop\\\\当前项目\\\\202207图纸管理\\\\图纸升级\\\\fbo-60010nt-t-j-002_a12-dwg.png");
    }
 
}