Oh MyUtils

이미지 리사이저 - 크기 조정, 퍼센트 스케일, SNS 프리셋 온라인

정확한 크기, 퍼센트 비율, SNS 프리셋으로 이미지 크기를 조정하세요. 포맷 변환, 품질 조절 — 100% 클라이언트 처리, 서버 업로드 없음.

자주 묻는 질문

이미지 리사이저란 무엇이며 왜 필요한가요?

이미지 리사이저는 이미지의 픽셀 크기를 변경하는 도구입니다. 웹 페이지 최적화(로딩 시간 단축), 소셜 미디어 플랫폼 요구사항 충족(각 플랫폼마다 특정 이미지 크기 존재), 이메일 템플릿용 이미지 준비, 썸네일 생성 등에 필수적입니다. 예를 들어 인스타그램은 정사각형 피드 게시물에 1080x1080 픽셀을, 유튜브 썸네일은 1280x720 픽셀을 요구합니다.

이 이미지 리사이저 도구를 어떻게 사용하나요?

1. 리사이즈 모드를 선택하세요: 크기(정확한 픽셀 값 입력), 퍼센트(비율로 확대/축소), 프리셋(소셜 미디어 플랫폼 크기 선택). 2. 업로드 영역에 이미지를 드래그 앤 드롭하거나 클릭하여 파일을 선택하세요. 3. 리사이즈 설정을 조정하세요. 4. 선택적으로 출력 포맷(PNG, JPEG, WebP)과 품질을 변경하세요. 5. '전체 리사이즈'를 클릭하여 처리하세요. 6. 개별 다운로드 또는 '전체 다운로드(ZIP)'를 사용하세요.

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

이미지는 100% 안전하며 브라우저를 벗어나지 않습니다. 모든 리사이즈는 HTML5 Canvas API를 사용하여 클라이언트 측에서 수행됩니다. 이미지 데이터가 어떤 서버로도 전송되지 않아 완전한 프라이버시가 보장됩니다. 브라우저의 네트워크 탭을 확인하면 업로드 요청이 없는 것을 확인할 수 있습니다.

맞춤, 채우기, 늘리기 모드의 차이점은 무엇인가요?

맞춤(Fit)은 원본 종횡비를 유지하면서 대상 크기 안에 이미지를 맞춥니다. 결과물이 한 방향에서 대상보다 작을 수 있습니다. 채우기(Fill)는 종횡비를 유지하면서 대상 크기를 완전히 채우고, 초과 부분을 잘라냅니다. 늘리기(Stretch)는 이미지를 대상 크기에 정확히 맞추며, 종횡비가 다르면 이미지가 왜곡될 수 있습니다. 대부분의 경우 맞춤 모드를 권장합니다.

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

세 가지 일반적인 웹 이미지 포맷을 지원합니다: PNG(무손실, 투명도 지원), JPEG(품질 조절 가능한 손실 압축, 투명도 미지원), WebP(손실/무손실 모두 지원하는 최신 포맷, 투명도 지원). 리사이즈 중 포맷을 변환할 수도 있습니다. 예를 들어 PNG를 WebP로 저장하여 파일 크기를 줄일 수 있습니다.

소셜 미디어 플랫폼의 올바른 이미지 크기는 무엇인가요?

모든 주요 플랫폼에 대한 내장 프리셋이 포함되어 있습니다: Twitter/X 게시물(1200x675), 인스타그램 피드(1080x1080), 인스타그램 스토리(1080x1920), 페이스북 게시물(1200x630), 유튜브 썸네일(1280x720), 링크드인 게시물(1200x627) 등. '프리셋' 모드를 선택하고 대상 플랫폼을 클릭하면 원클릭으로 정확한 크기로 리사이즈됩니다.

리사이즈하면 이미지 품질에 영향을 주나요?

리사이즈는 방향과 포맷에 따라 품질에 영향을 줄 수 있습니다. 축소(다운스케일링)는 일반적으로 품질이 잘 유지됩니다. 확대(업스케일링)는 이중선형 보간법을 사용하며, 약간 흐릿한 결과를 만들 수 있습니다(Canvas API의 한계). 손실 포맷(JPEG, WebP)의 경우 품질 슬라이더로 압축 수준을 조절할 수 있습니다. PNG 출력은 항상 무손실입니다.

지원하는 최대 파일 크기와 해상도는 얼마인가요?

이미지당 최대 50MB, 해상도 최대 16384 x 16384 픽셀(대부분의 브라우저에서 Canvas API 제한)을 지원합니다. 일괄 처리의 경우 최대 20개의 이미지를 동시에 리사이즈할 수 있습니다. 모바일 기기에서는 메모리 제약으로 인해 최대 해상도가 낮을 수 있습니다(Safari iOS에서 약 1670만 픽셀).

코드 예제

// Client-side image resizing using Canvas API
async function resizeImage(file, targetWidth, targetHeight, options = {}) {
  const { quality = 0.85, format = null, fitMode = 'fit' } = options;

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

    img.onload = () => {
      URL.revokeObjectURL(url);
      const origW = img.naturalWidth;
      const origH = img.naturalHeight;
      let canvasW, canvasH, drawX = 0, drawY = 0, drawW, drawH;

      if (fitMode === 'fit') {
        const scale = Math.min(targetWidth / origW, targetHeight / origH);
        canvasW = Math.round(origW * scale);
        canvasH = Math.round(origH * scale);
        drawX = 0; drawY = 0; drawW = canvasW; drawH = canvasH;
      } else if (fitMode === 'fill') {
        const scale = Math.max(targetWidth / origW, targetHeight / origH);
        drawW = Math.round(origW * scale);
        drawH = Math.round(origH * scale);
        drawX = Math.round((targetWidth - drawW) / 2);
        drawY = Math.round((targetHeight - drawH) / 2);
        canvasW = targetWidth; canvasH = targetHeight;
      } else {
        canvasW = targetWidth; canvasH = targetHeight;
        drawW = targetWidth; drawH = targetHeight;
      }

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

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

      ctx.drawImage(img, drawX, drawY, drawW, drawH);

      canvas.toBlob(
        (blob) => {
          if (!blob) { reject(new Error('Resize failed')); return; }
          resolve({
            blob, width: canvasW, height: canvasH,
            originalSize: file.size, resizedSize: blob.size,
          });
        },
        outputType,
        outputType === 'image/png' ? undefined : quality
      );
    };

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

// Usage
const input = document.querySelector('input[type="file"]');
input.addEventListener('change', async (e) => {
  const file = e.target.files[0];
  const result = await resizeImage(file, 800, 600, { quality: 0.9, fitMode: 'fit' });
  console.log(`Resized: ${result.width}x${result.height}, ${result.resizedSize} bytes`);

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

관련 도구