Oh MyUtils

이미지 크롭 - 이미지 자르기/회전 온라인

드래그 선택, 비율 프리셋, 회전으로 이미지를 자르고 포맷을 변환합니다. 100% 클라이언트 처리 — 서버 업로드 없음.

자주 묻는 질문

이미지 크롭이란 무엇이며 왜 필요한가요?

이미지 크롭은 이미지에서 특정 직사각형 영역을 선택하여 추출하는 도구로, 불필요한 테두리, 배경 또는 방해 요소를 제거합니다. 소셜 미디어용 이미지 준비(각 플랫폼마다 특정 비율 요구), 포커스된 썸네일 생성, 사진 구도 개선, 스크린샷에서 관련 콘텐츠만 보여주기 등에 필수적입니다.

이 이미지 크롭 도구를 어떻게 사용하나요?

1. 업로드 영역에 이미지를 끌어놓거나 클릭하여 파일을 선택합니다. 2. 이미지가 로드되면 드래그하여 위치를 조정하고 핸들로 크롭 영역을 조절합니다. 3. 선택적으로 프리셋 비율(1:1, 16:9 등)을 선택하여 비율을 고정합니다. 4. 필요시 회전이나 뒤집기 컨트롤을 사용합니다. 5. 원하는 출력 포맷과 품질을 선택합니다. 6. '크롭 적용'을 클릭한 후 '다운로드'로 저장합니다.

이미지 데이터는 안전한가요? 서버에 업로드되나요?

이미지는 100% 안전하며 브라우저를 벗어나지 않습니다. 모든 크롭은 HTML5 Canvas API를 사용하여 클라이언트 측에서 수행됩니다. 이미지 데이터가 서버로 전송되지 않아 완전히 비공개입니다.

어떤 비율을 사용할 수 있나요?

표준 비율(1:1, 4:3, 3:2, 16:9, 16:10)과 소셜 미디어 비율(Instagram Portrait 4:5, Instagram Story 9:16, Facebook Post 1.91:1, Facebook Cover 2.63:1, Twitter/X Header 3:1)을 제공합니다. 사용자 지정 비율 입력과 자유 크롭도 가능합니다.

어떤 이미지 포맷을 지원하나요?

입력으로 PNG, JPEG, WebP, GIF를 지원합니다. 출력은 PNG(무손실, 투명도 지원), JPEG(손실 압축, 품질 제어), WebP(손실 압축, 투명도 지원)로 내보낼 수 있습니다. GIF는 첫 프레임만 추출됩니다.

크롭과 리사이즈의 차이점은 무엇인가요?

크롭은 유지할 영역을 선택하여 이미지의 일부를 제거합니다. 크롭 영역의 픽셀은 원본 해상도를 유지합니다. 리사이즈는 모든 픽셀을 스케일링하여 전체 크기를 변경합니다. 두 가지를 모두 해야 한다면 먼저 크롭한 후 Image Resizer를 사용하세요.

크롭 전에 이미지를 회전하거나 뒤집을 수 있나요?

네. 90도 시계/반시계 회전 버튼, -45~+45도 미세 회전 슬라이더, 좌우/상하 뒤집기 컨트롤을 제공합니다. 모든 변환은 크롭 전에 적용됩니다.

지원되는 최대 파일 크기와 해상도는?

파일당 최대 50MB, 해상도 최대 16384 x 16384 픽셀을 지원합니다. 모바일 기기에서는 메모리 제약으로 최대 해상도가 낮을 수 있습니다.

코드 예제

// Client-side image cropping using Canvas API
async function cropImage(file, cropX, cropY, cropWidth, cropHeight, options = {}) {
  const { quality = 0.92, format = null } = options;

  return new Promise((resolve, reject) => {
    const img = new Image();
    const url = URL.createObjectURL(file);

    img.onload = () => {
      URL.revokeObjectURL(url);

      const canvas = document.createElement('canvas');
      canvas.width = cropWidth;
      canvas.height = cropHeight;
      const ctx = canvas.getContext('2d');

      const outputType = format || file.type || 'image/png';
      if (outputType === 'image/jpeg') {
        ctx.fillStyle = '#ffffff';
        ctx.fillRect(0, 0, cropWidth, cropHeight);
      }

      ctx.drawImage(
        img,
        cropX, cropY, cropWidth, cropHeight,
        0, 0, cropWidth, cropHeight
      );

      canvas.toBlob(
        (blob) => {
          if (!blob) { reject(new Error('Crop failed')); return; }
          resolve({
            blob,
            width: cropWidth,
            height: cropHeight,
            originalWidth: img.naturalWidth,
            originalHeight: img.naturalHeight,
          });
        },
        outputType,
        outputType === 'image/png' ? undefined : quality
      );
    };

    img.onerror = () => { URL.revokeObjectURL(url); reject(new Error('Failed to load')); };
    img.src = url;
  });
}

// Crop to center square
const input = document.querySelector('input[type="file"]');
input.addEventListener('change', async (e) => {
  const file = e.target.files[0];
  const img = new Image();
  img.src = URL.createObjectURL(file);
  await new Promise((r) => (img.onload = r));

  const size = Math.min(img.naturalWidth, img.naturalHeight);
  const x = Math.round((img.naturalWidth - size) / 2);
  const y = Math.round((img.naturalHeight - size) / 2);

  const result = await cropImage(file, x, y, size, size, { format: 'image/png' });
  console.log(`Cropped: ${result.width}x${result.height}`);

  const url = URL.createObjectURL(result.blob);
  const a = document.createElement('a');
  a.href = url; a.download = 'cropped.png'; a.click();
  URL.revokeObjectURL(url);
});

관련 도구