背景

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

Java读取图片 cmyk转rgb相关推荐

  1. java读取图片成rgb二维数组

    全栈工程师开发手册 (作者:栾鹏) java教程全解 java读取图片成rgb二维数组 测试代码 public static void main(String[] args) {Color[][] a ...

  2. java读取图片、PDF中图片上的文字

    读取图片上的文字 提示:本文是基于tess4j 文章目录 读取图片上的文字 前言 一.tess4j是什么? 二.使用步骤 1.POM引入库 2.实例代码 总结 前言 总是有一些与众不同的需求在等着研发 ...

  3. java读取图片缩略方法_java 图片缩略图的两种方法

    最近网上看到两种不同的java图片缩略图的绘制方案 第一种,使用Graphics().drawImage按照一定的比例重新绘制图像. Java代码 package com.image.suoluetu ...

  4. Java读取图片文件

    需求:读取图片输入流,获取图片并存储在桌面上 代码如下: import javax.imageio.ImageIO; import javax.imageio.stream.ImageOutputSt ...

  5. JAVA 读取图片储存至本地

    需求:serlvet经过处理通过报表工具返回一张报表图(柱状图 折线图). 现在需要把这个图存储到本地 以便随时查看 // 构造URL URL url = new URL(endStr);// 打开U ...

  6. java 读取图片给 matlab_如何将MATLAB图像处理程序转换为java?

    将Matlab代码转换为Java代码有几个一般的缺陷.我将Matlab转换成C代码,所以我的建议来自于这些经验. >如果你在Matlab中使用for循环,一般来说,你做错了.添加矩阵(图像等)是 ...

  7. java获取图片像素点的rgb值_java获取图片每个像素点的RGB

    /** * 获取图片RGB数组 * @param filePath * @return */ public int[][] getImageGRB(String filePath) { File fi ...

  8. java读取图片并显示

    一般我们会遇到一个网页会根据不同的状态来动态加载图片展示,比如首页轮播图,展示最新三张. 1.先去数据库查找最新发布的三张照片的ID. 2.根据图片ID去请求接口,直接写在src里面. <img ...

  9. java读取图片画布大小_Java图像文件的读写

    读取bmp文件到BufferedImage中 File file2 = new File("c:\\testimages\\tttt" + ".bmp"); / ...

  10. java 写照片exif属性,java读取图片的(尺寸、拍摄日期、标记)等EXIF信息

    主要代码如下: packagecom.test;importjava.io.File;importjava.io.IOException;importjava.util.Iterator;import ...

最新文章

  1. Android判断CPU是否为x86,如何判断. NET 程序集是否编译为 x86,x64或者任何 CPU_visual-studio_开发99编程知识库...
  2. 改变ie浏览器的收藏夹位置
  3. Asp.net控件开发学习笔记(六)----数据回传
  4. 使用EditPlus 删除文本文件中多余的空行 和 EditPlus 选择列
  5. 多线程别怕,有锁就安全;(解决线程安全问题)
  6. sql date类型_共享单车数据分析的SQL数据库设计
  7. 在Visual Studio中使用T4 Templates 生成代码
  8. Raspberry 安装vstudio
  9. 软件配置管理计划示例
  10. 软件可靠性测试意义,软件可靠性测试方法与目的
  11. Git, Gitlab使用文档
  12. 服务器虚拟化三种架构,X86虚拟化之三种服务器虚拟化战略架构
  13. BaseAdataer基本设配器
  14. 微信公众号页面中监听手机“返回”,并回到公众号里
  15. Viterbi-Algorithm(维特比算法)
  16. 云平台的云计算安全参数详解
  17. 免费范文网复制内容-百味书屋
  18. 缺血性中风和肠道菌群之间的桥梁:短链脂肪酸
  19. 企业微信 消息 html,企业微信怎么设置消息提醒
  20. windows10家庭版升级为企业版

热门文章

  1. 用Java输出正方形,长方形
  2. 1688店铺列表接口-(item_search_seller-搜索店铺列表接口)
  3. java 请求https post 接口 绕过证书验证
  4. 八爪鱼采集器使用方法
  5. 阅读《原则》有感之工作原则
  6. php获取扫描枪数据,条码扫描枪的读取技巧
  7. 与二次元老婆邂逅的游戏的创建过程(二)
  8. DO,DTO,VO,POJO, Java 中的各种 O(bject)
  9. html+css网页开发 之 头部导航条(logo、导航栏、搜索框)
  10. linux 网桥浅析