java 图片 缩略图_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 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 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 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 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 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

这张图片看起来失真情况就比上面那张好很多了,文中示例只写到了四宫格,如果需要九宫格的话,可以再补充一下,增加一个九宫格的图片切割长宽即可!

4、公众号

如果你觉得我的文章对你有帮助话,欢迎关注我的微信公众号:"一个快乐又痛苦的程序员"(无广告,单纯分享原创文章、已pj的实用工具、各种Java学习资源,期待与你共同进步)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值