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

时间:2018-07-29 20:10:44

标签: java arrays image-processing binary-data

我正在尝试将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 个答案:

答案 0 :(得分:0)

我尝试您编码并阅读@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;
}

答案 1 :(得分:0)

我最近有点忙,但是今天终于有机会回顾一下,根据上面所说的内容,我认为主要问题是在一种情况下压缩图像。其他不是。我确信有一个更好的解决方案,但是一个快速的解决方法是保存一个我想检查的图像的临时JPEG版本,然后使用2个缓冲图像进行比较,其中一个读入我拥有的JPEG文件。保存到该目录中,并读取我刚刚创建的临时JPEG文件,测试完成后,请使用File.delete()删除临时文件。

提取MP3图像并调用比较方法
Compare方法与最初所述的相同

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();