JAVA RGB轉CMYK 源碼(支持格式轉換)

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是一個工業的色彩標準文件。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章