简体   繁体   中英

Pink/Purple Color with Java Resizer

I'm using Groovy&Grails and thumbnailator to resize thumbnails with this lines of code:

BufferedImage image = ImageIO.read(new FileInputStream("input.jpg"))
BufferedImage output = Thumbnails.of(image).size(400, 400).crop(Positions.CENTER).asBufferedImage()
ByteArrayOutputStream baos = new ByteArrayOutputStream()
ImageIO.write(output, "jpg", baos)
baos.flush()
OutputStream outputStream = new FileOutputStream("output.jpg")
baos.writeTo(outputStream)
baos.close()   

This works in 99% of all cases (same Java, OS, Sourcecode), with input.jpg. But in some non-reproducible cases, the image will become this:

颜色

I've checked other threads, such as the following link: Pink/Reddish tint while resizing jpeg images using java thumbnailator or imgscalr

I'm stuck with the situation that the exact same file works 99%, but in some, to be defined cases, doesn't.

My question: How can this behaviour be reproduced?

Although the input is expected to be the same every time, something must be changing. What you can do is write out the input file unchanged along with output.jpg . When you encounter the problem then you'll be able to compare it's input file with the input file of a resize that have worked.

There should be some difference. If there is, then the problem is likely in the process providing the input file. If there isn't, which would be quite surprising, then something is wrong with the resizing code.

TIP: You can use SHAx, MD5, etc to determine if the input files are different.

Confirming the input file

To confirm the input file, you can write the incoming data to a separate file.

def inputCopy = new FileOutputStream("input-SOMETHING-UNIQUE-HERE.jpg")
def input = new WritingInputStream(
    new FileInputStream("input.jpg"),
    inputCopy)

BufferedImage image = ImageIO.read(input)
...
inputCopy.close()

The WritingInputStream writes data to an OutputStream as it's read from an InputStream . The source code is shown below:

class WritingInputStream extends FilterInputStream {
    private OutputStream output

    public WritingInputStream(InputStream input, OutputStream output) {
        super(input)

        this.output = output
    }

    int read() {
        int data = super.read()

        output.write(data)

        return data
    }

    int read(byte[] b) {
        int result = super.read(b)

        output.write(b)

        return result
    }

    int read(byte[] b, int off, int len) {
        int result = super.read(b, off, len)

        output.write(b, off, len)

        return result
    }    
}

An alternative to writing the inputCopy file out is to use an ByteArrayOutputStream and log the SHA1 of it's contents which you can then compare that to the SHA1 of the input file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM