java指定图片的dpi和存储大小kb

  • 公司需求,将文件夹下面的所有图片dpi设置为300,存储大小为90到150kb,折磨了我4天,今天终于解决了,写成本地直接能跑的代码记录一下。

  • 注意要将png(32位深度)格式的图片转换成jpg(24位深度)格式,只改变图片的后缀是不行的。

  • 查看图片修改后的dpi,在 FSViewer 里面查看,鼠标右键属性那里看到的值不准。

  • 需要引入 Thumbnailator 到 maven 项目里面的 pom.xml,或者直接去 官网下载.jar包导入项目。

google图片处理插件

<dependency>
	<groupId>net.coobird</groupId>
		<artifactId>thumbnailator</artifactId>
	<version>0.4.11</version>
</dependency>

java代码(只需要修改下文件路径往里面存图片就行了)

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import net.coobird.thumbnailator.Thumbnails;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.FileImageInputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;

//需求,将文件夹下面的所有图片dpi设置为300,存储大小为90到150kb
public class ImgDemo {
    public static void main(String[] args) throws IOException {
        //文件夹路径
        String path = "C:\\Users\\Administrator\\Desktop\\zy\\";

        File[] allFiles = new File(path).listFiles();
        for (int i = 0; i < allFiles.length; i++) {
            File allFile = allFiles[i];
            //文件夹下的文件路径
            String filepath = allFile.getPath();
            //将所有图片转成jpg格式
            pngToJpg(filepath);
            //设置图片的dpi
            makeDpi(filepath, 300);
            //将文件转成字节数组
            byte[] bytesByFile = getBytesByFile(filepath);
            //设置文件的存储大小,dpi不变
            byte[] bytes = scaleRange(bytesByFile, 90 * 1024, 150 * 1024);
            //文件输出流写入文件
            try {
                FileOutputStream outstream = new FileOutputStream(filepath);
                assert bytesByFile != null;
                outstream.write(bytes);  // 写入文件
                outstream.close(); // 关闭资源
            } catch (FileNotFoundException e) {
                // TODO 自动生成的 catch 块
                e.printStackTrace();
            } catch (IOException e) {
                // TODO 自动生成的 catch 块
                e.printStackTrace();
            }
        }
    }

    //png转jpg格式
    public static void pngToJpg(String filepath) {
        BufferedImage bufferedImage;
        try {
            bufferedImage = ImageIO.read(new File(filepath));
            BufferedImage newBufferedImage = new BufferedImage(
                    bufferedImage.getWidth(), bufferedImage.getHeight(),
                    BufferedImage.TYPE_INT_RGB);
            // TYPE_INT_RGB:创建一个RBG图像,24位深度,成功将32位图转化成24位
            newBufferedImage.createGraphics().drawImage(bufferedImage, 0, 0,
                    Color.WHITE, null);
            ImageIO.write(newBufferedImage, "jpg", new File(filepath));

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //设置dpi
    public static void makeDpi(String filepath, int dpi) throws IOException {
        ImageReader reader = ImageIO.getImageReadersByFormatName("jpeg").next();
        reader.setInput(new FileImageInputStream(new File(filepath)), true, false);
        BufferedImage image = ImageIO.read(new File(filepath));
        int w = 2550, h = -1;
        FileOutputStream fos = new FileOutputStream(filepath);
        JPEGImageEncoder jpegEncoder = JPEGCodec.createJPEGEncoder(fos);
        JPEGEncodeParam jpegEncodeParam = jpegEncoder.getDefaultJPEGEncodeParam(image);
        jpegEncodeParam.setDensityUnit(JPEGEncodeParam.DENSITY_UNIT_DOTS_INCH);
        jpegEncodeParam.setXDensity(dpi);
        jpegEncodeParam.setYDensity(dpi);
        jpegEncoder.encode(image, jpegEncodeParam);
        fos.close();
    }

    //将文件转换成Byte数组
    public static byte[] getBytesByFile(String pathStr) {
        File file = new File(pathStr);
        try {
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
            byte[] b = new byte[1000];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            byte[] data = bos.toByteArray();
            bos.close();
            return data;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

	//此部分为git上其他大佬写的插件,我把里面的核心代码拔出来直接用了
    //设置文件的存储大小,单位kb
    public static byte[] scaleRange(byte[] sourceBytes, long minSize, long maxSize) {
        if (sourceBytes != null && sourceBytes.length > 0 && ((long) sourceBytes.length > maxSize || (long) sourceBytes.length < minSize) && minSize <= maxSize) {
            byte[] desImageBytes = new byte[0];
            double startAccuracy = 0.0D;
            double endAccuracy = 0.0D;
            double currentAccuracy = 1.0D;
            try {
                Object var16;
                ByteArrayInputStream inputStream;
                ByteArrayOutputStream outputStream;
                byte[] currentImageBytes;
                if ((long) sourceBytes.length > maxSize) {
                    startAccuracy = 0.0D;
                    endAccuracy = 1.0D;
                } else {
                    for (; desImageBytes.length == 0; var16 = null) {
                        currentAccuracy *= 2.0D;
                        inputStream = new ByteArrayInputStream(sourceBytes);
                        outputStream = new ByteArrayOutputStream(sourceBytes.length);
                        Thumbnails.of(new InputStream[]{inputStream}).scale(currentAccuracy).toOutputStream(outputStream);
                        currentImageBytes = outputStream.toByteArray();
                        if ((long) currentImageBytes.length <= maxSize && (long) currentImageBytes.length >= minSize) {
                            desImageBytes = currentImageBytes;
                        } else if ((long) currentImageBytes.length > maxSize) {
                            startAccuracy = currentAccuracy / 2.0D;
                            endAccuracy = currentAccuracy;
                            break;
                        }
                    }
                }
                for (; desImageBytes.length == 0; var16 = null) {
                    currentAccuracy = (startAccuracy + endAccuracy) / 2.0D;
                    inputStream = new ByteArrayInputStream(sourceBytes);
                    outputStream = new ByteArrayOutputStream(sourceBytes.length);
                    Thumbnails.of(new InputStream[]{inputStream}).scale(currentAccuracy).toOutputStream(outputStream);
                    currentImageBytes = outputStream.toByteArray();
                    if ((long) currentImageBytes.length > maxSize) {
                        endAccuracy = currentAccuracy;
                    } else if ((long) currentImageBytes.length < minSize) {
                        startAccuracy = currentAccuracy;
                    } else {
                        desImageBytes = currentImageBytes;
                    }
                }
            } catch (Exception var15) {
                desImageBytes = sourceBytes;
            }
            return desImageBytes;
        } else {
            return sourceBytes;
        }
    }

}

参考文章

参考的修改图片到指定的dpi的方法.
参考的png转jpg的方法.
参考的图片按指定存储大小保存的插件\git.

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值