此类需要引入一个包和ISOcoated_v2_300_eci.icc(CMYK的位图);
连接为:https://download.csdn.net/download/xiaozukun/11107461
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.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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 ImageTool {
private static boolean hasAdobeMarker = false;
private static Log log = LogFactory.getLog(ImageTool.class);
/*
*返回图片的真实格式,此方法如果读取的图片为svg格式会返回空值
*/
public static String getRealFormatName(Object object) throws Exception {
ImageInputStream iis = ImageIO.createImageInputStream(object);
Iterator
while (iterator.hasNext()) {
ImageReader reader = (ImageReader) iterator.next();
return reader.getFormatName();
}
return null;
}
/*
*传图片的路径,和要将图片转成的格式
*/
public static void convertTif(String fileName, String extension) {
try {
File file = new File(fileName);
if (file.exists() == false) {
System.out.println("File not exist!!!");
return;
}
BufferedImage image = ImageIO.read(file);
BufferedImage convertedImage = new BufferedImage(image.getWidth(),
image.getHeight(), BufferedImage.TYPE_INT_RGB);
convertedImage.createGraphics().drawRenderedImage(image, null);
ImageIO.write(convertedImage, extension, new File(fileName));
} catch (IOException ex) {
ex.printStackTrace();
}
}
/*
*传进需要读取的图片,fileName是用来记录CMYK图片的名字
*/
public static BufferedImage readImage(File file, String fileName) throws IOException, ImageReadException {
hasAdobeMarker = false;
ImageInputStream stream = ImageIO.createImageInputStream(file);
Iterator
while (iter.hasNext()) {
ImageReader reader = iter.next();
reader.setInput(stream);
BufferedImage image;
ICC_Profile profile = null;
try {
image = reader.read(0);
} catch (IIOException e) {
checkAdobeMarker(file);
profile = Sanselan.getICCProfile(file);
WritableRaster raster = (WritableRaster) reader.readRaster(0, null);
if (hasAdobeMarker) {
convertInvertedColors(raster);
}
image = convertCmykToRgb(raster, profile);
log.info("The CMYK FileName ========" + fileName);
}
return image;
}
return null;
}
private static void checkAdobeMarker(File file) throws IOException, ImageReadException {
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;
}
}
}
private 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);
}
}
private static BufferedImage convertCmykToRgb(Raster cmykRaster, ICC_Profile cmykProfile) throws IOException {
if (cmykProfile == null) //读取CMYK的色彩配置文件
{
cmykProfile = ICC_Profile.getInstance(ImageTool.class.getResourceAsStream("ISOcoated_v2_300_eci.icc"));
}
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;
}
}
/** * 处理图片 * * @param src * @param outImgPath * @param new_w * @param new_h */
private synchronized static void disposeImage(BufferedImage src,
String outImgPath, int new_w, int new_h, String oldpath) {
// 得到图片
int old_w = src.getWidth();
// 得到源图宽
int old_h = src.getHeight();
// 得到源图长
BufferedImage newImg = null;
// 判断输入图片的类型
switch (src.getType()) {
/*case 0:newImg = new BufferedImage(new_w, new_h, BufferedImage.TYPE_4BYTE_ABGR);
break;*/
case 13:
// png,gifnewImg = new BufferedImage(new_w, new_h,
// BufferedImage.TYPE_4BYTE_ABGR);
break;
default:
newImg = new BufferedImage(new_w, new_h, BufferedImage.TYPE_INT_RGB);
break;
}
Graphics2D g = newImg.createGraphics();
// 从原图上取颜色绘制新图
g.drawImage(src, 0, 0, old_w, old_h, null);
g.dispose();
// 根据图片尺寸压缩比得到新图的尺寸
newImg.getGraphics().drawImage(src.getScaledInstance(new_w, new_h, Image.SCALE_SMOOTH), 0, 0,null);
// 调用方法输出图片文件
System.out.println(oldpath);
/*newImg.getGraphics().fillRect(0, 0, old_w, old_h);//填充整个屏幕
newImg.getGraphics().drawImage(src, new_w, new_h, 0,0, null); // 绘制缩小后的图
*/ OutImage(outImgPath, newImg, oldpath);
}
/**
* * 将图片文件输出到指定的路径,并可设定压缩质量 * * @param outImgPath * @param newImg * @param
* per
*/
private static void OutImage(String outImgPath, BufferedImage newImg,
String oldpath) {
// 判断输出的文件夹路径是否存在,不存在则创建
try {
File file = new File(outImgPath);
//OutputStream outputStream = new FileOutputStream(file);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}// 输出到文件流
ImageIO.write(newImg, outImgPath.substring(outImgPath.lastIndexOf(".") + 1), file);
//outputStream.close();
File oldfile = new File(oldpath);
oldfile.delete();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/*
测试
*/
public static void main(String[] args) throws IOException {
String filename = "C:/Users/Administrator/Desktop/微信图片_20190409143143.jpg";
String outImgPath= "C:/Users/Administrator/Desktop/3333.jpg";
//readImage(filename);
try {
BufferedImage src = ImageTool.readImage(new File(filename),outImgPath);
/*File file = new File(outImgPath);
//OutputStream outputStream = new FileOutputStream(file);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}// 输出到文件流
ImageIO.write(image, outImgPath.substring(outImgPath.lastIndexOf(".") + 1), file);*/
int maxLength =4000;
if (null != src) {
int old_w = src.getWidth();
// 得到源图宽
int old_h = src.getHeight();
// 得到源图长
int new_w = 0;
// 新图的宽
int new_h = 0;
// 新图的长
// 根据图片尺寸压缩比得到新图的尺寸
if (old_w > old_h && old_w >= maxLength) {
// 图片要缩放的比例
new_w = maxLength;
new_h = (int) Math.round(old_h * ((float) maxLength / old_w));
} else if (old_h >= maxLength) {
new_w = (int) Math.round(old_w * ((float) maxLength / old_h));
new_h = maxLength;
} else {//宽和高都小于最大值
new_w = old_w;
new_h = old_h;
}
disposeImage(src, outImgPath, new_w, new_h, "");
}
//outputStream.close();
} catch (ImageReadException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
//compressImage_cmyk2rgb2(filename,"C:/Users/Administrator/Desktop/3333.jpg",4000);
}