Skip to content

Image compressor unable to compress file to 32kb

I found an image for which our ImageCompressor implementation fails to compress it to the required file size: https://unsplash.com/photos/EHcIO_3DbOg

This is the log:

Exception in thread "Thread-13" java.io.IOException
        at org.briarproject.briar.desktop.attachment.media.ImageCompressorImpl.compressImage(ImageCompressorImpl.kt:86)
        at org.briarproject.briar.desktop.conversation.ConversationViewModel$sendMessage$1.invoke(ConversationViewModel.kt:180)
        at org.briarproject.briar.desktop.conversation.ConversationViewModel$sendMessage$1.invoke(ConversationViewModel.kt:175)
        at kotlin.concurrent.ThreadsKt$thread$thread$1.run(Thread.kt:30)

ImageCompressorImpl.kt:86

We have this there:

for (quality in 100 downTo 1 step 10) {
            val jpgWriter = ImageIO.getImageWritersByFormatName("jpg").next()
            jpgWriter.output = ImageIO.createImageOutputStream(out)

            val jpgWriteParam = jpgWriter.defaultWriteParam
            jpgWriteParam.compressionMode = ImageWriteParam.MODE_EXPLICIT
            jpgWriteParam.compressionQuality = quality / 100f

            val outputImage = IIOImage(scaled, null, null)
            jpgWriter.write(null, outputImage, jpgWriteParam)

            jpgWriter.dispose()
            if (out.size() <= MAX_IMAGE_SIZE) {
                LOG.i { "Compressed image to ${out.size()} bytes, quality $quality" }
                return ByteArrayInputStream(out.toByteArray())
            }
            out.reset()
        }
        throw IOException()

I have not yet debugged this, but I'm wondering what the lowest quality is that we actually try. We start with 100 but do we reach 1 or 10 as the last value? Edit: I just checked. We never reach 1 but the lowest value we try is 10. I guess we probably should change this to try quality 1 and in doubt even reduce image dimensions if even that does not suffice.

This is the full image:

imran-hecimovic-EHcIO_3DbOg-unsplash

Edited by Sebastian