解决x-file-storage缩略图质量不高、PNG黑色背景的问题

最近把图片系统迁移到x-file-storage,发现x-file-storage使用thumbnail还是没有处理图片质量问题和PNG透明背景变黑的问题。

看了下以前的代码,又研究了下x-file-storage源码,写了个辅助类解决了这个问题

package org.dromara.x.file.storage.core.upload;

import net.coobird.thumbnailator.ThumbnailParameter;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.filters.ImageFilter;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import java.util.function.Consumer;

/**
 * x-file-storage支持缩略图透明色处理为白色背景
 * 缩略图自动质量:长x宽=40000以下使用高质量,否则使用普通质量
 * @author JIM 2024-03-07
 */
public class CcUploadPretreatment extends UploadPretreatment {

    private static final double JPEG_QUALITY_HIGH = 0.95f;
    private static final double JPEG_QUALITY_LOW = 0.85f; //Thumbnailator 默认的质量

    private static class ThumbnailsImgFilter implements ImageFilter { //将压缩后的图片背景设置为白色
        @Override
        public BufferedImage apply(BufferedImage img) {
            int w = img.getWidth();
            int h = img.getHeight();
            BufferedImage newImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
            Graphics2D graphic = newImage.createGraphics();
            graphic.setColor(Color.white);//white
            graphic.fillRect(0, 0, w, h);
            graphic.drawRenderedImage(img, null);
            graphic.dispose();
            return newImage;
        }
    }
    private static final ThumbnailsImgFilter thumbnailsImgFilter = new ThumbnailsImgFilter();

    public CcUploadPretreatment(UploadPretreatment pre) {
        setFileStorageService(pre.getFileStorageService());
        setPlatform(pre.getPlatform());
        setFileWrapper(pre.getFileWrapper());
        setThumbnailBytes(pre.getThumbnailBytes());
        setThumbnailSuffix(pre.getThumbnailSuffix());
        setObjectId(pre.getObjectId());
        setObjectType(pre.getObjectType());
        setPath(pre.getPath());
        setSaveFilename(pre.getSaveFilename());
        setSaveThFilename(pre.getSaveThFilename());
        setThContentType(pre.getThContentType());
        setMetadata(pre.getMetadata());
        setUserMetadata(pre.getUserMetadata());
        setThMetadata(pre.getThMetadata());
        setThUserMetadata(pre.getThUserMetadata());
        setNotSupportMetadataThrowException(pre.getNotSupportMetadataThrowException());
        setNotSupportAclThrowException(pre.getNotSupportAclThrowException());
        setAttr(pre.getAttr());
        setProgressListener(pre.getProgressListener());
        setInputStreamPlus(pre.getInputStreamPlusDirect());
        setFileAcl(pre.getFileAcl());
        setThFileAcl(pre.getThFileAcl());
        setHashCalculatorManager(pre.getHashCalculatorManager());
    }

    private void configureThumbnail(Thumbnails.Builder<? extends InputStream> th, int width, int height) {
        th.size(width, height);
        th.outputQuality(width * height > 40000 ? JPEG_QUALITY_LOW : JPEG_QUALITY_HIGH);
        th.addFilter(thumbnailsImgFilter);
    }
    @Override
    public UploadPretreatment thumbnail(int width, int height) {
        return thumbnail(th -> configureThumbnail(th, width, height));
    }

}

使用方法:
在upload前,使用本类包装一下再调用upload方法。
原代码:

    @PostMapping("upload")
    @ApiOperation(value = "将文件上传至临时文件区", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public FileInfo upload(@RequestParam("file") MultipartFile file, Integer thumbWidth, Integer thumbHeight) {
        UploadPretreatment uploadPretreatment = fileStorageService.of(file).setPath(GlobalEx.UPLOAD_TEMP_DIR + "/");
        if(thumbWidth != null && thumbHeight != null){
            uploadPretreatment.thumbnail(thumbWidth, thumbHeight);
        }
        return uploadPretreatment.upload();
    }



修改为:

    @PostMapping("upload")
    @ApiOperation(value = "将文件上传至临时文件区", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public FileInfo upload(@RequestParam("file") MultipartFile file, Integer thumbWidth, Integer thumbHeight) {
        UploadPretreatment uploadPretreatment = fileStorageService.of(file).setPath(GlobalEx.UPLOAD_TEMP_DIR + "/");
        CcUploadPretreatment ccUploadPretreatment = new CcUploadPretreatment(uploadPretreatment);
        if(thumbWidth != null && thumbHeight != null){
            ccUploadPretreatment.thumbnail(thumbWidth, thumbHeight);
        }
        return ccUploadPretreatment.upload();
    }

图片质量0.95已经差不多了,当然你也可以使用1.0(100%)和0.95差别感觉不大但是缩略图大了1/3左右

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值