Java保真组合图片以及生成缩略图
业务需求:
在推送商品给买家的时候,可能会推送多个商品,每个商品对应一张图片,现在只需要发送一条消息,那么就需要将多张图片组合成一张自定义大小的图片。
1、举例
尺寸:648*300
尺寸:1080*454
尺寸:600*300
尺寸:800*500
如果传进来了两张图片,那么合成自定义大小的二宫格图片,如果传进来四张图片,合成自定义大小的四宫格图片(
九宫格等等的可以再自己增加一下
)
2、尝试先等比缩小或放大图片,然后组合(测试后发现好像不太行)
- 1、先尝试生成图片自定义大小的缩略图
/**
* 生成缩略图
* @param imgsrc 图片路径
* @param imgdist 输出路径
* @param widthdist 缩放后图片长
* @param heightdist 缩放后图片宽
public static void reduceImg(String imgsrc, String imgdist, int widthdist, int heightdist) {
try {
File srcfile = new File(imgsrc);
if (!srcfile.exists()) {
return;
Image src = javax.imageio.ImageIO.read(srcfile);
BufferedImage tag= new BufferedImage(widthdist, heightdist, BufferedImage.TYPE_INT_RGB);
tag.getGraphics().drawImage(src.getScaledInstance(widthdist, heightdist, Image.SCALE_SMOOTH), 0, 0, null);
FileOutputStream out = new FileOutputStream(imgdist);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
encoder.encode(tag);
out.close();
} catch (IOException ex) {
ex.printStackTrace();
public static void main(String[] args) {
try {
ImageUtils.reduceImg("/Users/weiwanxi/Downloads/写作图片/aqs.jpeg", "/Users/weiwanxi/Downloads/写作图片/treasureMap.jpg", 324, 150);
} catch (Exception e) {
System.out.print(e.getMessage());
测试之后生成的图片:
这一步缩略图其实是可以的,按照固定大小缩放也没有失真,至于我说的不行,是下面这一步。
- 2、先尝试生成四张图片的缩略图,然后组合成四宫格
public class ImageUtils2 {
* 合成图片
* @param imageList 图片路径集合
* @param width 合成图片的长
* @param height 合成图片的宽
* @throws Exception
public static void syntheticImage(List<String> imageList, int width, int height) throws Exception {
// 如果只有一张图片,直接返回
if (imageList.size() == 1){
return;
// 构造一个类型为预定义图像类型之一的BufferedImage,宽高为传进来的参数
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 创建输出流
FileOutputStream out = new FileOutputStream("/Users/weiwanxi/Downloads/写作图片/treasureMap.jpg");
// 制图的宽(长是一样的)
int syntheticHeight = 0;
// 图片缩放的大小
int zoomWeight, zoomHeight = 0;
// 二宫格
if (imageList.size() == 2){
zoomWeight = width / 2;
zoomHeight = height / 2;
syntheticHeight = height;
} // 四宫格
else if (imageList.size() <= 4){
zoomWeight = width / 4;
zoomHeight = height / 4;
syntheticHeight = height/ 2;
}else {
throw new RuntimeException();
BufferedImage img = null;
for (int i = 0; i < imageList.size(); i++){
// 绘制合成图像
Graphics g = bufferedImage.createGraphics();
try {
File file = new File(imageList.get(i));
img = reduceImg(file, zoomWeight, zoomHeight);
assert img != null;
switch (i){
case 0:
g.drawImage(img, 0, 0, width/2, syntheticHeight, null);
break;
case 1:
g.drawImage(img, width/2, 0, width/2, syntheticHeight, null);
break;
case 2:
g.drawImage(img, 0, height/2, width/2, height/2, null);
break;
case 3:
g.drawImage(img, width/2, height/2, width/2, height/2, null);
default:
break;
}catch (Exception e){
throw new RuntimeException("绘图出现异常");
}finally {
// 释放此图形的上下文以及它使用的所有系统资源。
g.dispose();
//将绘制的图像生成至输出流
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
encoder.encode(bufferedImage);
//关闭输出流
out.close();
System.out.println("合成图片完成咯。。");
* 生成缩略图
* @param image
* @param width
* @param height
* @return
public static BufferedImage reduceImg(File image, int width, int height) {
BufferedImage tag = null;
try {
Image src = ImageIO.read(image);
tag= new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 绘制图片
tag.getGraphics().drawImage(src.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);
} catch (IOException ex) {
ex.printStackTrace();
return tag;
测试:
public static void main(String[] args) {
try {
List<String> list = new ArrayList<>();
list.add("/Users/weiwanxi/Downloads/写作图片/aqs.jpeg");
list.add("/Users/weiwanxi/Downloads/写作图片/说着说着.jpg");
list.add("/Users/weiwanxi/Downloads/写作图片/线程池.png");
list.add("/Users/weiwanxi/Downloads/写作图片/乐观锁与悲观锁.jpg");
ImageUtils2.syntheticImage(list, 648, 300);
} catch (Exception e) {
System.out.print(e.getMessage());
合成后图片:648*300
可以看到,这样合成的图片失真是比较严重的,字都模糊不清,然后我就尝试了下面这种办法。
3、切割合成图片的大小,不在比例缩放,由image自动填充
public class ImageUtils {
* 合成图片
* @param imageList 图片路径集合
* @param width 合成图片的长
* @param height 合成图片的宽
* @throws Exception
public static void syntheticImage(List<String> imageList, int width, int height) throws Exception {
// 如果只有一张图片,直接返回
if (imageList.size() == 1){
return;
// 构造一个类型为预定义图像类型之一的BufferedImage,宽高为传进来的参数
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 创建输出流
FileOutputStream out = new FileOutputStream("/Users/weiwanxi/Downloads/写作图片/treasureMap2.jpg");
// 制图的宽(长是一样的)
int syntheticHeight = 0;
// 二宫格
if (imageList.size() == 2){
syntheticHeight = height;
} // 四宫格
else if (imageList.size() <= 4){
syntheticHeight = height/ 2;
}else {
throw new RuntimeException();
BufferedImage img = null;
for (int i = 0; i < imageList.size(); i++){
// 绘制合成图像
Graphics g = bufferedImage.createGraphics();
try {
File file = new File(imageList.get(i));
img = javax.imageio.ImageIO.read(file);
assert img != null;
switch (i){
case 0:
g.drawImage(img, 0, 0, width/2, syntheticHeight, null);
break;
case 1:
g.drawImage(img, width/2, 0, width/2, syntheticHeight, null);
break;
case 2:
g.drawImage(img, 0, height/2, width/2, height/2, null);
break;
case 3:
g.drawImage(img, width/2, height/2, width/2, height/2, null);
default:
break;
}catch (Exception e){
throw new RuntimeException("绘图出现异常");
}finally {
// 释放此图形的上下文以及它使用的所有系统资源。
g.dispose();
//将绘制的图像生成至输出流
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
encoder.encode(bufferedImage);
//关闭输出流
out.close();
System.out.println("合成图片完成咯。。");
测试(二宫格):
public static void main(String[] args) {
try {
List<String> list = new ArrayList<>();
list.add("/Users/weiwanxi/Downloads/写作图片/aqs.jpeg");
list.add("/Users/weiwanxi/Downloads/写作图片/说着说着.jpg");
// list.add("/Users/weiwanxi/Downloads/写作图片/线程池.png");
// list.add("/Users/weiwanxi/Downloads/写作图片/乐观锁与悲观锁.jpg");
ImageUtils.syntheticImage(list, 648, 300);
} catch (Exception e) {
System.out.print(e.getMessage());
合成后图片:648*300
测试(四宫格):
public static void main(String[] args) {
try {
List<String> list = new ArrayList<>();
list.add("/Users/weiwanxi/Downloads/写作图片/aqs.jpeg");
list.add("/Users/weiwanxi/Downloads/写作图片/说着说着.jpg");
list.add("/Users/weiwanxi/Downloads/写作图片/线程池.png");
list.add("/Users/weiwanxi/Downloads/写作图片/乐观锁与悲观锁.jpg");