Java 扩展图像支持库 TwelveMonkeys ImageIO

TwelveMonkeys ImageIO 通过 javax.imageio.* 包的插件为 Java 平台提供扩展图像文件格式支持。

注意,GIF、 PNG 和 WBMP 格式已经通过 ImageIO API 支持,使用的是 JDK 标准插件。对于 BMP、 JPEG 和 TIFF 格式,TwelveMonkeys 插件提供了扩展格式支持和其他特性。

Basic usage

大多数时候,你所需要做的只是在你的项目中包含插件,然后写下:

BufferedImage image = ImageIO.read(file);

这将把文件的第一个图像完全加载到内存中。

最基本和最简单的书写形式是:

if (!ImageIO.write(image, format, file)) {
   // Handle image not written case
}

这将使用给定格式的默认设置将整个图像写入单个文件。

这些插件在运行时会被自动发现。查看 FAQ 了解更多关于这种机制如何工作的信息。

Maven dependency example
To depend on the JPEG and TIFF plugin using Maven, add the following to your POM:

...

    ...
    
        com.twelvemonkeys.imageio
        imageio-jpeg
        3.8.1
    
    
        com.twelvemonkeys.imageio
        imageio-tiff
        3.8.1
    

    
    
        com.twelvemonkeys.servlet
        servlet
        3.8.1
    

    
    
        com.twelvemonkeys.servlet
        servlet
        3.8.1
        jakarta
    

最终我的 MyImageIO 增强类。其实也是为了解决某些情况下 jpg 图片 ImageIO.read() 方法报错的问题。我寻找原因,发现用 jdk 自带的 jpeg 解析器不能解析所有的jpeg格式文件(如cmyk)。出现 unsupported formate 错误。之后使用 createJPEG4 解决了此问题,但是最终生成的图片有红屏现象,最终使用 TwelveMonkeys ImageIO 是无入侵且完美解决,这个值得点赞。

    static class MyImageIO {

        public static BufferedImage read(File input) throws IOException {
            if (input == null) {
                throw new IllegalArgumentException("input == null!");
            }
            if (!input.canRead()) {
                throw new IIOException("Can't read input file!");
            }

            ImageInputStream stream = ImageIO.createImageInputStream(input);
            if (stream == null) {
                throw new IIOException("Can't create an ImageInputStream!");
            }
            BufferedImage bi = read(stream);
            if (bi == null) {
                stream.close();
            }
            return bi;
        }

        private static BufferedImage read(ImageInputStream stream)
                throws IOException {
            if (stream == null) {
                throw new IllegalArgumentException("stream == null!");
            }

            Iterator iter = ImageIO.getImageReaders(stream);
            if (!iter.hasNext()) {
                return null;
            }

            final ImageReader reader = iter.next();
            ImageReadParam param = reader.getDefaultReadParam();
            reader.setInput(stream, true, true);
            BufferedImage bi;
            try {
                bi = reader.read(0, param);
            } catch (IIOException e) {
                Raster raster = reader.readRaster(0, null);
                bi = createJPEG4(raster);
            } finally {
                reader.dispose();
                stream.close();
            }
            return bi;
        }

        private static BufferedImage createJPEG4(Raster raster) {
            int w = raster.getWidth();
            int h = raster.getHeight();
            byte[] rgb = new byte[w * h * 3];
            // 彩色空间转换
            float[] Y = raster.getSamples(0, 0, w, h, 0, (float[]) null);
            float[] Cb = raster.getSamples(0, 0, w, h, 1, (float[]) null);
            float[] Cr = raster.getSamples(0, 0, w, h, 2, (float[]) null);
            float[] K = raster.getSamples(0, 0, w, h, 3, (float[]) null);

            for (int i = 0, imax = Y.length, base = 0; i < imax; i++, base += 3) {
                float k = 220 - K[i], y = 255 - Y[i], cb = 255 - Cb[i], cr = 255 - Cr[i];

                double val = y + 1.402 * (cr - 128) - k;
                val = (val - 128) * .65f + 128;
                rgb[base] = val < 0.0 ? (byte) 0 : val > 255.0 ? (byte) 0xff
                        : (byte) (val + 0.5);

                val = y - 0.34414 * (cb - 128) - 0.71414 * (cr - 128) - k;
                val = (val - 128) * .65f + 128;
                rgb[base + 1] = val < 0.0 ? (byte) 0 : val > 255.0 ? (byte) 0xff
                        : (byte) (val + 0.5);

                val = y + 1.772 * (cb - 128) - k;
                val = (val - 128) * .65f + 128;
                rgb[base + 2] = val < 0.0 ? (byte) 0 : val > 255.0 ? (byte) 0xff
                        : (byte) (val + 0.5);
            }

            raster = Raster.createInterleavedRaster(new DataBufferByte(rgb,
                    rgb.length), w, h, w * 3, 3, new int[] { 0, 1, 2 }, null);

            ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
            ColorModel cm = new ComponentColorModel(cs, false, true,
                    Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
            return new BufferedImage(cm, (WritableRaster) raster, true, null);
        }
    }

参考

haraldk/TwelveMonkeys: TwelveMonkeys ImageIO: Additional plug-ins and extensions for Java's ImageIO https://github.com/haraldk/TwelveMonkeys

你可能感兴趣的:(Java 扩展图像支持库 TwelveMonkeys ImageIO)