图片裁剪工具

免费在线图片裁剪工具,支持自定义裁剪、预设尺寸裁剪(头像、封面、社交媒体等)。拖拽裁剪框、旋转图片、缩放调整,一键下载裁剪后的图片

上传图片

支持 JPG、PNG、WebP 等格式

✂️
点击或拖拽图片到此处上传
支持 JPG、PNG、WebP 等格式

什么是图片裁剪?

图片裁剪是指从原始图片中截取指定区域的操作。通过裁剪可以调整图片的宽高比例、去除不需要的部分、突出图片主体。常见的应用场景包括制作头像、社交媒体封面图、电商商品图片等。

图片裁剪的应用场景

  • 头像制作:裁剪为正方形(1:1)用于个人头像、社交媒体头像
  • 社交媒体封面:按照各平台的推荐尺寸裁剪(如微信封面、微博封面等)
  • 电商图片:裁剪商品图片突出主体,去除多余背景
  • 证件照片:按照标准尺寸裁剪证件照
  • 网站横幅:裁剪为合适的宽高比用于网站banner
  • 打印输出:按照打印尺寸比例裁剪图片

常见图片比例

比例 尺寸示例 应用场景
1:1 200x200, 500x500 头像、正方形图片
16:9 1920x1080, 1280x720 宽屏视频、横幅
4:3 800x600, 1024x768 传统显示器、PPT
9:16 1080x1920 手机竖屏、短视频
3:4 600x800 书籍封面、社交媒体
3:2 300x200, 600x400 相机照片、风景照

常见问题(FAQ)

Q: 为什么要裁剪图片?

A: 裁剪图片的目的包括:1)调整宽高比以适应不同的显示区域;2)去除不需要的部分,突出主题;3)减少文件大小;4)符合特定平台的要求(如头像尺寸);5)改善构图和视觉效果。

Q: 裁剪会影响图片质量吗?

A: 裁剪本身不会影响剩余部分的图片质量,但如果裁剪后需要放大显示,可能会出现像素化。建议在拍摄时使用足够高的分辨率,以便裁剪后仍有足够的像素。

Q: 什么是黄金比例裁剪?

A: 黄金比例(约1.618:1)被认为是最具美感的比例。使用黄金比例裁剪可以让图片看起来更加平衡和吸引人。常见的黄金比例包括3:2和5:3等接近的比值。

Q: 各大平台的头像尺寸是多少?

A: 常见平台的头像尺寸要求:
- 微信头像:200x200px
- 微博头像:180x180px
- Twitter头像:400x400px
- Facebook头像:180x180px
- Instagram头像:110x110px
- LinkedIn头像:400x400px

代码示例

JavaScript Canvas 裁剪示例

// 使用 Canvas 裁剪图片
function cropImage(image, x, y, width, height) {
    const canvas = document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;
    
    const ctx = canvas.getContext('2d');
    ctx.drawImage(image, x, y, width, height, 0, 0, width, height);
    
    return canvas;
}

// 中心裁剪为指定尺寸
function centerCrop(image, targetWidth, targetHeight) {
    const sourceWidth = image.width;
    const sourceHeight = image.height;
    
    // 计算缩放比例
    const scaleX = targetWidth / sourceWidth;
    const scaleY = targetHeight / sourceHeight;
    const scale = Math.max(scaleX, scaleY);
    
    // 计算裁剪区域
    const scaledWidth = sourceWidth * scale;
    const scaledHeight = sourceHeight * scale;
    const x = (scaledWidth - targetWidth) / 2 / scale;
    const y = (scaledHeight - targetHeight) / 2 / scale;
    
    return cropImage(image, x, y, targetWidth / scale, targetHeight / scale);
}

// 按比例裁剪
function aspectCrop(image, aspectRatio) {
    const sourceWidth = image.width;
    const sourceHeight = image.height;
    const sourceAspect = sourceWidth / sourceHeight;
    
    let cropWidth, cropHeight;
    
    if (sourceAspect > aspectRatio) {
        // 原图更宽,裁剪宽度
        cropHeight = sourceHeight;
        cropWidth = sourceHeight * aspectRatio;
    } else {
        // 原图更高,裁剪高度
        cropWidth = sourceWidth;
        cropHeight = sourceWidth / aspectRatio;
    }
    
    const x = (sourceWidth - cropWidth) / 2;
    const y = (sourceHeight - cropHeight) / 2;
    
    return cropImage(image, x, y, cropWidth, cropHeight);
}

