写在前面
这篇文章是我在2020年2月写的,首发于我的个人博客:xeblog.cn/articles/32 。
事情起因:当时有个朋友发了张图片给我,让我给他P图,说是让我给他把自己的微信付款码给P上去,我觉得也挺有意思的,就给他P了,这一P就一发不可收拾了,天天都有人来找我P这图。
想了下,能有什么问题难倒我们程序员呢?这不就想出来了用代码实现图片组成嘛,哈哈哈~
体会地址:xeblog.cn/tools/1.htm…
先去微信那里生成微信收款码(收付款 -> 二维码收款 -> 保存收款码),然后上传,接着选择你的设备,安卓手机选安卓,苹果手机选苹果,最终点击开始组成即可。
预备阶段
原图(来源于网络)
PS处理后的模板图
待组成图片
图片组成
根本步骤
- 读取模板图和待组成图,调整待组成图的尺度、旋转视点、亮度、对比度;
- 创建一个与模板图尺度共同的空白图画;
- 创建
Graphics2D
目标,经过Graphics2D
目标的drawImage()
办法将待组成图和模板图制作进空白图画的指定方位(需求留意图层顺序,先制作待组成图,后制作模板图); - 输出空白图画(组成后的图画)到本地。
代码
图片尺度调整、旋转运用到了 Thumbnailator
, 需添加 Maven
依靠
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
</dependency>
/**
* 横坐标
*/
private static final int x = 457;
/**
* 纵坐标
*/
private static final int y = 295;
/**
* 旋转视点
*/
private static final double angle = 16;
/**
* 缩放份额
*/
private static final double scale = 0.18;
/**
* 图片组成
*
* @param imagePath 待组成的图片途径
* @param outPath 组成后的图片输出途径
* @throws IOException
*/
private static void synthesis(String imagePath, String outPath) throws IOException {
// 模板图
BufferedImage template = ImageIO.read(new File("D:\local\images\template.png"));
// 待组成图
BufferedImage image = ImageIO.read(new File(imagePath));
// 调整待组成图的尺度和旋转视点
image = Thumbnails.of(image).scale(scale).rotate(angle).asBufferedImage();
// 组成后的图
BufferedImage result = new BufferedImage(template.getWidth(), template.getHeight(), template.getType());
Graphics2D graphics2D = result.createGraphics();
// 先画待组成图,后画模板图,这样就能将待组成图放置在模板图的基层
graphics2D.drawImage(image, x, y, null);
graphics2D.drawImage(template,0,0, null);
graphics2D.dispose();
ImageIO.write(result, "png", new File(outPath));
}
运转代码
public static void main(String[] args) throws IOException {
synthesis("D:\local\images\weixin_payment_code.png", "D:\local\images\result.png");
}
调整图片亮度、对比度
/**
* 调整亮度、对比度
*
* @param image
*/
private static void adjustBrightnessAndContrast(BufferedImage image) {
int width = image.getWidth();
int height = image.getHeight();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
Color color = new Color(image.getRGB(x, y));
int red = calculateColor(color.getRed());
int green = calculateColor(color.getGreen());
int blue = calculateColor(color.getBlue());
color = new Color(red, green, blue);
image.setRGB(x, y, color.getRGB());
}
}
}
/**
* 亮度,取值规模[-1,1]
*/
private static final double BRIGHTNESS = 0;
/**
* 对比度,取值规模[-1,1]
*/
private static final double CONTRAST = -0.5;
/**
* 核算亮度、对比度色彩值
*
* @param color 原色彩值
* @return 回来核算后的色彩值
*/
private static int calculateColor(int color) {
color = (int)((color - 127.5 * (1 - BRIGHTNESS)) * Math.tan((45 + 44 * CONTRAST) / 180 * Math.PI) + 127.5 * (1 + BRIGHTNESS));
return getColor(color);
}
/**
* 获取规模内的色彩值,[0,255]
*
* @param color
* @return
*/
private static int getColor(int color) {
return color > 255 ? 255 : color < 0 ? 0 : color;
}
在处理待组成图片的尺度和旋转视点后调用 adjustBrightnessAndContrast()
办法调整亮度和对比度
...
// 调整待组成图的尺度和旋转视点
image = Thumbnails.of(image).scale(scale).rotate(angle).asBufferedImage();
// 调整待组成图片的亮度、对比度
adjustBrightnessAndContrast(image);
...
从头运转代码
体会地址:xeblog.cn/tools/1.htm…
我正在参加「创意开发 投稿大赛」详情请看:创意开发大赛来了!