【问题标题】:Pink/Purple Color with Java Resizer粉红色/紫色与 Java Resizer
【发布时间】:2016-01-27 00:26:31
【问题描述】:

我正在使用 Groovy&Grails 和 thumbnailator 通过以下代码行调整缩略图的大小:

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

这适用于 99% 的所有情况(相同的 Java、操作系统、源代码),使用 input.jpg。但在某些不可重现的情况下,图像会变成这样:

我检查了其他线程,例如以下链接: Pink/Reddish tint while resizing jpeg images using java thumbnailator or imgscalr

我坚持认为完全相同的文件可以工作 99%,但在某些情况下,要定义的情况下却不能。

我的问题:如何重现这种行为?

【问题讨论】:

    标签: java grails thumbnails


    【解决方案1】:

    虽然每次输入都应该是相同的,但一定有一些变化。您可以做的是将输入文件与output.jpg 一起写出。当您遇到问题时,您将能够将其输入文件与已调整大小的输入文件进行比较。

    应该有一些区别。如果有,那么问题可能出在提供输入文件的过程中。如果没有,这将是非常令人惊讶的,那么调整大小的代码有问题。

    提示:您可以使用 SHAx、MD5 等来确定输入文件是否不同。

    确认输入文件

    要确认输入文件,可以将传入的数据写入单独的文件。

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

    WritingInputStream 将数据写入OutputStream,因为它是从InputStream 读取的。源码如下图:

    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
        }    
    }
    

    写入inputCopy 文件的另一种方法是使用ByteArrayOutputStream 并记录其内容的SHA1,然后您可以将其与输入文件的SHA1 进行比较。

    【讨论】:

    • 昨天我得到了紫色调整大小的输出,因为 source.jpg 文件导致紫色。然后我删除了 output.jpg,重新启动了 tomcat 实例,它工作了。使用相同的 input.jpg 文件,这听起来令人难以置信,但确实如此。
    • 这里有上传或涉及的东西吗?输入来自哪里?
    • 是的,该文件由用户上传,并将作为原始文件存储在文件系统中。如果我复制该文件(例如通过传输)并再次上传,它将再次失败。如果我重新启动 Tomcat servlet 并再次上传这个文件,它就可以工作了。
    • 那很好。现在也不是那么难以置信了。这意味着问题可能出在上传文件和处理文件之间。请参阅我关于如何验证输入文件的更新。
    • 感谢您的更新和努力。奇怪的是它在 Tomcat 重启后使用完全相同的文件。
    猜你喜欢
    • 2022-07-29
    • 2021-01-03
    • 2018-05-25
    • 2016-05-04
    • 2017-04-25
    • 2022-11-06
    • 1970-01-01
    • 1970-01-01
    • 2021-09-25
    相关资源
    最近更新 更多