目录
- 前言
- 一、获取系统支持图片格式
- 二、生成自定义图片
- 三、获取图片格式
- 四、图片裁剪
- 五、图片压缩
- 六、图片水印
- 七、Thumbnails工具类
前言
本文主要使用Java对图片各种操作进行处理。
一、获取系统支持图片格式
代码:
System.out.println(Arrays.asList(ImageIO.getReaderFormatNames()));
System.out.println(Arrays.asList(ImageIO.getReaderFileSuffixes()));
System.out.println(Arrays.asList(ImageIO.getReaderMIMETypes()));
String[] writerFormatName = ImageIO.getWriterFormatNames();
String[] writerSuffixName = ImageIO.getWriterFileSuffixes();
String[] writerMIMEType = ImageIO.getWriterMIMETypes();
输出:
[JPG, jpg, tiff, pcx, PCX, bmp, BMP, gif, GIF, WBMP, png, PNG, raw, RAW, JPEG, pnm, PNM, tif, TIF, TIFF, wbmp, jpeg]
[, jpg, tiff, pcx, bmp, gif, png, ppm, tif, pgm, wbmp, jpeg, pbm]
[, image/vnd.wap.wbmp, image/png, image/jpeg, image/x-portable-graymap, image/pcx, image/bmp, image/gif, image/x-windows-pcx, image/x-windows-bmp, image/x-pc-paintbrush, image/x-pcx, image/x-bmp, image/x-png, image/x-portable-bitmap, image/x-portable-pixmap, image/tiff, image/x-portable-anymap]
二、生成自定义图片
代码:
@SneakyThrows
public static void main(String[] args) {
BufferedImage bufferedImage = new BufferedImage(, 400, BufferedImage.TYPE_INT_BGR);
Graphics g = bufferedImage.getGraphics();
try {
g.fillRect(, 40, 400, 400);
g.setColor(new Color(, 120, 120));
g.setFont(new Font("隶书", Font.BOLD,));
g.drawString("自定义图片",, 200);
ImageIO.write(bufferedImage, "jpg", new File("D:/test.jpg"));
} finally {
g.dispose();//释放画笔
}
}
输出:
三、获取图片格式
代码:
public static String getImageFormatName(File file) throws IOException {
String formatName = null;
ImageInputStream iis = ImageIO.createImageInputStream(file);
Iterator<ImageReader> imageReader = ImageIO.getImageReaders(iis);
if (imageReader.hasNext()) {
ImageReader reader = imageReader.next();
formatName = reader.getFormatName();
}
return formatName;
}
四、图片裁剪
public static String cutImage(String sourcePath, String targetPath, int x, int y, int width, int height) throws IOException {
File file = new File(sourcePath);
if (!file.exists()) {
throw new IOException("not found the image:" + sourcePath);
}
if (null == targetPath || targetPath.isEmpty()) {
targetPath = sourcePath;
}
String formatName = getImageFormatName(file);
if (null == formatName) {
return targetPath;
}
formatName = formatName.toLowerCase();
// 防止图片后缀与图片本身类型不一致的情况
String pathPrefix = getPathWithoutSuffix(targetPath);
targetPath = pathPrefix + formatName;
// GIF需要特殊处理
if (IMAGE_FORMAT.GIF.getValue() == formatName) {
GifDecoder decoder = new GifDecoder();
int status = decoder.read(sourcePath);
if (status != GifDecoder.STATUS_OK) {
throw new IOException("read image " + sourcePath + " error!");
}
AnimatedGifEncoder encoder = new AnimatedGifEncoder();
encoder.start(targetPath);
encoder.setRepeat(decoder.getLoopCount());
for (int i =; i < decoder.getFrameCount(); i++) {
encoder.setDelay(decoder.getDelay(i));
BufferedImage childImage = decoder.getFrame(i);
BufferedImage image = childImage.getSubimage(x, y, width, height);
encoder.addFrame(image);
}
encoder.finish();
} else {
BufferedImage image = ImageIO.read(file);
image = image.getSubimage(x, y, width, height);
ImageIO.write(image, formatName, new File(targetPath));
}
return targetPath;
}
五、图片压缩
public static String zoom(String sourcePath, String targetPath, int width, int height) throws IOException {
File file = new File(sourcePath);
if (!file.exists()) {
throw new IOException("not found the image :" + sourcePath);
}
if (null == targetPath || targetPath.isEmpty()) {
targetPath = sourcePath;
}
String formatName = getImageFormatName(file);
if (null == formatName) {
return targetPath;
}
formatName = formatName.toLowerCase();
String pathPrefix = getPathWithoutSuffix(targetPath);
targetPath = pathPrefix + formatName;
// GIF处理
if (IMAGE_FORMAT.GIF.getValue() == formatName) {
GifDecoder decoder = new GifDecoder();
int status = decoder.read(sourcePath);
if (status != GifDecoder.STATUS_OK) {
throw new IOException("read image " + sourcePath + " error!");
}
AnimatedGifEncoder encoder = new AnimatedGifEncoder();
encoder.start(targetPath);
encoder.setRepeat(decoder.getLoopCount());
for (int i =; i < decoder.getFrameCount(); i++) {
encoder.setDelay(decoder.getDelay(i));
BufferedImage image = zoom(decoder.getFrame(i), width, height);
encoder.addFrame(image);
}
encoder.finish();
} else {
BufferedImage image = ImageIO.read(file);
BufferedImage zoomImage = zoom(image, width, height);
ImageIO.write(zoomImage, formatName, new File(targetPath));
}
return targetPath;
}
六、图片水印
private static void waterMark(Image srcImg, String path) throws IOException {
int srcImgWidth = srcImg.getWidth(null);
int srcImgHeight = srcImg.getHeight(null);
/*
//网络图片
URL url = new URL("url");
//将URL对象输入流转化为图片对象 (url.openStream()方法,获得一个输入流)
Image srcImg = ImageIO.read(url.openStream());
//获取图片的宽
int srcImgWidth = srcImg.getWidth(null);
//获取图片的高
int srcImgHeight = srcImg.getHeight(null);
System.out.println("图片的宽:"+srcImgWidth);
System.out.println("图片的高:"+srcImgHeight);
*/
BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
// 加水印
//创建画笔
GraphicsD g = bufImg.createGraphics();
//绘制原始图片
g.drawImage(srcImg,, 0, srcImgWidth, srcImgHeight, null);
/*
//文字水印
//根据图片的背景设置水印颜色
g.setColor(new Color(, 255, 255, 128));
//设置字体 画笔字体样式为微软雅黑,加粗,文字大小为pt
g.setFont(new Font("微软雅黑", Font.BOLD,));
String waterMarkContent = "自定义水印";
//设置水印的坐标(为原图片中间位置)
int x = srcImgWidth /;
int y = srcImgHeight /;
//画出水印 第一个参数是水印内容,第二个参数是x轴坐标,第三个参数是y轴坐标
g.drawString(waterMarkContent, x, y);
g.dispose();*/
//图片水印
// 水印文件
String waterMarkImage = "D:/print.jpg";
Image srcWaterMark = ImageIO.read(new File(waterMarkImage));
//获取水印图片的宽度
int widthWaterMark = srcWaterMark.getWidth(null);
//获取水印图片的高度
int heightWaterMark = srcWaterMark.getHeight(null);
//设置 alpha 透明度:alpha 必须是范围 [.0, 1.0] 之内(包含边界值)的一个浮点数字
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,.9f));
//绘制水印图片
g.drawImage(srcWaterMark, (srcImgWidth - widthWaterMark) /,
(srcImgHeight - heightWaterMark) /, widthWaterMark, heightWaterMark, null);
// 水印文件结束
g.dispose();
//文件输出地址
String tarImgPath = path;
// 输出图片
FileOutputStream outImgStream = new FileOutputStream(tarImgPath);
ImageIO.write(bufImg, "png", outImgStream);
outImgStream.flush();
outImgStream.close();
}
七、Thumbnails工具类
通过以上对图片的各种操作,还是需要对流进行转化,那是不是已经有成型的工具类了呢?对,Thumbnails工具类就能对以上各种情况处理。
主要有以下功能处理:
- 旋转
- 水印
- 裁剪
- 指定大小进行缩放
- 按照比例进行缩放
- 不按照比例,指定大小进行缩放
- 转化图片格式
- 输出到OutputStream
- 输出到BufferedImage
代码示例如下:
依赖
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>.4.17</version>
</dependency>
代码
@SneakyThrows
public static void main(String[] args) {
//指定大小进行缩放
Thumbnails.of("D:/test.jpg").size(, 100).toFile("D:/test.jpg.jpg");
//按照比例进行缩放
// scale 图片的压缩比例 值在-1之间,1f就是原图,0.5就是原图的一半大小
// outputQuality 图片压缩的质量 值在-1 之间,越接近1质量越好,越接近0 质量越差
Thumbnails.of("D:/test.jpg").scale(.75f).outputQuality(0.8f).toFile("D:/test.jpg");
//不按照比例,指定大小进行缩放 keepAspectRatio(false) 默认是按照比例缩放的
Thumbnails.of("D:/test.jpg").size(, 100).keepAspectRatio(false).toFile("D:/test.jpg");
//旋转 rotate(角度),正数:顺时针 负数:逆时针
Thumbnails.of("D:/test.jpg").size(, 1024).rotate(90).toFile("C:/image+90.jpg");
//水印 watermark(位置,水印图,透明度)
Thumbnails.of("D:/test.jpg").size(, 1024)
.watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File("水印地址")),.5f)
.outputQuality(.4f).toFile("输出地址");
//裁剪
Thumbnails.of("D:/test.jpg").sourceRegion(Positions.CENTER,, 400).size(200, 200).keepAspectRatio(false)
.toFile("输出地址");
//转化图片格式
Thumbnails.of("D:/test.jpg").size(, 666).outputFormat("png").toFile("D:/test.png");
// 输出到OutputStream
OutputStream os = new FileOutputStream("D:/test.jpg");
Thumbnails.of("test.jpg").size(, 666).toOutputStream(os);
//输出到BufferedImage
BufferedImage thumbnail = Thumbnails.of("D:/test.jpg").size(, 666).asBufferedImage();
ImageIO.write(thumbnail, "jpg", new File("test.jpg"));
}