Thumbnails.of Could not obtain image from URL(javax.imageio.IIOException: Unsupported Image Type)

Thumbnails在下载个别图片的时候报上面的错误,根据提示猜测是图片格式问题。经查看网上相关资料,发现是因为个别图片格式是CMYK导致的。java的api无法解析cmyk格式的图片,只能解析rgb格式的。所以需要将cmyk格式的图片转成rgb格式的。代码如下:

import javax.imageio.IIOException;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.color.ColorSpace;
import java.awt.image.*;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;

/**
 * @project: cunkongjian
 * @description: CMYK格式图片转RGB格式图片的处理,因为Thumbnails无法处理CMYK格式图片
 * @author: zhaoyujie
 * @create: 2019-03-04 17:17
 */
public class CMYKUtil {
    public static BufferedImage readImage(File file) throws IOException {

        return readImage(ImageIO.createImageInputStream(file));
    }

    public static BufferedImage readImage(InputStream stream) throws IOException {

        return readImage(ImageIO.createImageInputStream(stream));
    }

    public static BufferedImage readImage(ImageInputStream input) throws IOException {
        Iterator<?> readers = ImageIO.getImageReaders(input);
        if (readers == null || !readers.hasNext()) {
            return null;
        }

        ImageReader reader = (ImageReader) readers.next();
        reader.setInput(input);

        BufferedImage image;
        try {
            // 尝试读取图片 (包括颜色的转换).
            image = reader.read(0); //RGB

        } catch (IIOException e) {
            // 读取Raster (没有颜色的转换).
            Raster raster = reader.readRaster(0, null);//CMYK
            image = createJPEG4(raster);
        }

        return image;
    }


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

也就是如果读取图片失败,则直接转格式处理。然后使用Thumbnails下载即可。

Thumbnails.of(CMYKUtil.readImage(new URL(url).openStream()))
        .scale(1f)
        .outputQuality(0.25f)
        .toFile("C:\\Users\\zyj\\Desktop\\t8.jpg");

猜你喜欢

转载自blog.csdn.net/keketrtr/article/details/88129641