Java读取图片 cmyk转rgb

news/2024/10/23 9:31:21/

背景

使用java处理图片的时候,比如用ImageIo.read(图片)时,是不能处理CMYK的图片的,会报错,因此,我们需要将CMYK转化为RGB模式,并且排除转换时的色差问题。

代码

package com.e369.elc.framework.image;import java.awt.color.ColorSpace;
import java.awt.color.ICC_ColorSpace;
import java.awt.color.ICC_Profile;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import javax.imageio.IIOException;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import org.apache.sanselan.ImageReadException;
import org.apache.sanselan.Sanselan;
import org.apache.sanselan.common.byteSources.ByteSource;
import org.apache.sanselan.common.byteSources.ByteSourceFile;
import org.apache.sanselan.formats.jpeg.JpegImageParser;
import org.apache.sanselan.formats.jpeg.segments.UnknownSegment;public class Cmyk2RgbUtil {public static final int COLOR_TYPE_RGB = 1;public static final int COLOR_TYPE_CMYK = 2;public static final int COLOR_TYPE_YCCK = 3;public static BufferedImage readImage(String fileName) throws IOException, ImageReadException {int colorType = COLOR_TYPE_RGB;boolean hasAdobeMarker = false;File file = new File(fileName);ImageInputStream stream = ImageIO.createImageInputStream(file);Iterator<ImageReader> iter = ImageIO.getImageReaders(stream);if (iter == null || !iter.hasNext()) {throw new RuntimeException("CMYK 转 RGB报错,未找到image reader");}ImageReader reader = iter.next();reader.setInput(stream);BufferedImage image;ICC_Profile profile = null;try {image = reader.read(0);} catch (IIOException e) {colorType = COLOR_TYPE_CMYK;JpegImageParser parser = new JpegImageParser();ByteSource byteSource = new ByteSourceFile(file);@SuppressWarnings("rawtypes")ArrayList segments = parser.readSegments(byteSource, new int[] {0xffee}, true);if (segments != null && segments.size() >= 1) {UnknownSegment app14Segment = (UnknownSegment) segments.get(0);byte[] data = app14Segment.bytes;if (data.length >= 12 && data[0] == 'A' && data[1] == 'd' && data[2] == 'o' && data[3] == 'b' && data[4] == 'e') {hasAdobeMarker = true;int transform = app14Segment.bytes[11] & 0xff;if (transform == 2)colorType = COLOR_TYPE_YCCK;}}profile = Sanselan.getICCProfile(file);WritableRaster raster = (WritableRaster) reader.readRaster(0, null);if (colorType == COLOR_TYPE_YCCK)convertYcckToCmyk(raster);if (hasAdobeMarker)convertInvertedColors(raster);image = convertCmykToRgb(raster, profile);}return image;}public static void convertYcckToCmyk(WritableRaster raster) {int height = raster.getHeight();int width = raster.getWidth();int stride = width * 4;int[] pixelRow = new int[stride];for (int h = 0; h < height; h++) {raster.getPixels(0, h, width, 1, pixelRow);for (int x = 0; x < stride; x += 4) {int y = pixelRow[x];int cb = pixelRow[x + 1];int cr = pixelRow[x + 2];int c = (int) (y + 1.402 * cr - 178.956);int m = (int) (y - 0.34414 * cb - 0.71414 * cr + 135.95984);y = (int) (y + 1.772 * cb - 226.316);if (c < 0)c = 0;else if (c > 255)c = 255;if (m < 0)m = 0;else if (m > 255)m = 255;if (y < 0)y = 0;else if (y > 255)y = 255;pixelRow[x] = 255 - c;pixelRow[x + 1] = 255 - m;pixelRow[x + 2] = 255 - y;}raster.setPixels(0, h, width, 1, pixelRow);}}public static void convertInvertedColors(WritableRaster raster) {int height = raster.getHeight();int width = raster.getWidth();int stride = width * 4;int[] pixelRow = new int[stride];for (int h = 0; h < height; h++) {raster.getPixels(0, h, width, 1, pixelRow);for (int x = 0; x < stride; x++)pixelRow[x] = 255 - pixelRow[x];raster.setPixels(0, h, width, 1, pixelRow);}}public static BufferedImage convertCmykToRgb(Raster cmykRaster, ICC_Profile cmykProfile) throws IOException {if (cmykProfile == null)cmykProfile = ICC_Profile.getInstance(Cmyk2RgbUtil.class.getResourceAsStream("/ISOcoated_v2_300_eci.icc"));if (cmykProfile.getProfileClass() != ICC_Profile.CLASS_DISPLAY) {byte[] profileData = cmykProfile.getData();if (profileData[ICC_Profile.icHdrRenderingIntent] == ICC_Profile.icPerceptual) {intToBigEndian(ICC_Profile.icSigDisplayClass, profileData, ICC_Profile.icHdrDeviceClass); // Header is firstcmykProfile = ICC_Profile.getInstance(profileData);}}ICC_ColorSpace cmykCS = new ICC_ColorSpace(cmykProfile);BufferedImage rgbImage = new BufferedImage(cmykRaster.getWidth(), cmykRaster.getHeight(), BufferedImage.TYPE_INT_RGB);WritableRaster rgbRaster = rgbImage.getRaster();ColorSpace rgbCS = rgbImage.getColorModel().getColorSpace();ColorConvertOp cmykToRgb = new ColorConvertOp(cmykCS, rgbCS, null);cmykToRgb.filter(cmykRaster, rgbRaster);return rgbImage;}static void intToBigEndian(int value, byte[] array, int index) {array[index] = (byte) (value >> 24);array[index + 1] = (byte) (value >> 16);array[index + 2] = (byte) (value >> 8);array[index + 3] = (byte) (value);}public static void main(String[] args) throws ImageReadException, IOException {File outputfile = new File("C:\\Users\\emp\\Desktop\\fa1.jpg");ImageIO.write(readImage("C:\\Users\\emp\\Desktop\\1.jpg"), "jpg", outputfile);}
}

http://www.ppmy.cn/news/826674.html

相关文章

php cmyk转rgb,用PHP将CMYK格式的JPG文件转为RGB格式 | 学步园

上次说到&#xff0c;CMYK格式的JPG用IE6浏览时无法显示&#xff0c;解决方法是用PS之类的软件转成RGB。但对于网站来说&#xff0c;用户并不知道这么解决&#xff0c;所以还是要程序想办法解决了。解决方法是用imagick或者imagemagick来处理图片&#xff0c;imagick代码如下&a…

ps出现两种颜色模式CMYK/RGB模式

如上图ps窗口出现两种颜色模式&#xff0c;会导致所在页面颜色变暗 解决方案 在视图窗口取消校样颜色就可以了

java cmyk转rgb_Java实现把cmyk格式图片转换为RGB格式图片

这个代码是我在网上找的&#xff0c;可以运行。 package com.pb.util; import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGImageEncoder; import java.awt.Transparency; import java.awt.color.ColorSpace; import java.awt.image.BufferedIma…

RGB色彩模式与CMYK色彩模式参数转换公式

资料来源于网络&#xff0c;仅供个人学习使用。 1. RGB色彩模式 自然界中绝大部分的可见光谱可以用红、绿和蓝三色光按不同比例和强度的混合来表示。RGB分别代表着3种颜色&#xff1a;R代表红色&#xff0c;G代表绿色、B代表蓝色。RGB模型也称为加色模型&#xff0c;通常用于…

CMYK与RGB

CMYK 1、简介 ①CMYK模式是一种色彩模式&#xff0c;当阳光照射到一个物体上时&#xff0c;这个物体将吸收一部分光线&#xff0c;并将剩下的光线进行反射&#xff0c;反射的光线就是我们所看见的物体颜色的减色色彩模式&#xff0c;同时也是与RGB模式的根本不同之处 ②C&…

CMYK转RGB

扫描仪的颜色空间一般为CMYK&#xff0c;从扫描仪上得到的图片如果是自己移植图片解码器&#xff0c; 一般需要将CMYK转换至RGB888。相关解释&#xff0c;参考国外资料&#xff1a; To understand the CMYK color model, it is best to start with an understanding of RGB co…

java cmyk转rgb_图片 CMYK转RGB 代码

//大部分情况都转换没问题&#xff0c;有极个别的转换不成功。现在想&#xff0c;是不是调用convert.exe 更方便 呵呵 private static boolean isCMYK(String filename) { boolean result false; BufferedImage img null; try { img ImageIO.read(new File(filename)); } ca…

CMYK convert RGB

libjpeg 处理CMYK 格式数据以及iCC配置文件 ICC文件&#xff0c;又叫ICC Color Profile&#xff0c;是指设备管理色彩特性的文件&#xff0c;各种具有色彩管理功能的软件&#xff08;如photoshop&#xff09;可以依据ICC文件的配置对不同设备的颜色特点进行准确地显示&#xf…