代码之家  ›  专栏  ›  技术社区  ›  oznomal

二进制数据图像转换不等于同一图像的JPG

  •  1
  • oznomal  · 技术社区  · 6 年前

    我试图将MP3文件中的嵌入图像与另存为JPG的完全相同的图像进行比较。如果图像是相同的,那么我想执行一些进一步的处理,但是,当我比较2个图像(RGB比较)时,我总是得到错误。

    我确信这些图像是相同的,因为我从相同的MP3中提取了图像,并使用以下代码最初创建了JPG。

    Artwork aw = tag.getFirstArtwork();
    
    ByteArrayInputStream bis = new ByteArrayInputStream(aw.getBinaryData());
    BufferedImage imgA = ImageIO.read(bis);
    
    File outputfile = new File("expectedImage.jpg");
    ImageIO.write(imgA, "jpg", outputfile);
    


    在我运行它来获取图像之后,我刚刚对该部分进行了注释,现在我有了以下代码来比较MP3嵌入图像和JPG

    提取MP3图像并调用比较方法

    try {
        Artwork aw = tag.getFirstArtwork();
    
        ByteArrayInputStream bis = new ByteArrayInputStream(aw.getBinaryData());
        BufferedImage imgA = ImageIO.read(bis);
    
        File expectedImageFile = new File("expectedImage.jpg");
        BufferedImage imgB = ImageIO.read(expectedImageFile);
    
        if(compareImages(imgA, imgB)) {
            System.out.println("The Images Match.");
        }else {
            System.out.println("The Images Do Not Match.");
        }
    } 
    catch (IOException e) {
        e.printStackTrace();
    }
    


    比较图像
    该方法在第一次通过循环时比较像素是否相等时失败。

    public static boolean compareImages(BufferedImage imgA, BufferedImage imgB) {
    
        // The images must be the same size.
        if (imgA.getWidth() != imgB.getWidth() || imgA.getHeight() != imgB.getHeight()) {
            return false;
        }
    
        int width = imgA.getWidth();
        int height = imgA.getHeight();
    
        // Loop over every pixel.
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
    
                // Compare the pixels for equality.
                if (imgA.getRGB(x, y) != imgB.getRGB(x, y)) {
                    return false;
                }
            }
        }
    
        return true;
    } 
    
    2 回复  |  直到 6 年前
        1
  •  0
  •   Crammeur    6 年前

    我试着给你编代码然后读 @Sami Kuhmonen 评论,我理解。

    当你使用 ImageIO.write(imgA, "jpg", outputfile) 您通过另一个编码器,可能会丢失数据。

    你需要用标准技术来改变这一点。

    例子 [更新]

    public static void main(String[] args) {
    
        try {
            //Write the picture to BAOS
            ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
            byteBuffer.write(aw.getBinaryData(), 0, 1);
    
            //New file target
            File outputfile = new File("expectedImage.jpg");
            OutputStream outputStream = new FileOutputStream(outputfile);
            byteBuffer.writeTo(outputStream);
            outputStream.close();
    
    
            File expectedImageFile = new File("expectedImage.jpg");
    
            ByteArrayInputStream bis = new ByteArrayInputStream(aw.getBinaryData());
            BufferedImage imgA = ImageIO.read(bis);
            FileInputStream fis = new FileInputStream(expectedImageFile);
            BufferedImage imgB = ImageIO.read(fis);
    
            if(compareImages(imgA, imgB)) {
                System.out.println("The Images Match.");
            }else {
                System.out.println("The Images Do Not Match.");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    
    
    }
    
    public static boolean compareImages(BufferedImage imgA, BufferedImage imgB) {
    
        // The images must be the same size.
        if (imgA.getWidth() != imgB.getWidth() || imgA.getHeight() != imgB.getHeight()) {
            return false;
        }
    
        int width = imgA.getWidth();
        int height = imgA.getHeight();
    
        // Loop over every pixel.
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
    
                // Compare the pixels for equality.
                if (imgA.getRGB(x, y) != imgB.getRGB(x, y)) {
                    return false;
                }
            }
        }
    
        return true;
    }
    
        2
  •  0
  •   oznomal    6 年前

    我最近有点忙,但今天终于有机会回顾一下,根据上面所说的,我发现主要问题是图像在一种情况下被压缩,而在另一种情况下则不是。我确信有更好的解决方案,但一个快速的修复方法是保存一个临时的jpeg版本的图像我想检查,然后使用2个缓冲图像进行比较,其中一个读取我保存到目录中的jpeg文件,另一个读取我刚创建的temp jpeg文件,测试完成后,只需使用file.delete()删除temp文件。

    提取MP3图像并调用比较方法
    比较法与原定方法相同

    Artwork aw = tag.getFirstArtwork();
    ByteArrayInputStream bis = new ByteArrayInputStream(aw.getBinaryData());
    
    BufferedImage tempImg = ImageIO.read(bis);
    
    File tempFile = new File("temp.jpg");
    ImageIO.write(tempImg, "jpg", tempFile);
    
    BufferedImage imgA = ImageIO.read(tempFile);
    
    File expectedImageFile = new File("imgToCheckAgainst.jpg");
    BufferedImage imgB = ImageIO.read(expectedImageFile);
    
    if(compareImages(imgA, imgB)) {
        System.out.println("The Images Match");
    }else {
        System.out.println("The images do not match.");
    }
    
    tempFile.delete();