// 使用示例
const img = new Image();
img.onload = () => {
    // 自由裁剪
    const cropped1 = cropImage(img, 100, 100, 200, 200);
    
    // 中心裁剪为正方形
    const cropped2 = centerCrop(img, 300, 300);
    
    // 裁剪为16:9比例
    const cropped3 = aspectCrop(img, 16/9);
    
    // 显示裁剪结果
    document.body.appendChild(cropped1);
};
img.src = 'image.jpg';

Python Pillow 裁剪示例

from PIL import Image

def crop_image(input_path, output_path, left, top, width, height):
    """
    裁剪图片
    :param input_path: 输入图片路径
    :param output_path: 输出图片路径
    :param left: 左上角 x 坐标
    :param top: 左上角 y 坐标
    :param width: 裁剪宽度
    :param height: 裁剪高度
    """
    img = Image.open(input_path)
    
    # 定义裁剪区域 (left, top, right, bottom)
    crop_box = (left, top, left + width, top + height)
    cropped_img = img.crop(crop_box)
    
    cropped_img.save(output_path)
    print(f'裁剪完成,尺寸: {cropped_img.size}')

def center_crop(input_path, output_path, size):
    """
    从中心裁剪为正方形
    :param size: 输出尺寸
    """
    img = Image.open(input_path)
    width, height = img.size
    
    left = (width - size) // 2
    top = (height - size) // 2
    
    cropped = img.crop((left, top, left + size, top + size))
    cropped.save(output_path)
    print(f'中心裁剪完成,尺寸: {cropped.size}')

def aspect_crop(input_path, output_path, aspect_ratio):
    """
    按比例裁剪
    :param aspect_ratio: 宽高比 (width/height)
    """
    img = Image.open(input_path)
    width, height = img.size
    current_aspect = width / height
    
    if current_aspect > aspect_ratio:
        # 原图更宽,裁剪宽度
        new_width = int(height * aspect_ratio)
        left = (width - new_width) // 2
        top = 0
        right = left + new_width
        bottom = height
    else:
        # 原图更高,裁剪高度
        new_height = int(width / aspect_ratio)
        left = 0
        top = (height - new_height) // 2
        right = width
        bottom = top + new_height
    
    cropped = img.crop((left, top, right, bottom))
    cropped.save(output_path)
    print(f'比例裁剪完成,尺寸: {cropped.size}')

def smart_resize_and_crop(input_path, output_path, target_width, target_height):
    """
    智能调整大小并裁剪(保持比例填充目标尺寸)
    """
    img = Image.open(input_path)
    
    # 计算缩放比例
    img_ratio = img.width / img.height
    target_ratio = target_width / target_height
    
    if img_ratio > target_ratio:
        # 原图更宽,按高度缩放
        new_height = target_height
        new_width = int(new_height * img_ratio)
    else:
        # 原图更高,按宽度缩放
        new_width = target_width
        new_height = int(new_width / img_ratio)
    
    # 缩放图片
    resized = img.resize((new_width, new_height), Image.LANCZOS)
    
    # 中心裁剪
    left = (new_width - target_width) // 2
    top = (new_height - target_height) // 2
    cropped = resized.crop((left, top, left + target_width, top + target_height))
    
    cropped.save(output_path)
    print(f'智能裁剪完成,最终尺寸: {cropped.size}')

# 使用示例
crop_image('input.jpg', 'output.jpg', 100, 100, 300, 300)
center_crop('input.jpg', 'avatar.jpg', 200)
aspect_crop('input.jpg', 'wide.jpg', 16/9)
smart_resize_and_crop('input.jpg', 'banner.jpg', 1920, 1080)

Node.js Sharp 裁剪示例

const sharp = require('sharp');

async function cropImage(inputPath, outputPath, left, top, width, height) {
    await sharp(inputPath)
        .extract({ left, top, width, height })
        .toFile(outputPath);
    console.log('裁剪完成');
}

