Java CMYK转RGB源码网上很多,但是RGB转CMYK源码网上很少,那么多是只提供公式,要么提供依赖文件不全。这两天搜索很好久,终于找到一个可行方法。
项目使用maven搭建,依赖的工具包如下。在pom.xm文件添加该包依赖
<dependency>
<groupId>javax.media.jai</groupId>
<artifactId>com.springsource.javax.media.jai.codec</artifactId>
<version>1.1.3</version>
</dependency>
package cn.soqi.mp.qihome.controller;
import cn.soqi.mp.api.qihome.AjaxResult;
import cn.soqi.mp.app.listener.AppContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.imageio.ImageIO;
import javax.media.jai.JAI;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
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.io.*;
@Controller
@RequestMapping("/mg/image")
public class TestImageBinary {
static BASE64Encoder encoder = new sun.misc.BASE64Encoder();
static BASE64Decoder decoder = new sun.misc.BASE64Decoder();
@RequestMapping("/page.html")
public String intoUploadPage(){
return "/mg/management/rgb2cmyk";
}
@RequestMapping("/upload.do")
@ResponseBody
public AjaxResult uploadOneImage(HttpServletRequest request,@RequestParam(required = false) String targetName,@RequestParam("pic") MultipartFile file) throws IOException{
AjaxResult result = new AjaxResult();
InputStream input = null ;
OutputStream output = null ;
if(file.isEmpty()==false){
input=file.getInputStream();
}
//1 先将用户上传的文件保存到本地
String temFileName=mkFile(file.getOriginalFilename(),"original");
File saveFile = new File(temFileName);
output = new FileOutputStream(saveFile) ;
int temp = 0 ;
byte data[] = new byte[512] ;
while((temp=input.read(data,0,512))!=-1){
output.write(data) ; // 分块保存
}
input.close() ;
output.close() ;
//end
String targetFileName=null;
if(targetName!=null&&!targetName.equals("")) {
targetFileName = mkFile(targetName, "after_transfer");
}
InputStream inputStream = new FileInputStream(saveFile);
rgbToCmyk(inputStream, saveFile.getAbsolutePath(), targetFileName);
result.setSuccess(true);
result.setContent("上传成功并转码");
return result;
}
static String getImageBinary(String fileName){
File f = new File(fileName);
BufferedImage bi;
try {
bi = ImageIO.read(f);
String fileType=getFileType(fileName);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageIO.write(bi, fileType, outputStream);
byte[] bytes = outputStream.toByteArray();
return encoder.encodeBuffer(bytes).trim();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 获取文件类型
* @param fileName 文件全名
* @return
*/
static String getFileType(String fileName){
return fileName.substring(fileName.lastIndexOf(".")+1,fileName.length());
}
/**
* 将其他格式的图片转换成CDR或其它文件格式
* @param sourceFileName 上传文件名
* @param newFileName 新文件名
*/
static void base64StringToImage(String sourceFileName,String newFileName){
try {
String base64String =getImageBinary(sourceFileName);
byte[] bytes1 = decoder.decodeBuffer(base64String);
ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes1);
BufferedImage bi1 =ImageIO.read(inputStream);
File w2 = new File(newFileName);//可以是jpg,png,gif格式
ImageIO.write(bi1, getFileType(sourceFileName), w2);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 创建文件名
* @param fileName 文件名
* @param parentDir 可变参数,文件目录(在当前路径下新建目录)
* @return 返回文件绝对路径
*/
static String mkFile(String fileName,String...parentDir) throws IOException {
StringBuffer absoluteFileName = getCurrentPath();
if(parentDir.length>0){
absoluteFileName.append(File.separator);
absoluteFileName.append(parentDir[0]);
File newDir=new File(absoluteFileName.toString());
if(!newDir.exists()){
newDir.mkdirs();
}
}
absoluteFileName.append(File.separator);
absoluteFileName.append(fileName);
String templateName=absoluteFileName.toString();
File file=new File(templateName);
if(!file.exists()){
file.createNewFile();
}
return absoluteFileName.toString();
}
/**
* 获取当前项目运行路径
* @return
*/
public static StringBuffer getCurrentPath(){
StringBuffer absoluteFileName = new StringBuffer();
ServletContext scontext = AppContext.getInstance().getContext();
absoluteFileName.append(scontext.getRealPath("/"));
absoluteFileName.append("WEB-INF");
return absoluteFileName;
}
/**
* 将rgb图片转化为cmyk图片
* @param fileName 文件名
* @param format 转化之后的文件格式(默认tif格式)
* @throws IOException
*/
public static void rgbToCmyk(String fileName,String...format) throws IOException{
BufferedImage rgbImage = ImageIO.read(new File(fileName));
BufferedImage cmykImage = null;
ColorSpace cpace = new ICC_ColorSpace(ICC_Profile.getInstance(TestImageBinary.class.getClassLoader().getResourceAsStream("common/ISOcoated_v2_300_eci.icc")));
ColorConvertOp op = new ColorConvertOp(rgbImage.getColorModel().getColorSpace(), cpace, null);
cmykImage = op.filter(rgbImage, null);
String newFileName=null;
newFileName = fileName.substring(0, fileName.lastIndexOf("."));
if(format.length>0) {
JAI.create("filestore", cmykImage, newFileName + format[0], format[0]);
}else {
JAI.create("filestore", cmykImage, newFileName + "tif", "TIFF");
}
}
/**
* 将图片为rgb转化为cmyk
* @param inputStream 图片输入流
* @param fileName 图片名词(绝对路径)
* @param newFileName 图片保存路径(绝对路径)(如果没有参数,则生成的图片在当前目录下,且格式为tif)
* @throws IOException
*/
public static void rgbToCmyk(InputStream inputStream,String fileName,String...newFileName) throws IOException{
BufferedImage rgbImage = ImageIO.read(inputStream);
BufferedImage cmykImage = null;
ColorSpace cpace = new ICC_ColorSpace(ICC_Profile.getInstance(TestImageBinary.class.getClassLoader().getResourceAsStream("ISOcoated_v2_300_eci.icc")));
ColorConvertOp op = new ColorConvertOp(rgbImage.getColorModel().getColorSpace(), cpace, null);
cmykImage = op.filter(rgbImage, null);
if(newFileName.length>0&&newFileName[0]!=null) {
String targetFileName=fileName.substring(0,fileName.lastIndexOf(".")+1)+"tif";
JAI.create("filestore", cmykImage,targetFileName,"TIFF");
cmykImage.flush();
base64StringToImage(targetFileName,newFileName[0]);//转成对应格式
File file=new File(fileName);
if(file.exists())
file.delete();
}else {
String targetFileName=fileName.substring(0,fileName.lastIndexOf(".")+1)+"tif";
JAI.create("filestore", cmykImage, targetFileName, "TIFF");
}
}
}
项目需要依赖ISOcoated_v2_300_eci.icc文件,ISOcoated_v2_300_eci.icc是一个工业的色彩标准文件。