Vue 3에서 사용하는 이미지 크롭 도구

Vue 3에서 사용하는 이미지 크롭 도구

Vue 3 프로젝트에서 이미지 크롭 기능을 구현하려면 vue-cropper 라이브러리가 매우 유용합니다. 이 라이브러리는 직관적인 인터페이스와 다양한 기능을 제공합니다.

설치 방법

npm install vue-cropper@next

기본 사용법

컴포넌트 임포트

import 'vue-cropper/dist/index.css'
import { VueCropper } from 'vue-cropper'

템플릿 구조

<template>
  <div class="cropper-container">
    <vue-cropper
      ref="cropperRef"
      :img="cropOption.sourceImage"
      :outputSize="cropOption.quality"
      :outputType="cropOption.format"
      autoCrop
      :centerBox="true"
      :canMove="true"
      @realTime="handlePreview"
    />
    
    <div class="preview-section">
      <img :src="previewData.url" :style="previewData.img" />
    </div>
    
    <div class="controls">
      <input type="file" @change="handleFileSelect" accept="image/*" />
      <button @click="zoomIn">확대</button>
      <button @click="zoomOut">축소</button>
      <button @click="rotateLeft">좌회전</button>
      <button @click="rotateRight">우회전</button>
      <button @click="handleUpload" :disabled="isUploading">
        {{ isUploading ? '업로드 중...' : '업로드' }}
      </button>
    </div>
  </div>
</template>

스크립트 구현

<script setup>
import { ref, reactive } from 'vue'
import 'vue-cropper/dist/index.css'
import { VueCropper } from 'vue-cropper'
import axios from 'axios'

// 크롭 옵션 설정
const cropOption = reactive({
  sourceImage: '',
  quality: 1,
  format: 'png'
})

// 컴포넌트 참조
const cropperRef = ref(null)
const isUploading = ref(false)
const previewData = ref({ url: '', img: {} })

// 실시간 미리보기 처리
const handlePreview = (data) => {
  previewData.value = {
    url: data.url,
    img: data.img,
    div: data.div
  }
}

// 파일 선택 처리
const handleFileSelect = (event) => {
  const file = event.target.files[0]
  if (!file) return

  const validTypes = ['image/jpeg', 'image/png', 'image/gif']
  if (!validTypes.includes(file.type)) {
    alert('지원하는 이미지 형식: jpeg, png, gif')
    return
  }

  const reader = new FileReader()
  reader.onload = (e) => {
    cropOption.sourceImage = e.target.result
  }
  reader.readAsDataURL(file)
}

// 확대/축소 기능
const zoomIn = () => cropperRef.value?.changeScale(1)
const zoomTo = (ratio) => cropperRef.value?.changeScale(ratio)

// 회전 기능
const rotateLeft = () => cropperRef.value?.rotateLeft()
const rotateRight = () => cropperRef.value?.rotateRight()

// 이미지 업로드
const handleUpload = () => {
  if (!cropperRef.value) return
  
  isUploading.value = true
  cropperRef.value.getCropBlob(async (blob) => {
    const formData = new FormData()
    formData.append('image', blob, `image.${cropOption.format}`)
    
    try {
      const response = await axios.post('/api/upload', formData, {
        headers: { 'Content-Type': 'multipart/form-data' }
      })
      
      if (response.data.code === 200) {
        alert('이미지 업로드 성공')
      }
    } catch (error) {
      alert('업로드 실패: ' + error.message)
    } finally {
      isUploading.value = false
    }
  })
}
</script>

스타일 정의

<style scoped>
.cropper-container {
  width: 100%;
  max-width: 600px;
  margin: 0 auto;
}

.preview-section {
  margin-top: 20px;
  border: 1px solid #ddd;
  min-height: 200px;
}

.controls {
  display: flex;
  gap: 10px;
  margin-top: 15px;
  flex-wrap: wrap;
}

.controls button {
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  background-color: #409eff;
  color: white;
  cursor: pointer;
}

.controls button:disabled {
  background-color: #ccc;
  cursor: not-allowed;
}

.controls input[type="file"] {
  margin-right: 10px;
}
</style>

주요 옵션 설명

속성 설명 기본값
img 크롭할 이미지 URL -
outputSize 출력 이미지 품질 (0.1 ~ 1) 1
outputType 출력 포맷 (jpeg, png, webp) png
autoCrop 자동 크롭 영역 생성 false
centerBox 크롭 박스를 이미지에 맞춤 false
canMove 이미지 이동 가능 여부 true
fixed 크롭 박스 비율 고정 false

사용 시 주의사항

  • 로컬 mock 서버가 실행 중이면 이미지 변환 시 오류가 발생할 수 있으므로 종료 후 사용하세요
  • 반드시 외層 컨테이너를 만들고 크기를 설정해야 합니다
  • 마우스 휠로 이미지 확대/축소 가능
  • 크롭 영역 테두리를 드래그하여 크기 조절 가능

vue-cropper는 Vue 3 환경에서 이미지 크롭 기능을 쉽게 구현할 수 있도록 도와주는 강력한 도구입니다. 위에 설명된 기본 사용법과 옵션들을 활용하면 다양한 요구사항에 맞는 이미지 크롭 기능을 구현할 수 있습니다.

태그: vue3 vue-cropper image-cropping JavaScript frontend

6월 3일 19:52에 게시됨