java图片压缩踩过的坑

java图片压缩踩过的坑

使用谷歌压缩工具Thumbnailator, 支持 图片缩放,区域裁剪,水印,旋转等,自行研究

         <!-- 图片压缩 -->
          <dependency>
                <groupId>net.coobird</groupId>
                <artifactId>thumbnailator</artifactId>
                <version>0.4.8</version>
            </dependency>

保持图片尺寸不变,压缩大小,代码如下:

import net.coobird.thumbnailator.Thumbnails;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 图片压缩
 * @author
 */
@Slf4j
public class ImageCompressUtil {

    /**
     * 图片质量压缩,不改变大小
     * @param file
     * @param destPath
     * @param quality
     * @return
     * @throws IOException
     */
    public static String compressImage(File file, String destPath, float quality) {
        try {
            if (!file.exists()) {
                log.error("compressImage file not found 文件不存在");
                throw new FileNotFoundException("文件不存在");
            }

            File destFile = new File(destPath);
            if (!destFile.exists() && destFile.isDirectory()) {
                destFile.mkdirs();
            }

            String destFileUrl = destPath + File.separator + file.getName();
            Thumbnails.of(file)
                    .scale(1f)
                    .outputQuality(quality)
                    .toFile(destFileUrl);

            return destFileUrl;
        } catch (IOException e) {
            log.error("e");
            return "";
        }
    }

    /**
     * 压缩图片
     * @param httpUrl  图片地址
     * @param destPath
     * @return
     */
    public static String compressHttpUrl(String httpUrl, String destPath) {
        try {
            URL url = new URL(httpUrl);
            HttpURLConnection connection = (HttpURLConnection)url.openConnection();
            InputStream input = connection.getInputStream();
            String destUrl = destPath + httpUrl.substring(httpUrl.lastIndexOf('/'));
            Thumbnails.of(input)
                    .scale(1f)
//                    .size(200, 500)   大小
//                    .outputQuality(0.5f) 质量
//                    .outputFormat("jpg") 图片格式
//                    .useOriginalFormat() 使用原文件格式
                    .toFile(destUrl);
            input.close();
            return destUrl;
        } catch (IOException e) {
            log.error("压缩图片异常");
            return "";
        }
    }

    public static void main(String[] args) {
//        String url = "";
//        String destPath = "C:/test/image";
//        compressImage(new File(url), destPath, 0.25f);
//        compressHttpUrl(url, destPath);
    }
}

利用上面的代码进行图片压缩时,非jpeg格式的图片会出现 Unsupported Image Type
在不改变代码基础可以借助第三方包解决:
引入twelvemonkeys 自动发现

        <dependency>
            <groupId>com.twelvemonkeys.imageio</groupId>
            <artifactId>imageio-jpeg</artifactId>
            <version>3.4.1</version>
        </dependency>

第二种方式,利用ImageIO和twelvemonkeys 进行压缩

