写在前面

这篇文章是我在2020年2月写的,首发于我的个人博客:xeblog.cn/articles/32 。

事情起因:当时有个朋友发了张图片给我,让我给他P图,说是让我给他把自己的微信付款码给P上去,我觉得也挺有意思的,就给他P了,这一P就一发不可收拾了,天天都有人来找我P这图。

用代码帮朋友处理P图问题

想了下,能有什么问题难倒我们程序员呢?这不就想出来了用代码实现图片组成嘛,哈哈哈~

体会地址:xeblog.cn/tools/1.htm…

先去微信那里生成微信收款码(收付款 -> 二维码收款 -> 保存收款码),然后上传,接着选择你的设备,安卓手机选安卓,苹果手机选苹果,最终点击开始组成即可。

预备阶段

原图(来源于网络)

用代码帮朋友处理P图问题

PS处理后的模板图

用代码帮朋友处理P图问题

待组成图片

用代码帮朋友处理P图问题

图片组成

根本步骤

  • 读取模板图和待组成图,调整待组成图的尺度、旋转视点、亮度、对比度;
  • 创建一个与模板图尺度共同的空白图画;
  • 创建 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");
}

用代码帮朋友处理P图问题

调整图片亮度、对比度

/**
 * 调整亮度、对比度
 *
 * @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);
...

从头运转代码

用代码帮朋友处理P图问题

体会地址:xeblog.cn/tools/1.htm…

我正在参加「创意开发 投稿大赛」详情请看:创意开发大赛来了!