首先将文件转化为BufferedImage对象(准备部分)
/**
* @param fileUrl 文件绝对路径或相对路径
* @return 读取到的缓存图像
* @throws IOException 路径错误或者不存在该文件时抛出IO异常
*/
public static BufferedImage getBufferedImage(String fileUrl)
throws IOException {
File f = new File(fileUrl);
return ImageIO.read(f);
}
/**
* 远程图片转BufferedImage
* @param destUrl 远程图片地址
* @return
*/
public static BufferedImage getBufferedImageDestUrl(String destUrl) {
HttpURLConnection conn = null;
BufferedImage image = null;
try {
URL url = new URL(destUrl);
conn = (HttpURLConnection) url.openConnection();
if (conn.getResponseCode() == 200) {
image = ImageIO.read(conn.getInputStream());
return image;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
conn.disconnect();
}
return image;
}
将BufferedImage对象保存到本地
/**
* 输出图片
* @param buffImg 图像拼接叠加之后的BufferedImage对象
* @param savePath 图像拼接叠加之后的保存路径
*/
public static void generateSaveFile(BufferedImage buffImg, String savePath) {
int temp = savePath.lastIndexOf(".") + 1;
try {
File outFile = new File(savePath);
if(!outFile.exists()){
outFile.createNewFile();
}
ImageIO.write(buffImg, savePath.substring(temp), outFile);
System.out.println("ImageIO write...");
} catch (IOException e) {
e.printStackTrace();
}
}
图片叠加的实现方法
/**
*
* @Title: 构造图片
* @Description: 生成水印并返回java.awt.image.BufferedImage
* @param buffImg 源文件(BufferedImage)
* @param waterFile 水印文件(BufferedImage)
* @param x 距离右下角的X偏移量
* @param y 距离右下角的Y偏移量
* @param alpha 透明度, 选择值从0.0~1.0: 完全透明~完全不透明
* @return BufferedImage
* @throws IOException
*/
public static BufferedImage overlyingImage(BufferedImage buffImg, BufferedImage waterImg,
int x, int y, float alpha) throws IOException {
// 创建Graphics2D对象,用在底图对象上绘图
Graphics2D g2d = buffImg.createGraphics();
int waterImgWidth = waterImg.getWidth();// 获取层图的宽度
int waterImgHeight = waterImg.getHeight();// 获取层图的高度
// 在图形和图像中实现混合和透明效果
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
// 绘制
g2d.drawImage(waterImg, x, y, waterImgWidth, waterImgHeight, null);
g2d.dispose();// 释放图形上下文使用的系统资源
return buffImg;
}
图片拼接的实现方法(两张图片):
/**
* 待合并的两张图必须满足这样的前提,如果水平方向合并,则高度必须相等;如果是垂直方向合并,宽度必须相等。
* mergeImage方法不做判断,自己判断。
* @param img1 待合并的第一张图
* @param img2 带合并的第二张图
* @param isHorizontal 为true时表示水平方向合并,为false时表示垂直方向合并
* @return 返回合并后的BufferedImage对象
* @throws IOException
*/
public static BufferedImage mergeImage(BufferedImage img1,
BufferedImage img2, boolean isHorizontal) throws IOException {
int w1 = img1.getWidth();
int h1 = img1.getHeight();
int w2 = img2.getWidth();
int h2 = img2.getHeight();
// 从图片中读取RGB
int[] ImageArrayOne = new int[w1 * h1];
ImageArrayOne = img1.getRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 逐行扫描图像中各个像素的RGB到数组中
int[] ImageArrayTwo = new int[w2 * h2];
ImageArrayTwo = img2.getRGB(0, 0, w2, h2, ImageArrayTwo, 0, w2);
// 生成新图片
BufferedImage DestImage = null;
if (isHorizontal) { // 水平方向合并
DestImage = new BufferedImage(w1+w2, h1, BufferedImage.TYPE_INT_RGB);
DestImage.setRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB
DestImage.setRGB(w1, 0, w2, h2, ImageArrayTwo, 0, w2);
} else { // 垂直方向合并
DestImage = new BufferedImage(w1, h1 + h2, BufferedImage.TYPE_INT_RGB);
DestImage.setRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB
DestImage.setRGB(0, h1, w2, h2, ImageArrayTwo, 0, w2); // 设置下半部分的RGB
}
return DestImage;
}
图片拼接的实现方法(多张图片垂直合并) :
public static BufferedImage mergeImage(ArrayList<BufferedImage> imgs) {
int h = 0;
int w = 0;
for (BufferedImage img : imgs) {
h += img.getHeight();
w = img.getWidth();
}
BufferedImage DestImage;
DestImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
int hPoint=0;
for (int i = 0; i < imgs.size(); i++) {
int width = imgs.get(i).getWidth();
int height = imgs.get(i).getHeight();
int[] ImageArray = new int[width * height];
ImageArray = imgs.get(i).getRGB(0, 0, width, height, ImageArray, 0, width); // 逐行扫描图像中各个像素的RGB到数组中
if (i == 0) {
DestImage.setRGB(0, 0, width, height, ImageArray, 0, width);
}else {
hPoint+=height;
DestImage.setRGB(0, hPoint, width, height, ImageArray, 0, width);
}
}
return DestImage;
}
测试方法
/**
* Java 测试图片叠加方法
*/
public static void overlyingImageTest() {
String sourceFilePath = "D://test//test1.jpg";
String waterFilePath = "D://test//test2.jpg";
String saveFilePath = "D://test//overlyingImageNew.jpg";
try {
BufferedImage bufferImage1 = getBufferedImage(sourceFilePath);
BufferedImage bufferImage2 = getBufferedImage(waterFilePath);
// 构建叠加层
BufferedImage buffImg = overlyingImage(bufferImage1, bufferImage2, 0, 0, 1.0f);
// 输出水印图片
generateSaveFile(buffImg, saveFilePath);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Java 测试图片合并方法
*/
public static void imageMargeTest() {
// 读取待合并的文件
BufferedImage bi1 = null;
BufferedImage bi2 = null;
// 调用mergeImage方法获得合并后的图像
BufferedImage destImg = null;
System.out.println("下面是垂直合并的情况:");
String saveFilePath = "D://test//new1.jpg";
String divingPath = "D://test//new2.jpg";
String margeImagePath = "D://test//margeNew.jpg";
try {
bi1 = getBufferedImage(saveFilePath);
bi2 = getBufferedImage(divingPath);
// 调用mergeImage方法获得合并后的图像
destImg = mergeImage(bi1, bi2, false);
} catch (IOException e) {
e.printStackTrace();
}
// 保存图像
generateSaveFile(destImg, margeImagePath);
System.out.println("垂直合并完毕!");
}
/**
* Java 测试多个图片垂直合并方法
*/
public static void manyImageMargeTest() {
String path="D:\\myWord\\ce\\";
File file = new File(path);
File[] comicFileList = file.listFiles();
for (File comicFile : comicFileList) {
//章节列表
File[] chapterFileList = comicFile.listFiles();
for (File chapterFile : chapterFileList) {
ArrayList<BufferedImage> bufferedImageList=new ArrayList<>();
//章节名
String name = chapterFile.getName();
BufferedImage destImg;
File[] imgList = chapterFile.listFiles();
for (File imgFile : imgList) {
try {
bufferedImageList.add(getBufferedImage(imgFile.getPath()));
} catch (IOException e) {
e.printStackTrace();
}
}
destImg = mergeImage(bufferedImageList);
// 保存图像
generateSaveFile(destImg,comicFile.getPath()+File.separator+ name+".png");
System.out.println(chapterFile.getPath()+File.separator+ name+".png");
}
}
}
public static void main(String[] args) {
// 测试图片的叠加
overlyingImageTest();
// 测试图片的垂直合并
imageMargeTest();
}