async function centerCrop(inputPath, outputPath, size) {
    const metadata = await sharp(inputPath).metadata();
    const { width, height } = metadata;
    
    const left = Math.floor((width - size) / 2);
    const top = Math.floor((height - size) / 2);
    
    await sharp(inputPath)
        .extract({ left, top, width: size, height: size })
        .toFile(outputPath);
    console.log('中心裁剪完成');
}

async function smartCrop(inputPath, outputPath, width, height) {
    // 使用 sharp 的 cover 方法实现智能裁剪
    await sharp(inputPath)
        .resize(width, height, {
            fit: 'cover',
            position: 'center'
        })
        .toFile(outputPath);
    console.log('智能裁剪完成');
}

async function resizeWithCrop(inputPath, outputPath, maxWidth, maxHeight) {
    const metadata = await sharp(inputPath).metadata();
    const { width: originalWidth, height: originalHeight } = metadata;
    
    const ratio = Math.min(maxWidth / originalWidth, maxHeight / originalHeight);
    const newWidth = Math.floor(originalWidth * ratio);
    const newHeight = Math.floor(originalHeight * ratio);
    
    await sharp(inputPath)
        .resize(newWidth, newHeight)
        .toFile(outputPath);
    console.log('缩放完成');
}

// 使用示例
cropImage('input.jpg', 'output.jpg', 100, 100, 300, 300);
centerCrop('input.jpg', 'avatar.jpg', 200);
smartCrop('input.jpg', 'banner.jpg', 1920, 1080);
resizeWithCrop('input.jpg', 'thumbnail.jpg', 300, 300);

Java BufferedImage 裁剪

import java.awt.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.File;

public class ImageCropper {
    
    public static void cropImage(String inputPath, String outputPath, 
                                  int x, int y, int width, int height) throws Exception {
        BufferedImage originalImage = ImageIO.read(new File(inputPath));
        
        // 创建裁剪后的图片
        BufferedImage croppedImage = originalImage.getSubimage(x, y, width, height);
        
        // 保存裁剪后的图片
        ImageIO.write(croppedImage, "jpg", new File(outputPath));
        
        System.out.println("裁剪完成,尺寸: " + croppedImage.getWidth() + 
                           "x" + croppedImage.getHeight());
    }
    
    public static void centerCrop(String inputPath, String outputPath, int size) throws Exception {
        BufferedImage originalImage = ImageIO.read(new File(inputPath));
        int width = originalImage.getWidth();
        int height = originalImage.getHeight();
        
        int x = (width - size) / 2;
        int y = (height - size) / 2;
        
        cropImage(inputPath, outputPath, x, y, size, size);
    }
    
    public static void smartResizeAndCrop(String inputPath, String outputPath, 
                                           int targetWidth, int targetHeight) throws Exception {
        BufferedImage originalImage = ImageIO.read(new File(inputPath));
        int originalWidth = originalImage.getWidth();
        int originalHeight = originalImage.getHeight();
        
        // 计算缩放比例
        double ratio = Math.min(
            (double) targetWidth / originalWidth,
            (double) targetHeight / originalHeight
        );
        
        int newWidth = (int) (originalWidth * ratio);
        int newHeight = (int) (originalHeight * ratio);
        
        // 缩放图片
        BufferedImage resizedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = resizedImage.createGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g2d.drawImage(originalImage, 0, 0, newWidth, newHeight, null);
        g2d.dispose();
        
        // 中心裁剪
        int x = (newWidth - targetWidth) / 2;
        int y = (newHeight - targetHeight) / 2;
        BufferedImage croppedImage = resizedImage.getSubimage(x, y, targetWidth, targetHeight);
        
        ImageIO.write(croppedImage, "jpg", new File(outputPath));
        System.out.println("智能裁剪完成");
    }
    
    public static void main(String[] args) throws Exception {
        cropImage("input.jpg", "output.jpg", 100, 100, 300, 300);
        centerCrop("input.jpg", "avatar.jpg", 200);
        smartResizeAndCrop("input.jpg", "banner.jpg", 1920, 1080);
    }
}