【原创】图片压缩器,目前支持jpg/jpeg/png

									**图片压缩器**

在这里插入图片描述
命令:jave - jar jar包(文尾有源码,自己打包即可) 就是以上的窗口,比较明了了

inputPath: 源文件夹(以我目前的逻辑,需要保证文件夹里面全是jpg/jpeg/png的图片)
outputPath: 输出目标文件夹
thread: 线程数,自行斟酌,最大10个线程
quality: 压缩质量,0.1~1.0,压缩程度线性提升,输出图像质量线性下降

在这里插入图片描述
代码如下:

public class ImgTranslate {

private static String inputPath = "";
private static String outputPath = "";
private static String changeMessage = "";
private static int threadNum = 1;
private static float qualityNum = 0.1f;
public static void main(String[] args) {

    // 创建 JFrame 实例
    JFrame frame = new JFrame("IMG_TRANSLATE");
    // 设置窗口大小
    frame.setSize(450, 240);
    // 设置窗口关闭时的操作
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationRelativeTo(null);
    // 创建面板,用于放置文件夹选择框和按钮
    JPanel panel = new JPanel();
    // 将面板放置在窗口中
    frame.add(panel);
    // 调用用户定义的方法添加文件夹选择框和按钮
    placeComponents(panel);
    // 使窗口可见
    frame.setVisible(true);
}
private static void placeComponents(JPanel panel) {

    panel.setLayout(null);

    // 创建标签、文本框和按钮,用于显示文件夹路径和选择文件
    JLabel folder1Label = new JLabel("inputPath:");
    folder1Label.setBounds(10, 20, 80, 25);
    panel.add(folder1Label);
    JTextField folder1Field = new JTextField(30);
    folder1Field.setBounds(100, 20, 200, 25);
    panel.add(folder1Field);
    JButton selectFile1Button = new JButton("choose");
    selectFile1Button.setPreferredSize(new Dimension(100, 30));
    selectFile1Button.setBounds(320, 20, 80, 25);
    panel.add(selectFile1Button);

    JLabel folder2Label = new JLabel("outputPath:");
    folder2Label.setBounds(10, 50, 80, 25);
    panel.add(folder2Label);
    JTextField folder2Field = new JTextField(30);
    folder2Field.setBounds(100, 50, 200, 25);
    panel.add(folder2Field);
    JButton selectFile2Button = new JButton("choose");
    selectFile2Button.setPreferredSize(new Dimension(100, 30));
    selectFile2Button.setBounds(320, 50, 80, 25);
    panel.add(selectFile2Button);

    JComboBox<String> thread = new JComboBox<>();
    JComboBox<String> quality = new JComboBox<>();
    for (int i = 1; i <= 10; i++) {
        thread.addItem(i+"");
        quality.addItem(new BigDecimal(i).divide(new BigDecimal(10)).toString());
    }
    JLabel folder3Label = new JLabel("thread:");
    folder3Label.setBounds(10, 80, 80, 25);
    panel.add(folder3Label);
    thread.setBounds(100,80,200,25);
    JLabel folder4Label = new JLabel("quality:");
    folder4Label.setBounds(10, 110, 80, 25);
    panel.add(folder4Label);
    quality.setBounds(100,110,200,25);
    panel.add(thread);
    panel.add(quality);

    thread.addItemListener(new ItemListener() {
        public void itemStateChanged(ItemEvent e) {
            if (e.getStateChange() == ItemEvent.SELECTED) {
                // 当选项被选中时,获取选中的值并进行相应的操作
                String selectedOption = (String) thread.getSelectedItem();
               threadNum = Integer.parseInt(selectedOption);
            }
        }
    });
    quality.addItemListener(new ItemListener() {
        public void itemStateChanged(ItemEvent e) {
            if (e.getStateChange() == ItemEvent.SELECTED) {
                // 当选项被选中时,获取选中的值并进行相应的操作
                String selectedOption = (String) quality.getSelectedItem();
                qualityNum = Float.parseFloat(selectedOption);
            }
        }
    });

    JLabel label = new JLabel(changeMessage);
    label.setBounds(150, 170, 100, 25);

// label.setForeground(Color.RED); // 设置文本颜色为红色
panel.add(label);
// 为每个按钮添加选择文件的监听器
selectFile1Button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
selectFile(folder1Field,0);
}
});

    selectFile2Button.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            selectFile(folder2Field,1);
        }
    });
    JButton okButton = new JButton("confirm");
    okButton.setBounds(150, 140, 80, 25);
    panel.add(okButton);
    okButton.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            if("".equals(inputPath)||"".equals(outputPath)){
                JOptionPane.showMessageDialog(null, "The inputPath or the outputPath cannot be null");
            }else {
                JOptionPane.showMessageDialog(null, "start translate...");
                try {
                    Thread.sleep(3000);
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
                new Thread(() -> {
                    try {
                        translating();
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }
                }).start();
                Timer timer = new Timer(500, new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        try {
                            changeMessage = "translated  "+(new BigDecimal(new File(outputPath).listFiles().length).divide(new BigDecimal(new File(inputPath).listFiles().length)))
                                    .multiply(new BigDecimal(100))+"%";
                        }catch (Exception e1){
                            changeMessage = "translated  "+"0%";
                        }
                        label.setText(changeMessage);
                        if(changeMessage.contains("100%")){
                            label.setForeground(Color.pink);
                        }
                    }
                });
                timer.start();
            }

        }

        private void translating() throws Exception {
            translate(inputPath,outputPath,qualityNum);
        }
    });



}

