Java图片操作
这是一个简单的可以但不限于用于给添加图片或文字水印的工具类, 日后其他图片操作可以以此为基础进行增修
主要逻辑
- 获取图片的
BufferedImage, 或者新建一个, 作为画布 - 新建
Graphic图像并进行绘制, 可以绘制图像或文字或其他几何图案 - 绘制完成后将图像
dispose
类似但不完全学习MyBatis-Plus的做法, 使用ComposeWrapper封装组合条件
java
package io.tomoto.util;
import javafx.util.Pair;
import lombok.*;
import lombok.experimental.Accessors;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
/**
* 图片组合工具类
*
* @author Tomoto
* @version 1.0
* @since 1.0 2022/4/7 11:47
*/
public class ImageComposeUtil {
/**
* 获取图片BufferedImage类型值
*
* @param imagePath 图片路径
* @return BufferedImage
*/
public static BufferedImage getBufferedImage(String imagePath) {
// ImageIO.read(file) 会出现图片变红问题, 故不使用
Image image = Toolkit.getDefaultToolkit().getImage(imagePath);
if (image instanceof BufferedImage) {
return (BufferedImage) image;
}
// 确保加载所有像素
image = new ImageIcon(image).getImage();
BufferedImage bimage;
try {
bimage = GraphicsEnvironment
.getLocalGraphicsEnvironment()
.getDefaultScreenDevice()
.getDefaultConfiguration()
.createCompatibleImage(
image.getWidth(null),
image.getHeight(null),
Transparency.OPAQUE);
} catch (HeadlessException ignore) {
int type = BufferedImage.TYPE_INT_RGB;
bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
}
// 将图像绘制进BufferedImage
Graphics g = bimage.createGraphics();
g.drawImage(image, 0, 0, null);
g.dispose();
return bimage;
}
/**
* 将图片导出为jpg格式文件
*
* @param outputPath 文件导出完整路径, 包含文件名
* @param image BufferedImage图片
*/
public static void toJpg(String outputPath, BufferedImage image) {
try {
// 若使用JPEGImageEncoder进行图片输出, 在程序打包时会出现com.sun.image.codec.jpeg不存在的问题, 故不使用
ImageIO.write(image, "jpg", new File(outputPath));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 图片组合文字
*
* @param origin 原图路径
* @param attach 文字数据
* @param wrapper 组合条件
* @return BufferedImage
*/
public static BufferedImage composeText(String origin, String attach, ComposeWrapper wrapper) {
BufferedImage originalImage = getBufferedImage(origin);
return composeText(originalImage, attach, wrapper);
}
/**
* 图片组合文字
*
* @param origin 原图
* @param attach 文字数据
* @param wrapper 组合条件
* @return BufferedImage
*/
public static BufferedImage composeText(BufferedImage origin, String attach, ComposeWrapper wrapper) {
Pair<Integer, Integer> position = wrapper.getPosition();
position = position == null ? new Pair<>(0, 0) : position;
Font font = wrapper.getFont();
Color color = wrapper.getColor();
AffineTransform transform = wrapper.getTransform();
Graphics2D graphics = origin.createGraphics();
if (font != null) {
graphics.setFont(font);
} else {
font = graphics.getFont();
}
if (color != null) {
graphics.setColor(color);
}
if (transform != null) {
graphics.setTransform(transform);
}
graphics.drawString(attach, position.getKey(), position.getValue() + font.getSize());
graphics.dispose();
return origin;
}
/**
* 图片组合图片
*
* @param origin 原图路径
* @param attach 附加图片路径
* @param wrapper 组合条件
* @return BufferedImage
*/
public static BufferedImage composeImage(String origin, String attach, ComposeWrapper wrapper) {
BufferedImage originalImage = getBufferedImage(origin);
BufferedImage attachedImage = getBufferedImage(attach);
return composeImage(originalImage, attachedImage, wrapper);
}
/**
* 图片组合图片
*
* @param origin 原图
* @param attach 附加图片
* @param wrapper 组合条件
* @return BufferedImage
*/
public static BufferedImage composeImage(BufferedImage origin, BufferedImage attach, ComposeWrapper wrapper) {
Pair<Integer, Integer> position = wrapper.getPosition();
position = position == null ? new Pair<>(0, 0) : position;
Pair<Integer, Integer> size = wrapper.getImageSize();
size = size == null ? new Pair<>(attach.getWidth(), attach.getHeight()) : size;
Composite composite = wrapper.getComposite();
AffineTransform transform = wrapper.getTransform();
Graphics2D graphics = origin.createGraphics();
if (composite != null) {
graphics.setComposite(composite);
}
if (transform != null) {
graphics.setTransform(transform);
}
graphics.drawImage(attach, position.getKey(), position.getValue(), size.getKey(), size.getValue(), null);
graphics.dispose();
return origin;
}
/**
* 组合条件封装
*/
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@ToString
@EqualsAndHashCode
public static class ComposeWrapper {
/**
* 位置(x, y)
* <p>
* 默认为(0, 0)
*/
private Pair<Integer, Integer> position = new Pair<>(0, 0);
/**
* 图片尺寸(width, height)
*/
private Pair<Integer, Integer> imageSize;
/**
* 组合条件
* <p>
* 可用于设置透明度
*/
private Composite composite;
/**
* 形变
*/
private AffineTransform transform;
/**
* 字体
* <p>
* 仅对文字有效
*/
private Font font;
/**
* 文字颜色
* <p>
* 仅对文字有效, 默认为黑色
*/
private Color color = Color.BLACK;
/**
* 设置坐标
*
* @param x x
* @param y y
* @return this
*/
public ComposeWrapper setPosition(Integer x, Integer y) {
position = new Pair<>(x, y);
return this;
}
/**
* 设置尺寸
*
* @param width 宽
* @param height 高
* @return this
*/
public ComposeWrapper setImageSize(Integer width, Integer height) {
imageSize = new Pair<>(width, height);
return this;
}
/**
* 设置透明度
* <p>
* 仅对图片有效, 文字透明度通过Font设置
*
* @param opacity 透明度
* @return this
*/
public ComposeWrapper setOpacity(Float opacity) {
composite = AlphaComposite.SrcOver.derive(opacity);
return this;
}
/**
* 设置旋转角度
* <p>
* 此操作会将当前坐标作为锚点, 需要在设置坐标后再设置
*
* @param angle 角度
* @return this
*/
public ComposeWrapper setRotate(Double angle) {
transform = new AffineTransform();
transform.rotate(angle, position.getKey(), position.getValue());
return this;
}
}
}