From b778472a554eab501bba7cbb3d98d4b0eff6bd57 Mon Sep 17 00:00:00 2001 From: phaub Date: Thu, 9 Feb 2023 12:12:02 +0100 Subject: [PATCH 1/3] Setting jpeg quality in JPEGCodec As a simple way to make the jpeg quality property settable, e.g. for use in QuPath, the approach of this PR uses System.setProperty() and System.getProperty to support adjustable jpeg quality while avoiding passing the 'jpegquality' value from QuPath through the entire class hierarchy from QuPath to Bioformats to ome.codecs. Related to: https://github.com/ome/bioformats/issues/3370 --- src/main/java/ome/codecs/JPEGCodec.java | 50 ++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/main/java/ome/codecs/JPEGCodec.java b/src/main/java/ome/codecs/JPEGCodec.java index 237d6ec4..4569fd8e 100644 --- a/src/main/java/ome/codecs/JPEGCodec.java +++ b/src/main/java/ome/codecs/JPEGCodec.java @@ -48,6 +48,14 @@ import ome.codecs.CodecException; import ome.codecs.gui.AWTImageTools; +//::phaub 09.02.23 +import javax.imageio.IIOImage; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.stream.ImageOutputStream; +import javax.imageio.IIOException; + + /** * This class implements JPEG compression and decompression. */ @@ -82,7 +90,47 @@ public byte[] compress(byte[] data, CodecOptions options) options.bitsPerSample / 8, false, options.littleEndian, options.signed); try { - ImageIO.write(img, "jpeg", out); + //ImageIO.write(img, "jpeg", out); + + //::phaub 09.02.23 (Adjustable jpeg quality) + + // How to use: + // Set jpegquality as system property in the calling object (e.g. QuPath using OMEPyramidWriter()): + // String OME_JPEGQUALITY = "ome.codec.jpegquality"; + // double jpegquality = 0.95; + // System.setProperty(OME_JPEGQUALITY, String.valueOf( jpegquality )); + + String OME_JPEGQUALITY = "ome.codec.jpegquality"; + + double jpegquality = 0.75; + String sJPEGQuality = System.getProperty(OME_JPEGQUALITY, null); + if (sJPEGQuality != null) + jpegquality = Double.parseDouble(sJPEGQuality); + jpegquality = Math.max(0.25, Math.min(1.0, jpegquality)); + + ImageWriter jpgWriter = ImageIO.getImageWritersByFormatName("jpg").next(); + if (jpgWriter == null) { + return null; + } + ImageWriteParam jpgWriteParam = jpgWriter.getDefaultWriteParam(); + jpgWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); + jpgWriteParam.setCompressionQuality((float) jpegquality); + + ImageOutputStream stream = ImageIO.createImageOutputStream(out); + if (stream == null) { + throw new IIOException("Can't create an ImageOutputStream!"); + } + + jpgWriter.setOutput(stream); + + try { + IIOImage outputImage = new IIOImage(img, null, null); + jpgWriter.write(null, outputImage, jpgWriteParam); + } finally { + jpgWriter.dispose(); + stream.flush(); + stream.close(); + } } catch (IOException e) { throw new CodecException("Could not write JPEG data", e); From 190b75d9a82239d9c637e74581071fb03d058dde Mon Sep 17 00:00:00 2001 From: David Gault Date: Wed, 5 Apr 2023 11:20:04 +0100 Subject: [PATCH 2/3] Update src/main/java/ome/codecs/JPEGCodec.java --- src/main/java/ome/codecs/JPEGCodec.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/ome/codecs/JPEGCodec.java b/src/main/java/ome/codecs/JPEGCodec.java index 4569fd8e..e67884ff 100644 --- a/src/main/java/ome/codecs/JPEGCodec.java +++ b/src/main/java/ome/codecs/JPEGCodec.java @@ -103,9 +103,9 @@ public byte[] compress(byte[] data, CodecOptions options) String OME_JPEGQUALITY = "ome.codec.jpegquality"; double jpegquality = 0.75; - String sJPEGQuality = System.getProperty(OME_JPEGQUALITY, null); - if (sJPEGQuality != null) - jpegquality = Double.parseDouble(sJPEGQuality); + if (options.quality > 0) { + jpegquality = options.quality; + } jpegquality = Math.max(0.25, Math.min(1.0, jpegquality)); ImageWriter jpgWriter = ImageIO.getImageWritersByFormatName("jpg").next(); From 0cae3d51347b89327ce35c7c046f284197c20a29 Mon Sep 17 00:00:00 2001 From: David Gault Date: Thu, 6 Apr 2023 13:18:35 +0100 Subject: [PATCH 3/3] JPEGCodec: Fix indentations --- src/main/java/ome/codecs/JPEGCodec.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/main/java/ome/codecs/JPEGCodec.java b/src/main/java/ome/codecs/JPEGCodec.java index 869b9cc6..08ac4c4a 100644 --- a/src/main/java/ome/codecs/JPEGCodec.java +++ b/src/main/java/ome/codecs/JPEGCodec.java @@ -97,7 +97,6 @@ public byte[] compress(byte[] data, CodecOptions options) try { //::phaub 09.02.23 (Adjustable jpeg quality) - // How to use: // Set jpegquality using CodecOptions in the calling object (e.g. QuPath using OMEPyramidWriter()): // CodecOptions options = new CodecOptions(); @@ -112,7 +111,7 @@ public byte[] compress(byte[] data, CodecOptions options) ImageWriter jpgWriter = ImageIO.getImageWritersByFormatName("jpg").next(); if (jpgWriter == null) { - return null; + return null; } ImageWriteParam jpgWriteParam = jpgWriter.getDefaultWriteParam(); jpgWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); @@ -121,16 +120,16 @@ public byte[] compress(byte[] data, CodecOptions options) ImageOutputStream stream = new MemoryCacheImageOutputStream(out); try { Iterator iterator = ImageIO.getImageWritersByFormatName("jpeg"); - if (iterator.hasNext()) { - ImageWriter writer = iterator.next(); - writer.setOutput(stream); + if (iterator.hasNext()) { + ImageWriter writer = iterator.next(); + writer.setOutput(stream); IIOImage outputImage = new IIOImage(img, null, null); - writer.write(null, outputImage, jpgWriteParam); + writer.write(null, outputImage, jpgWriteParam); } } finally { - jpgWriter.dispose(); - stream.flush(); - stream.close(); + jpgWriter.dispose(); + stream.flush(); + stream.close(); } } catch (IOException e) {