Java图片裁剪案例如何实操

wen java案例 32

本文目录导读:

Java图片裁剪案例如何实操

  1. 使用Java原生API(BufferedImage)
  2. 添加边界检查的增强版
  3. 使用Thumbnails库(推荐)
  4. 实用工具类
  5. 完整示例:图形界面裁剪工具
  6. 注意事项

我来为你介绍Java图片裁剪的几种实操方法,从基础到进阶。

使用Java原生API(BufferedImage)

这是最基础、无需第三方依赖的方法:

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class ImageCropDemo {
    public static void cropImage(String sourcePath, String targetPath, 
                                  int x, int y, int width, int height) throws IOException {
        // 1. 读取原图
        File sourceFile = new File(sourcePath);
        BufferedImage originalImage = ImageIO.read(sourceFile);
        // 2. 裁剪图片
        BufferedImage croppedImage = originalImage.getSubimage(x, y, width, height);
        // 3. 保存裁剪后的图片
        File targetFile = new File(targetPath);
        ImageIO.write(croppedImage, "jpg", targetFile);
        System.out.println("图片裁剪完成!");
    }
    public static void main(String[] args) {
        try {
            // 裁剪坐标为(100, 100),宽高为300x300的区域
            cropImage("input.jpg", "output.jpg", 100, 100, 300, 300);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

添加边界检查的增强版

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class SafeImageCropper {
    /**
     * 安全裁剪图片,带边界检查
     */
    public static BufferedImage safeCrop(BufferedImage source, 
                                          int x, int y, int width, int height) {
        // 获取原图尺寸
        int imageWidth = source.getWidth();
        int imageHeight = source.getHeight();
        // 边界检查:确保裁剪区域不超出原图范围
        x = Math.max(0, Math.min(x, imageWidth - 1));
        y = Math.max(0, Math.min(y, imageHeight - 1));
        width = Math.min(width, imageWidth - x);
        height = Math.min(height, imageHeight - y);
        return source.getSubimage(x, y, width, height);
    }
    public static void main(String[] args) {
        try {
            BufferedImage original = ImageIO.read(new File("input.jpg"));
            BufferedImage cropped = safeCrop(original, 100, 100, 300, 300);
            ImageIO.write(cropped, "jpg", new File("safe_output.jpg"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

使用Thumbnails库(推荐)

需要添加Maven依赖:

<dependency>
    <groupId>net.coobird</groupId>
    <artifactId>thumbnailator</artifactId>
    <version>0.4.20</version>
</dependency>
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import java.io.File;
import java.io.IOException;
public class ThumbnailsCropDemo {
    // 方式1:指定坐标裁剪
    public static void cropByPosition() throws IOException {
        Thumbnails.of("input.jpg")
                .sourceRegion(100, 100, 300, 300)  // x, y, width, height
                .size(300, 300)
                .toFile("crop_by_position.jpg");
    }
    // 方式2:使用预定义位置裁剪
    public static void cropByCenter() throws IOException {
        Thumbnails.of("input.jpg")
                .sourceRegion(Positions.CENTER, 300, 300)  // 从中心裁切
                .size(300, 300)
                .toFile("crop_center.jpg");
    }
    // 方式3:保持比例裁剪
    public static void cropWithRatio() throws IOException {
        Thumbnails.of("input.jpg")
                .sourceRegion(100, 100, 300, 300)
                .size(150, 150)  // 可以缩小尺寸
                .keepAspectRatio(true)
                .toFile("crop_with_ratio.jpg");
    }
    // 方式4:批量裁剪
    public static void batchCrop() throws IOException {
        File[] files = {new File("img1.jpg"), new File("img2.jpg")};
        for (File file : files) {
            String outputName = "cropped_" + file.getName();
            Thumbnails.of(file)
                    .sourceRegion(Positions.CENTER, 200, 200)
                    .size(200, 200)
                    .toFile(outputName);
        }
    }
}

实用工具类

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class ImageCropUtil {
    /**
     * 居中裁剪为正方形
     */
    public static BufferedImage cropToSquare(BufferedImage source) {
        int width = source.getWidth();
        int height = source.getHeight();
        int size = Math.min(width, height);
        int x = (width - size) / 2;
        int y = (height - size) / 2;
        return source.getSubimage(x, y, size, size);
    }
    /**
     * 按比例裁剪
     */
    public static BufferedImage cropByRatio(BufferedImage source, double ratio) {
        int width = source.getWidth();
        int height = source.getHeight();
        double sourceRatio = (double) width / height;
        if (sourceRatio > ratio) {
            // 原图太宽,裁剪宽度
            int newWidth = (int)(height * ratio);
            int x = (width - newWidth) / 2;
            return source.getSubimage(x, 0, newWidth, height);
        } else {
            // 原图太高,裁剪高度
            int newHeight = (int)(width / ratio);
            int y = (height - newHeight) / 2;
            return source.getSubimage(0, y, width, newHeight);
        }
    }
    /**
     * 四分裁剪(将图片分为4份)
     */
    public static BufferedImage[] cropToFour(BufferedImage source) {
        int width = source.getWidth() / 2;
        int height = source.getHeight() / 2;
        BufferedImage[] parts = new BufferedImage[4];
        parts[0] = source.getSubimage(0, 0, width, height);
        parts[1] = source.getSubimage(width, 0, width, height);
        parts[2] = source.getSubimage(0, height, width, height);
        parts[3] = source.getSubimage(width, height, width, height);
        return parts;
    }
}

完整示例:图形界面裁剪工具

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
public class ImageCropGUI extends JFrame {
    private JLabel imageLabel;
    private BufferedImage originalImage;
    private Rectangle cropRect;
    public ImageCropGUI() {
        setTitle("图片裁剪工具");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());
        // 图片显示区域
        imageLabel = new JLabel();
        imageLabel.setPreferredSize(new Dimension(600, 400));
        add(new JScrollPane(imageLabel), BorderLayout.CENTER);
        // 控制面板
        JPanel controlPanel = new JPanel();
        JButton loadBtn = new JButton("加载图片");
        JButton cropBtn = new JButton("裁剪保存");
        loadBtn.addActionListener(e -> loadImage());
        cropBtn.addActionListener(e -> cropAndSave());
        controlPanel.add(loadBtn);
        controlPanel.add(cropBtn);
        add(controlPanel, BorderLayout.SOUTH);
        // 鼠标拖拽选择裁剪区域
        imageLabel.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                cropRect = new Rectangle(e.getPoint());
            }
            @Override
            public void mouseReleased(MouseEvent e) {
                cropRect.setSize(
                    e.getX() - cropRect.x,
                    e.getY() - cropRect.y
                );
                repaint();
            }
        });
        pack();
        setLocationRelativeTo(null);
    }
    private void loadImage() {
        JFileChooser chooser = new JFileChooser();
        if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
            try {
                originalImage = ImageIO.read(chooser.getSelectedFile());
                imageLabel.setIcon(new ImageIcon(originalImage));
            } catch (Exception ex) {
                JOptionPane.showMessageDialog(this, "加载图片失败!");
            }
        }
    }
    private void cropAndSave() {
        if (originalImage == null || cropRect == null) return;
        try {
            BufferedImage cropped = originalImage.getSubimage(
                cropRect.x, cropRect.y, 
                cropRect.width, cropRect.height
            );
            JFileChooser chooser = new JFileChooser();
            if (chooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
                ImageIO.write(cropped, "jpg", chooser.getSelectedFile());
                JOptionPane.showMessageDialog(this, "保存成功!");
            }
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(this, "裁剪失败!");
        }
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new ImageCropGUI().setVisible(true));
    }
}

注意事项

  1. 图片格式支持:jpg、png、gif、bmp等常见格式都支持
  2. 内存管理:大图片处理时注意使用-Xmx参数增加JVM内存
  3. 坐标验证:确保裁剪坐标不超出图片范围,否则会抛出异常
  4. 性能优化:批量处理时建议使用线程池

推荐优先使用Thumbnails库,因为它代码简洁、功能强大,还支持缩放、旋转等操作,如果只是简单裁剪,Java原生API就足够了。

抱歉,评论功能暂时关闭!