private static void translate(String inputPath, String outputPath, float quality)throws Exception {
    //分割源目录线程
    //分线程执行后续方法
    File inputFiles = new File(inputPath);
    while (inputFiles.listFiles().length/threadNum==0){
        threadNum--;
    }
    File[] files = inputFiles.listFiles();
    java.util.List<File> fileList = Arrays.asList(files);

    java.util.List<java.util.List<File>> partition = Lists.partition(fileList, fileList.size() / threadNum);
    ExecutorService executor = Executors.newFixedThreadPool(threadNum);
    for (java.util.List<File> smallList : partition) {
        executor.submit(() -> {
            // 在这里执行你的操作
            for (File file : smallList) {
                try {
                    BufferedImage inputImage = ImageIO.read(file);
                    String type = file.getName().split("\\.")[1];
                    switch (type){
                        case "jpg":
                            jpgTranslate(outputPath, quality, file, inputImage);
                            break;
                        case "jpeg":
                            jpgTranslate(outputPath, quality, file, inputImage);
                            break;
                        case "png":
                            pngTranslate(outputPath, quality,file, inputImage);
                            break;
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }
    // 关闭线程池并等待任务完成
    executor.shutdown();






}

private static void pngTranslate(String outputPath, float quality,File file, BufferedImage inputImage) {
    int width = inputImage.getWidth();
    int height = inputImage.getHeight();
    BufferedImage compressedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            int rgb = inputImage.getRGB(x, y);
            int r = (rgb >> 16) & 0xff;
            int g = (rgb >> 8) & 0xff;
            int b = rgb & 0xff;
            int gray = (int) (0.2989 * r + 0.5870 * g + 0.1140 * b);
            int grayCompressed = (int) (gray * quality);
            int rgbCompressed = (grayCompressed << 16) | (grayCompressed << 8) | grayCompressed;
            compressedImage.setRGB(x, y, rgbCompressed);
        }
    }
    try {
        ImageIO.write(compressedImage, "png", new File(outputPath+"\\"+file.getName()));
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private static void jpgTranslate(String outputPath, float quality, File file, BufferedImage inputImage) throws IOException {
    Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpg");
    ImageWriter writer = (ImageWriter) writers.next();
    OutputStream outputStream = new FileOutputStream(outputPath+"\\"+file.getName());
    ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(outputStream);
    writer.setOutput(imageOutputStream);

    ImageWriteParam param = writer.getDefaultWriteParam();
    param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
    param.setCompressionQuality(quality);

    writer.write(null, new IIOImage(inputImage, null, null), param);

    imageOutputStream.close();
    outputStream.close();
}


private static void selectFile(JTextField textField,int flag) {
    JFileChooser fileChooser = new JFileChooser();
    fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); // 限制只能选择文件夹
    int returnValue = fileChooser.showOpenDialog(null); // 显示打开文件对话框
    if (returnValue == JFileChooser.APPROVE_OPTION) { // 如果用户选择了文件夹并点击了“打开”按钮
        File selectedDirectory = fileChooser.getSelectedFile(); // 获取用户选择的文件夹
        textField.setText(selectedDirectory.getAbsolutePath()); // 将文件夹路径设置到文本框中
        if(flag==0){
            inputPath = selectedDirectory.getAbsolutePath();
        }else {
            outputPath = selectedDirectory.getAbsolutePath();
        }
    } else { // 如果用户没有选择文件夹或点击了取消按钮,清空文本框内容
        textField.setText("");
    }
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JCodec是一个Java视频编解码库,其中包含了JPEG压缩和解压缩的代码。这些代码位于jcodec/src/main/java/org/jcodec/api/moments/JpegEncoder.java中。 下面是一个简单的示例,展示如何使用JCodec进行JPEG压缩: ```java import java.awt.image.BufferedImage; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import javax.imageio.ImageIO; import org.jcodec.api.moments.JpegEncoder; import org.jcodec.common.model.ColorSpace; import org.jcodec.common.model.Picture; public class JpegCompressionExample { public static void main(String[] args) throws IOException { // 读取图像文件 BufferedImage image = ImageIO.read(new File("input.png")); // 将BufferedImage转换为JCodec中的Picture对象 Picture pic = Picture.create(image.getWidth(), image.getHeight(), ColorSpace.RGB); pic.setRGB(0, 0, image.getWidth(), image.getHeight(), image.getRGB(0, 0, image.getWidth(), image.getHeight()), 0, image.getWidth()); // 创建JPEG编码并进行压缩 JpegEncoder encoder = new JpegEncoder(); byte[] data = encoder.encodeFrame(pic, 80); // 将压缩后的数据写入文件 FileOutputStream out = new FileOutputStream(new File("output.jpg")); out.write(data); out.close(); } } ``` 在此示例中,我们首先使用ImageIO从文件中读取输入图像。然后,我们将它转换为JCodec中的Picture对象,并创建了一个JpegEncoder对象。最后,我们使用JpegEncoder对图像进行压缩,并将压缩后的数据写入文件。 需要注意的是,这里的quality参数指定了JPEG压缩的质量,范围从0到100。值越高,图像质量越好,但文件大小也越大。在实际应用中,需要根据具体情况选择一个合适的quality值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值