/**
     * 图片质量压缩,大小不变
     * @param url
     * @param destFilePath
     * @param quality 0-1
     * @return
     */
    public static String compressImageQuality(String url, String destFilePath, float quality) {
        log.info("compressPictureByQuality 图片压缩|url:" + url + ";destFilePath:" + destFilePath
                + ";quality:" + quality);
        String destFileUrl = destFilePath + url.substring(url.lastIndexOf("/"));
        File destFileDir = new File(destFilePath);
        if (!destFileDir.exists()) {
            destFileDir.mkdirs();
        }

        File destFile = new File(destFileUrl);

        try (FileOutputStream out = new FileOutputStream(destFile)) {
            File file = new File(url);
            if (!file.exists()) {
                log.error("Not Found Img File,文件不存在");
                throw new FileNotFoundException("Not Found Img File,文件不存在");
            }

            log.info("图片压缩前大小" + file.length() + "字节");

            ImageWriteParam imgWriteParams = new javax.imageio.plugins.jpeg.JPEGImageWriteParam(null);
            // 要使用压缩,必须指定压缩方式为MODE_EXPLICIT
            imgWriteParams.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
            // 这里指定压缩的程度,参数quality是取值0~1范围内,
            imgWriteParams.setCompressionQuality(quality);
            imgWriteParams.setProgressiveMode(ImageWriteParam.MODE_DISABLED);
            // 使用RGB格式
            ColorModel colorModel = ColorModel.getRGBdefault();
            // 文件
            BufferedImage bufferedImage = ImageIO.read(file);
            // 指定压缩时使用的色彩模式
            imgWriteParams.setDestinationType(new javax.imageio.ImageTypeSpecifier(colorModel,
                    colorModel.createCompatibleSampleModel(
                            bufferedImage.getWidth(), bufferedImage.getHeight())));

            // 指定写图片的方式为 jpg
            ImageWriter imgWriter = ImageIO.getImageWritersByFormatName("jpg").next();
            imgWriter.reset();
            // 必须先指定out值,才能调用write方法, ImageOutputStream可以通过任何OutputStream构造
            imgWriter.setOutput(ImageIO.createImageOutputStream(out));
            // 调用write方法,就可以向输入流写图片
            imgWriter.write(null, new IIOImage(bufferedImage, null, null),
                    imgWriteParams);
            log.info("结束设定压缩图片参数");
            bufferedImage.flush();
            out.flush();

            log.info("图片压缩后大小" + destFile.length() + "字节");
            return destFileUrl;
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }
踩坑说明:
DataInputStream dataInputStream;
Thumbnails.of(dataInputStream).size(width, height).keepAspectRatio(false).useOriginalFormat().toFile(destFileUrl);
直接使用Thumbnails.of(dataInputStream) 会出现错误:UnsupportedFormatException: No suitable ImageReader found for source data
解决方法:
  1.把input存成本地文件,利用本地文件路径操作 Thumbnails.of(url)
  2.转换成BufferedImage
     BufferedImage bufferedImage = ImageIO.read(dataInputStream);
     Thumbnails.of(bufferedImage ).size(width, height).keepAspectRatio(false).useOriginalFormat().toFile(destFileUrl);

更多压缩方式可以参考:https://blog.csdn.net/zmx729618/article/details/78729049

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Java 中可以使用 ImageIO 类和 BufferedImage 类来进行图片压缩操作。以下是一个简单的示例代码: ```java import java.awt.Dimension; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; public class ImageCompressor { public static void main(String[] args) throws IOException { File inputFile = new File("input.jpg"); BufferedImage inputImage = ImageIO.read(inputFile); int maxWidth = 800; int maxHeight = 600; Dimension newDimension = getScaledDimension(new Dimension(inputImage.getWidth(), inputImage.getHeight()), new Dimension(maxWidth, maxHeight)); BufferedImage outputImage = new BufferedImage(newDimension.width, newDimension.height, BufferedImage.TYPE_INT_RGB); outputImage.getGraphics().drawImage(inputImage.getScaledInstance(newDimension.width, newDimension.height, Image.SCALE_SMOOTH), 0, 0, null); File outputFile = new File("output.jpg"); ImageIO.write(outputImage, "jpg", outputFile); } public static Dimension getScaledDimension(Dimension imageSize, Dimension boundary) { int width = imageSize.width; int height = imageSize.height; int maxWidth = boundary.width; int maxHeight = boundary.height; double ratio = Math.min((double) maxWidth / width, (double) maxHeight / height); return new Dimension((int) (width * ratio), (int) (height * ratio)); } } ``` 上述代码中,首先读取一张图片(假设为 input.jpg),然后指定最大宽度和最大高度进行压缩。使用 `getScaledDimension` 方法计算新的宽度和高度,然后创建一个新的 `BufferedImage` 对象并将原始图片缩放到新的尺寸,最后将新的图片保存到文件中(假设为 output.jpg)。 需要注意的是,这里使用的是 `Image.SCALE_SMOOTH` 参数,表示使用平滑缩放算法,可以得到更好的压缩效果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值