oss上传压缩图片格式转换失真

文章讨论了在Java中使用ImageIO和Thumbnails库进行图片压缩时可能出现的背景失真问题,特别是当从PNG转换为JPEG时。解决方案包括调整压缩比例和尺寸,以及处理透明图层。此外,还介绍了如何将压缩后的图片转换为InputStream以便上传至阿里云OSS。
摘要由CSDN通过智能技术生成
小问题:由于上传图片太大需要压缩,在使用java的ImageIO类来操作图片的时候,有时候图片生成出来背景失真

原图:

失真图片:

有三种压缩方式
按指定大小把图片进行缩放(会遵循原图宽高比例)
//按指定大小把图片进行缩和放(会遵循原图高宽比例) 
        //此处把图片压成400×500的缩略图
 Thumbnails.of(fromPic).size(400,500).toFile(toPic);
 //变为400*300,遵循原图比例缩或放到400*某个高度
按照指定比列进行缩小和放大
 //按照比例进行缩小和放大
 Thumbnails.of(fromPic).scale(0.2f).toFile(toPic);//按比例缩小
 Thumbnails.of(fromPic).scale(2f);//按比例放大
图片尺寸不变,压缩图片文件大小
//图片尺寸不变,压缩图片文件大小outputQuality实现,参数1为最高质量
Thumbnails.of(fromPic).scale(1f).outputQuality(0.25f).toFile(toPic);

toFile(pic)部分可以使用.asBufferedImager().var输出为图片缓存

.eg:

InputStream inputStream = multipartFile.getInputStream();

BufferedImage image = Thumbnails.of(inputStream).size(w, h).asBufferedImage();
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(image , "jpg", os);

return new ByteArrayInputStream(os.toByteArray());

这里由于使用阿里云传输使用putObject();接收inputStream,所以我们在这里就把[BufferedImage]转换成input流进行传输;

我这里转换的图片是jpg,如果用户上传的是png,就会造成透明图层描述错误,失真,因为png是32位图,jpg为24位图,强制转换会造成透明图层的失真

 BufferedImage newBufferedImage = new BufferedImage(bufImg.getWidth(), bufImg.getHeight(), BufferedImage.TYPE_INT_RGB);
newBufferedImage.createGraphics().drawImage(bufImg, 0, 0, Color.WHITE, null);

附上完整方法:

 public String uploadImg2Oss(MultipartFile file) {
//        if (file.getSize() > 1024 * 1024 * 1024 * 200) {
//            return "视频太大";//RestResultGenerator.createErrorResult(ResponseEnum.PHOTO_TOO_MAX);
//        }
        String originalFilename = file.getOriginalFilename();
        String substring = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
        String name = CodecUtil.createUUID() + substring;
        try {
            InputStream inputStream = file.getInputStream();
            //图片读到内存中
            BufferedImage bufImg = ImageIO.read(inputStream);
            //压缩代码
            //设置初始化压缩率为1
            float ratio = 1f;
            //设置压缩后图片宽度为80
            float width =800f;
            //获取原图宽高
            float ImgWidth = bufImg.getWidth();
            float ImgHeight = bufImg.getHeight();
            //根据原图宽度,与压缩宽度重新计算压缩率
//            if (ImgWidth > width){
//                ratio = width / ImgWidth;
//            }
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            //按压缩率进行压缩
            bufImg = Thumbnails.of(bufImg).scale(ratio).asBufferedImage();
//            //按指定大小进行压缩
//            bufImg = Thumbnails.of(bufImg).size(800,800).asBufferedImage();
            // Todo 这里我转换成了jpg格式,一旦用户传来的是png,就会造成透明图层描述错误,失真,因为png是32位图,jpg为24位图,强制转换会造成透明图层的失真
            //设置转换规格,颜色空间,传入图片image中的wh参数
            BufferedImage newBufferedImage = new BufferedImage(bufImg.getWidth(), bufImg.getHeight(), BufferedImage.TYPE_INT_RGB);
            //使用新图片缓冲流生成图片
            newBufferedImage.createGraphics().drawImage(bufImg, 0, 0, Color.WHITE, null);
            //先转成jpg压缩,然后通过oss来修改为源文件本来的后缀格式
            ImageIO.write(newBufferedImage,"jpg",bos);
            //获取输出流
            inputStream = new ByteArrayInputStream(bos.toByteArray());
            this.uploadFile2OSS(inputStream, name);
            return name;//RestResultGenerator.createSuccessResult(name);
        } catch (Exception e) {
            return "上传失败";//RestResultGenerator.createErrorResult(ResponseEnum.PHOTO_UPLOAD);
        }
    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值