Java原生代码实现使用jdk内部的GIFImageReader、GIFImageWriter等类,maven在编译的时候会提示这是sun公司的私有API,在1.7、1.8版的JDK中已经删除,所以是有风险的。
import com.oupeng.joke.domain.Image;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.sun.imageio.plugins.gif.GIFImageReader;
import com.sun.imageio.plugins.gif.GIFImageReaderSpi;
import com.sun.imageio.plugins.gif.GIFImageWriter;
import com.sun.imageio.plugins.gif.GIFImageWriterSpi;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.spi.ImageWriterSpi;
import javax.imageio.stream.FileImageInputStream;
import javax.imageio.stream.FileImageOutputStream;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;
public class ImageUtils {
private static final Logger log = LoggerFactory.getLogger(ImageUtils.class);
// public static void main(String[] args) {
// ImageUtils.getGifOneFrame("/nh/logs/c.gif", 5);
// }
/**
* 获取GIF图片一帧图片
* @param src GIF图地址
* @param target 目标地址
* @param frame 第几帧
* @return
*/
public static boolean getGifOneFrame(String src, String target, int frame) {
FileImageInputStream in = null;
FileImageOutputStream out = null;
try {
in = new FileImageInputStream(new File(src));
ImageReaderSpi readerSpi = new GIFImageReaderSpi();
GIFImageReader gifReader = (GIFImageReader) readerSpi.createReaderInstance();
gifReader.setInput(in);
int num = gifReader.getNumImages(true);
if (num > frame) {
ImageWriterSpi writerSpi = new GIFImageWriterSpi();
GIFImageWriter writer = (GIFImageWriter) writerSpi.createWriterInstance();
for (int i = 0; i < num; i++) {
if (i == frame) {
File newfile = new File(target);
out = new FileImageOutputStream(newfile);
writer.setOutput(out);
writer.write(gifReader.read(i));
return true;
}
}
}
return false;
} catch (Exception e) {
log.error(e.getMessage(), e);
return false;
} finally {
close(in, out);
}
}
/**
* 复制文件
* @param src
* @param target
* @return
*/
public static boolean copyImageToPath(String src, String target) {
InputStream in = null;
OutputStream out = null;
try {
File srcFile = new File(src);
File targetFile = new File(target);
in = new FileInputStream(srcFile);
out = new FileOutputStream(targetFile);
byte[] bytes = new byte[1024];
int len = -1;
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
}
return true;
} catch (Exception e) {
log.error(e.getMessage(), e);
return false;
} finally {
close(in, out);
}
}
/**
* 获取图片宽高
* @param file
* @return
*/
public static void getImgWidthAndHeight(File file, Image image) {
InputStream is = null;
BufferedImage src ;
try {
if(image == null){
image = new Image();
}
is = new FileInputStream(file);
src = javax.imageio.ImageIO.read(is);
image.setWidth(src.getWidth());
image.setHeight(src.getHeight());
} catch (Exception e) {
log.error(e.getMessage(), e);
} finally {
close(is, null);
}
}
/**
* 获取图片宽高
* @param file
* @return
*/
public static Image getImgWidthAndHeight(File file) {
InputStream is = null;
BufferedImage src ;
Image image = new Image();
try {
is = new FileInputStream(file);
src = javax.imageio.ImageIO.read(is);
image.setWidth(src.getWidth());
image.setHeight(src.getHeight());
} catch (Exception e) {
log.error(e.getMessage(), e);
} finally {
close(is, null);
}
return image;
}
/**
* 获取图片宽度
* @param file
* @return
*/
public static int getImgWidth(File file) {
InputStream is = null;
BufferedImage src = null;
int ret = 0;
try {
is = new FileInputStream(file);
src = javax.imageio.ImageIO.read(is);
ret = src.getWidth(); // 得到源图宽
} catch (Exception e) {
log.error(e.getMessage(), e);
} finally {
close(is, null);
}
return ret;
}
/**
* 获取图片高度
* @param file 图片文件
* @return 高度
*/
public static int getImgHeight(File file) {
InputStream is = null;
BufferedImage src;
int ret = 0;
try {
is = new FileInputStream(file);
src = javax.imageio.ImageIO.read(is);
ret = src.getHeight(); // 得到源图高
} catch (Exception e) {
log.error(e.getMessage(), e);
} finally {
close(is, null);
}
return ret;
}
/**
* 格式转换
* @param src
* @param target
* @param format
* @return
*/
public static Image generateImage(String src, String target, String format, Image image) {
try {
if(image == null){
image = new Image();
}
File input = new File(src);
BufferedImage bim = ImageIO.read(input);
image.setWidth(bim.getWidth());
image.setHeight(bim.getHeight());
File output = new File(target);
ImageIO.write(bim, format, output);
} catch (IOException e) {
log.error(e.getMessage(), e);
}
return image;
}
/**
* 关闭资源
* @param in
* @param out
*/
private static void close(Closeable in, Closeable out) {
try {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
} catch (Exception e1) {
log.error(e1.getMessage(), e1);
}
}
}
/**
* 缩放图片
* @param src
* @return
*/
public static BufferedImage zoomImage(String src, int targetWidth) {
BufferedImage result = null;
try {
File srcfile = new File(src);
if (!srcfile.exists()) {
log.error("源文件不存在:{}", src);
return null;
}
BufferedImage im = ImageIO.read(srcfile);
/* 原始图像的宽度和高度 */
int width = im.getWidth();
int height = im.getHeight();
//压缩计算
float resizeTimes = (float)targetWidth / (float)width;
BigDecimal bd = new BigDecimal((double)resizeTimes);
bd = bd.setScale(1 ,4); // (1:小数点位数, 2:表示四舍五入,可以选择其他舍值方式,例如去尾,等等.
resizeTimes = bd.floatValue();
// float resizeTimes = 0.3f; /*这个参数是要转化成的倍数,如果是1就是转化成1倍*/
/* 调整后的图片的宽度和高度 */
int toWidth = (int) (width * resizeTimes);
int toHeight = (int) (height * resizeTimes);
/* 新生成结果图片 */
result = new BufferedImage(toWidth, toHeight, BufferedImage.TYPE_INT_RGB);
result.getGraphics().drawImage( im.getScaledInstance(toWidth, toHeight, java.awt.Image.SCALE_SMOOTH), 0, 0, null);
} catch (Exception e) {
System.out.println("创建缩略图发生异常" + e.getMessage());
}
return result;
}
public static boolean writeHighQuality(BufferedImage im, String fileFullPath) {
try {
/*输出到文件流*/
FileOutputStream newimage = new FileOutputStream(fileFullPath);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(newimage);
JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(im);
/* 压缩质量 */
jep.setQuality(0.9f, true);
encoder.encode(im, jep);
/*近JPEG编码*/
newimage.close();
return true;
} catch (Exception e) {
return false;
}
}
public static boolean widthCutting(String source, String target, int width){
return ImageUtil.writeHighQuality(ImageUtil.zoomImage(source, width), target);
}
上面的工具类中使用了Image对象
public class Image {
/**
* 宽度
*/
private Integer width;
/**
* 高度
*/
private Integer height;
/**
* 路径
*/
private String path;
public Integer getWidth() {
return width;
}
public void setWidth(Integer width) {
this.width = width;
}
public Integer getHeight() {
return height;
}
public void setHeight(Integer height) {
this.height = height;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
}
第一步,需要在项目中加入im4java的Maven依赖
<dependency>
<groupId>org.im4javagroupId>
<artifactId>im4javaartifactId>
<version>1.4.0version>
dependency>
第二步, 创建工具类
import org.im4java.core.ConvertCmd;
import org.im4java.core.IMOperation;
import org.im4java.core.IdentifyCmd;
import org.im4java.core.ImageCommand;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class Im4JavaUtils {
private static final Logger logger = LoggerFactory.getLogger(Im4JavaUtils.class);
/** 是否使用 GraphicsMagick (Windows下为true) **/
private static final boolean USE_GRAPHICS_MAGICK_PATH = false;
/** ImageMagick 安装目录 **/
private static final String IMAGE_MAGICK_PATH = "C:\\Program Files\\ImageMagick-6.3.9-Q8";
/** GraphicsMagick 安装目录 **/
private static final String GRAPHICS_MAGICK_PATH = "C:\\Program Files\\GraphicsMagick-1.3.23-Q8";
/**
* 获取 ImageCommand
* @param comm 命令类型(convert, identify)
* @return
*/
private static ImageCommand getImageCommand(String comm) {
ImageCommand cmd = null;
if ("convert".equalsIgnoreCase(comm)) {
cmd = new ConvertCmd(USE_GRAPHICS_MAGICK_PATH);
} else if ("identify".equalsIgnoreCase(comm)) {
cmd = new IdentifyCmd(USE_GRAPHICS_MAGICK_PATH);
} // else if....
// Windows环境下需要配置应用路径
if (cmd != null && System.getProperty("os.name").toLowerCase().indexOf("windows") != -1) {
cmd.setSearchPath(USE_GRAPHICS_MAGICK_PATH ? GRAPHICS_MAGICK_PATH : IMAGE_MAGICK_PATH);
}
return cmd;
}
/**
* 降低品质,以减小文件大小
* @param path 原文件路径
* @param des 目标文件路径
* @param quality 保留品质(1-100)
* @throws Exception
*/
public static void reduceQuality(String path, String des, double quality) throws Exception {
createDirectory(des);
IMOperation op = new IMOperation();
op.addImage(path);
op.quality(quality);
op.addImage(des);
ConvertCmd cmd = (ConvertCmd) getImageCommand("convert");
cmd.run(op);
}
/**
* 改变图片大小比例
* @param path 原文件路径
* @param des 目标文件路径
* @param ratio 缩放比例
* @throws Exception
*/
public static void resizeImage(String path, String des, String ratio) throws Exception {
// 创建目标文件
createDirectory(des);
IMOperation op = new IMOperation();
op.addImage(path);
op.addRawArgs(ratio);
op.addImage(des);
ConvertCmd cmd = (ConvertCmd) getImageCommand("convert");
cmd.run(op);
}
/**
* 等比缩放图片(如果width为空,则按height缩放; 如果height为空,则按width缩放)
* @param path 原文件路径
* @param des 目标文件路径
* @param width 缩放后的宽度
* @param height 缩放后的高度
* @param sample 是否以缩放方式,而非缩略图方式
* @throws Exception
*/
public static void scaleResizeImage(String path, String des, Integer width, Integer height, boolean sample) throws Exception {
createDirectory(des);
IMOperation op = new IMOperation();
op.addImage(path);
if (sample) op.resize(width, height);
else op.sample(width, height);
op.addImage(des);
ConvertCmd cmd = (ConvertCmd) getImageCommand("convert");
cmd.run(op);
}
/**
* 从原图中裁剪出新图
* @param path 原文件路径
* @param des 目标文件路径
* @param x 原图左上角
* @param y 原图左上角
* @param width 新图片宽度
* @param height 新图片高度
* @throws Exception
*/
public static void cropImage(String path, String des, int x, int y, int width, int height) throws Exception {
createDirectory(des);
IMOperation op = new IMOperation();
op.addImage(path);
op.crop(width, height, x, y);
op.addImage(des);
ConvertCmd cmd = (ConvertCmd) getImageCommand("convert");
cmd.run(op);
}
/**
* 将图片分割为若干小图
* @param path 原文件路径
* @param des 目标文件路径
* @param width 指定宽度(默认为完整宽度)
* @param height 指定高度(默认为完整高度)
* @return 小图路径
* @throws Exception
*/
public static List subsectionImage(String path, String des, Integer width, Integer height) throws Exception {
createDirectory(des);
IMOperation op = new IMOperation();
op.addImage(path);
op.crop(width, height);
op.addImage(des);
ConvertCmd cmd = (ConvertCmd) getImageCommand("convert");
cmd.run(op);
return getSubImages(des);
}
/**
*
*
去除Exif信息
* 按指定的宽度等比缩放图片
* 降低图片品质
* 将图片分割分指定高度的小图
*
* @param path 原文件路径
* @param des 目标文件路径
* @param width 指定宽度
* @param subImageHeight 指定高度
* @param quality 保留品质
* @return 小图路径
* @throws Exception
*
*/
public static List大家还可以参考我专栏中的其他文章:
(1)Java图片处理 - 安装ImageMagick库使用convert命令
(2)Java图片处理 - 创建工具类
(3)Java图片处理 - 复制
(4)Java图片处理 - 缩放图片
(5)Java图片处理 - gif图获取一帧图片