# 需求
将图 1~ 图 7 拼成图 8。
图 1
图 2
图 3
图 4
图 5
图 6
图 7
图 8
# 解决
package image; | |
import com.alibaba.fastjson.JSONObject; | |
import javax.imageio.ImageIO; | |
import java.awt.*; | |
import java.awt.image.BufferedImage; | |
import java.io.*; | |
import java.util.ArrayList; | |
import java.util.List; | |
/** | |
* Created by huihui on 2018/7/31. | |
*/ | |
public class GraphicsTest { | |
/** | |
* 改变图片的大小 | |
* @param inputStream 上传图片的输入流 | |
* @param newWidth 新图片的宽 | |
* @param newHeight 新图片的高 | |
* @return | |
*/ | |
public static BufferedImage resizeImage(InputStream inputStream, int newWidth, int newHeight) { | |
// 新的图片 | |
BufferedImage image = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB); | |
try { | |
// 读取图片 | |
BufferedImage prevImage = ImageIO.read(inputStream); | |
// 渲染图片 | |
Graphics2D graphics2D = image.createGraphics(); | |
// 此类中可以设置图片的透明度 | |
GraphicsConfiguration graphicsConfiguration = graphics2D.getDeviceConfiguration(); | |
// 设置透明度为原图片的透明度 | |
image = graphicsConfiguration.createCompatibleImage(newWidth, newHeight, prevImage.getTransparency()); | |
// 释放对象 | |
graphics2D.dispose(); | |
// 再次渲染图片 | |
graphics2D = image.createGraphics(); | |
// 创建原图的缩放版本,可以设置图片的缩放算法 | |
Image imageFrom = prevImage.getScaledInstance(newWidth, newHeight, Image.SCALE_AREA_AVERAGING); | |
graphics2D.drawImage(imageFrom, 0, 0, null); | |
graphics2D.dispose(); | |
} catch (IOException e) { | |
System.out.println("读取图片失败"); | |
} finally { | |
try { | |
inputStream.close(); | |
} catch (IOException e) { | |
System.out.println("输入输出流关闭失败"); | |
} | |
} | |
return image; | |
} | |
/** | |
* 在图片上添加水印图片 | |
* @param bottomImage 底层图片的 BufferedImage | |
* @param waterImage 水印图片的 BufferedImage | |
* @param x x 坐标 | |
* @param y y 坐标 | |
* @param alpha 透明度,选择值从 0.0 到 1.0:完全透明到完全不透明 | |
* @return | |
*/ | |
public static BufferedImage waterMark(BufferedImage bottomImage, BufferedImage waterImage, int x, int y, float alpha) { | |
Graphics2D graphics2D = bottomImage.createGraphics(); | |
int waterImageWidth = waterImage.getWidth(); | |
int waterImageHeight = waterImage.getHeight(); | |
graphics2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha)); | |
graphics2D.drawImage(waterImage, x, y, waterImageWidth, waterImageHeight, null); | |
graphics2D.dispose(); | |
return bottomImage; | |
} | |
/** | |
* 输出图片 | |
* @param bufferedImage 要输出图片的 BufferedImage | |
* @param formatName 要生成图片的类型 | |
* @param outputStream 生成图片的 OutputStream | |
*/ | |
public static void generateImage(BufferedImage bufferedImage, String formatName, OutputStream outputStream) { | |
try { | |
ImageIO.write(bufferedImage, formatName, outputStream); | |
} catch (IOException e) { | |
System.out.println("图片输出错误"); | |
} | |
} | |
public static void main(String[] args) { | |
String materialJsonArrayStr = "[\n" + | |
" {\n" + | |
" \"width\": \"1132\",\n" + | |
" \"height\": \"392\",\n" + | |
" \"x\": \"\",\n" + | |
" \"y\": \"\"\n" + | |
" },\n" + | |
" {\n" + | |
" \"width\": \"433\",\n" + | |
" \"height\": \"297\",\n" + | |
" \"x\": \"48\",\n" + | |
" \"y\": \"87\"\n" + | |
" },\n" + | |
" {\n" + | |
" \"width\": \"552\",\n" + | |
" \"height\": \"376\",\n" + | |
" \"x\": \"576\",\n" + | |
" \"y\": \"8\"\n" + | |
" },\n" + | |
" {\n" + | |
" \"width\": \"455\",\n" + | |
" \"height\": \"104\",\n" + | |
" \"x\": \"318\",\n" + | |
" \"y\": \"70\"\n" + | |
" },\n" + | |
" {\n" + | |
" \"width\": \"429\",\n" + | |
" \"height\": \"66\",\n" + | |
" \"x\": \"335\",\n" + | |
" \"y\": \"90\"\n" + | |
" },\n" + | |
" {\n" + | |
" \"width\": \"322\",\n" + | |
" \"height\": \"88\",\n" + | |
" \"x\": \"380\",\n" + | |
" \"y\": \"170\"\n" + | |
" },\n" + | |
" {\n" + | |
" \"width\": \"255\",\n" + | |
" \"height\": \"36\",\n" + | |
" \"x\": \"400\",\n" + | |
" \"y\": \"205\"\n" + | |
" }\n" + | |
"]"; | |
File file1 = new File("src/main/resources/分层_0006_背景.png"); | |
File file2 = new File("src/main/resources/分层_0000_品1.png"); | |
File file3 = new File("src/main/resources/分层_0001_品2.png"); | |
File file4 = new File("src/main/resources/分层_0003_黄色小标签.png"); | |
File file5 = new File("src/main/resources/分层_0002_每满199减100.png"); | |
File file6 = new File("src/main/resources/分层_0005_红色小标签.png"); | |
File file7 = new File("src/main/resources/分层_0004_全球年中购物节.png"); | |
File presentFile = new File("src/main/resources/成品.png"); | |
List<File> fileList = new ArrayList<>(); | |
fileList.add(file1); | |
fileList.add(file2); | |
fileList.add(file3); | |
fileList.add(file4); | |
fileList.add(file5); | |
fileList.add(file6); | |
fileList.add(file7); | |
if (!file1.exists() || !file2.exists() || !file3.exists() || !file4.exists() || !file5.exists() || !file6.exists() || !file7.exists()) { | |
return; | |
} | |
List<Material> materialList = JSONObject.parseArray(materialJsonArrayStr, Material.class); | |
try { | |
for (int i = 0; i < materialList.size(); i++) { | |
Material material = materialList.get(i); | |
material.setInputStream(new FileInputStream(fileList.get(i))); | |
materialList.set(i, material); | |
} | |
OutputStream outputStream = new FileOutputStream(presentFile); | |
String presentImageName = presentFile.getName(); | |
String formatName = presentImageName.substring(presentImageName.indexOf(".") + 1); | |
BufferedImage bottomImage = resizeImage(materialList.get(0).getInputStream(), materialList.get(0).getWidth(), materialList.get(0).getHeight()); | |
for (int i = 1; i < materialList.size(); i++) { | |
BufferedImage waterImage = resizeImage(materialList.get(i).getInputStream(), materialList.get(i).getWidth(), materialList.get(i).getHeight()); | |
bottomImage = waterMark(bottomImage, waterImage, materialList.get(i).getX(), materialList.get(i).getY(), 1.0f); | |
} | |
generateImage(bottomImage, formatName, outputStream); | |
} catch (FileNotFoundException e) { | |
e.printStackTrace(); | |
} | |
} | |
} | |
class Material { | |
private InputStream inputStream; | |
private int width; | |
private int height; | |
private int x; | |
private int y; | |
public InputStream getInputStream() { | |
return inputStream; | |
} | |
public void setInputStream(InputStream inputStream) { | |
this.inputStream = inputStream; | |
} | |
public int getWidth() { | |
return width; | |
} | |
public void setWidth(int width) { | |
this.width = width; | |
} | |
public int getHeight() { | |
return height; | |
} | |
public void setHeight(int height) { | |
this.height = height; | |
} | |
public int getX() { | |
return x; | |
} | |
public void setX(int x) { | |
this.x = x; | |
} | |
public int getY() { | |
return y; | |
} | |
public void setY(int y) { | |
this.y = y; | |
} | |
@Override | |
public String toString() { | |
return "Material{" + | |
"inputStream=" + inputStream + | |
", width=" + width + | |
", height=" + height + | |
", x=" + x + | |
", y=" + y + | |
'}'; | |
} | |
} |