Skip to Content
์ด๋ฏธ์ง€ ์—๋””ํ„ฐ

์ด๋ฏธ์ง€ ์—๋””ํ„ฐ

@inkio/image-editor๋Š” ์ž๋ฅด๊ธฐ, ํšŒ์ „, ํฌ๊ธฐ ์กฐ์ ˆ, ๊ทธ๋ฆฌ๊ธฐ, ๋„ํ˜•, ํ…์ŠคํŠธ ์ฃผ์„ ๊ธฐ๋Šฅ์„ ๊ฐ–์ถ˜ ๋…๋ฆฝ ์ด๋ฏธ์ง€ ํŽธ์ง‘๊ธฐ์ž…๋‹ˆ๋‹ค. ์—๋””ํ„ฐ์˜ ์ด๋ฏธ์ง€ ๋ธ”๋ก์— ์—ฐ๊ฒฐํ•˜๊ฑฐ๋‚˜ ๋‹จ๋… ์ปดํฌ๋„ŒํŠธ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์„ค์น˜์™€ CSS

์ด๋ฏธ์ง€ ์—๋””ํ„ฐ๋Š” ์ž์ฒด ์Šคํƒ€์ผ์‹œํŠธ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์•ฑ ์ง„์ž…์ ์—์„œ ํ•œ ๋ฒˆ import ํ•˜์„ธ์š”.

import '@inkio/image-editor/style.css';

์—๋””ํ„ฐ์— ์—ฐ๊ฒฐํ•˜๊ธฐ

@inkio/editor(๋˜๋Š” @inkio/simple)์˜ imageBlock.imageEditor ์˜ต์…˜์— ImageEditorModal์„ ์ „๋‹ฌํ•˜๋ฉด ์ด๋ฏธ์ง€ ํˆด๋ฐ”์— ํŽธ์ง‘ ๋ฒ„ํŠผ์ด ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค. ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ๋ชจ๋‹ฌ์ด ์—ด๋ฆฌ๊ณ , ์ €์žฅ ์‹œ ํŽธ์ง‘ ๊ฒฐ๊ณผ๊ฐ€ ํ•ด๋‹น ์ด๋ฏธ์ง€ ๋ธ”๋ก์— ๋ฐ˜์˜๋ฉ๋‹ˆ๋‹ค.

import { Editor } from '@inkio/editor'; import { ImageEditorModal } from '@inkio/image-editor'; import '@inkio/editor/style.css'; import '@inkio/image-editor/style.css'; export function Page() { return ( <Editor onImageUpload={async (file) => URL.createObjectURL(file)} imageBlock={{ imageEditor: ImageEditorModal }} /> ); }

imageEditor์—๋Š” { isOpen, imageSrc, onSave, onClose } ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ์กฑํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋ผ๋ฉด ๋ฌด์—‡์ด๋“  ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ImageEditorModal์ด ๊ธฐ๋ณธ ๊ตฌํ˜„์ž…๋‹ˆ๋‹ค.

ImageEditorModal props

Propํƒ€์ž…์„ค๋ช…
isOpenboolean๋ชจ๋‹ฌ ์—ด๋ฆผ ์—ฌ๋ถ€ (ํ•„์ˆ˜)
imageSrcstringํŽธ์ง‘ํ•  ์ด๋ฏธ์ง€ ์†Œ์Šค (ํ•„์ˆ˜)
onSave(editedImageData: string) => void์ €์žฅ ์‹œ ํŽธ์ง‘๋œ data URL ์ฝœ๋ฐฑ (ํ•„์ˆ˜)
onClose() => void๋‹ซ๊ธฐ ์ฝœ๋ฐฑ (ํ•„์ˆ˜)
theme'light' | 'dark'์ƒ‰์ƒ ํ…Œ๋งˆ (๋ฏธ์ง€์ • ์‹œ .inkio ๋ฃจํŠธ์˜ ํ…Œ๋งˆ๋ฅผ ๋”ฐ๋ฆ„)
imageQualitynumber์ถœ๋ ฅ ํ’ˆ์งˆ 0~1 (๊ธฐ๋ณธ๊ฐ’: 0.92)
imageFormat'png' | 'jpeg' | 'webp'์ถœ๋ ฅ ํ˜•์‹ (๊ธฐ๋ณธ๊ฐ’: 'png')
toolsToolType[]๋…ธ์ถœํ•  ๋„๊ตฌ ๋ชฉ๋ก
localestring | Partial<ImageEditorLocale>๋กœ์ผ€์ผ ID ๋˜๋Š” ๋ผ๋ฒจ ์˜ค๋ฒ„๋ผ์ด๋“œ
messagesInkioImageEditorMessageOverrides | InkioMessageOverrides๋ฉ”์‹œ์ง€ ์˜ค๋ฒ„๋ผ์ด๋“œ
iconsPartial<InkioIconRegistry>์•„์ด์ฝ˜ ์˜ค๋ฒ„๋ผ์ด๋“œ

๋‹จ๋… ์ปดํฌ๋„ŒํŠธ ์‚ฌ์šฉ

๋ชจ๋‹ฌ ์—†์ด ์ธ๋ผ์ธ ํŽธ์ง‘ ํ™”๋ฉด์„ ์ง์ ‘ ๋ฐฐ์น˜ํ•˜๋ ค๋ฉด ImageEditor๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

import { ImageEditor } from '@inkio/image-editor'; import '@inkio/image-editor/style.css'; export function StandaloneEditor({ src }: { src: string }) { return ( <ImageEditor src={src} onSave={(dataUrl) => console.log('saved', dataUrl)} onCancel={() => console.log('cancelled')} /> ); }

ImageEditor props

Propํƒ€์ž…์„ค๋ช…
srcstringํŽธ์ง‘ํ•  ์ด๋ฏธ์ง€ ์†Œ์Šค (ํ•„์ˆ˜)
onSave(dataUrl: string) => void์ €์žฅ ์‹œ ํŽธ์ง‘๋œ data URL ์ฝœ๋ฐฑ (ํ•„์ˆ˜)
onCancel() => void์ทจ์†Œ ์ฝœ๋ฐฑ (ํ•„์ˆ˜)
outputFormat'png' | 'jpeg' | 'webp'์ถœ๋ ฅ ํ˜•์‹ (๊ธฐ๋ณธ๊ฐ’: 'png')
outputQualitynumber์ถœ๋ ฅ ํ’ˆ์งˆ 0~1
toolsToolType[]๋…ธ์ถœํ•  ๋„๊ตฌ ๋ชฉ๋ก
defaultToolToolType์ดˆ๊ธฐ ์„ ํƒ ๋„๊ตฌ
localePartial<ImageEditorLocale>๋ผ๋ฒจ ์˜ค๋ฒ„๋ผ์ด๋“œ
classNamestring๋ฃจํŠธ ์—˜๋ฆฌ๋จผํŠธ ํด๋ž˜์Šค
maxUndoStepsnumber์‹คํ–‰ ์ทจ์†Œ ๊ธฐ๋ก ํ•œ๋„ (๊ธฐ๋ณธ๊ฐ’: 30)
onDirtyChange(dirty: boolean) => void๋ฏธ์ €์žฅ ๋ณ€๊ฒฝ ๋ฐœ์ƒ/ํ•ด์†Œ ์ฝœ๋ฐฑ

๋„๊ตฌ์™€ ์ฃผ์„

ToolType์€ ๋‹ค์Œ ๋„๊ตฌ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

type ToolType = 'crop' | 'rotate' | 'resize' | 'draw' | 'shape' | 'text';
  • crop โ€” ์ž๋ฅด๊ธฐ ์˜์—ญ ์ง€์ •
  • rotate โ€” ํšŒ์ „ ๋ฐ ์ขŒ์šฐ/์ƒํ•˜ ๋ฐ˜์ „
  • resize โ€” ์ถœ๋ ฅ ํฌ๊ธฐ ์กฐ์ ˆ
  • draw โ€” ์ž์œ  ๊ทธ๋ฆฌ๊ธฐ (๋ธŒ๋Ÿฌ์‹œ)
  • shape โ€” ์‚ฌ๊ฐํ˜•, ํƒ€์›, ํ™”์‚ดํ‘œ, ์„  ๋„ํ˜•
  • text โ€” ํ…์ŠคํŠธ ์ฃผ์„

tools๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธ ๋ชฉ๋ก(['resize', 'draw', 'shape', 'text', 'rotate'])์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

<ImageEditor src={src} tools={['draw', 'text']} onSave={save} onCancel={cancel} />

๊ทธ๋ฆฌ๊ธฐยท๋„ํ˜•ยทํ…์ŠคํŠธ๋กœ ์ถ”๊ฐ€ํ•œ ํ•ญ๋ชฉ์€ ์ฃผ์„(annotation)์œผ๋กœ ๊ด€๋ฆฌ๋ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์ฃผ์„ ํƒ€์ž…์€ Annotation ์œ ๋‹ˆ์˜จ์œผ๋กœ export๋ฉ๋‹ˆ๋‹ค.

ํƒ€์ž…์„ค๋ช…
RectAnnotation์‚ฌ๊ฐํ˜• ๋„ํ˜•
EllipseAnnotationํƒ€์› ๋„ํ˜•
ArrowAnnotationํ™”์‚ดํ‘œ
LineAnnotation์ง์„ 
TextAnnotationDataํ…์ŠคํŠธ ์ฃผ์„
FreeDrawAnnotation์ž์œ  ๊ทธ๋ฆฌ๊ธฐ ์„ 

์ด ์™ธ์— CropRect, Transform, DrawOptions, ShapeOptions, TextOptions, ImageEditorState ๋“ฑ์˜ ๋ณด์กฐ ํƒ€์ž…๋„ ํ•จ๊ป˜ export๋ฉ๋‹ˆ๋‹ค.

i18n

์ด๋ฏธ์ง€ ์—๋””ํ„ฐ๋Š” @inkio/core์™€ ๋™์ผํ•œ ๋ฉ”์‹œ์ง€ ์ฒด๊ณ„๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ๋„๊ตฌ ๋ผ๋ฒจ ๋“ฑ UI ํ…์ŠคํŠธ๋Š” ๋‹ค์Œ ํ—ฌํผ๋กœ ์กฐํšŒยท์˜ค๋ฒ„๋ผ์ด๋“œํ•ฉ๋‹ˆ๋‹ค.

import { enImageEditorMessages, resolveImageEditorMessages, mergeImageEditorMessages, toImageEditorMessageOverrides, } from '@inkio/image-editor';
Export์„ค๋ช…
enImageEditorMessages๊ธฐ๋ณธ(์˜์–ด) ๋ฉ”์‹œ์ง€ ์„ธํŠธ
resolveImageEditorMessages๋กœ์ผ€์ผ ์ž…๋ ฅ๊ณผ ์˜ค๋ฒ„๋ผ์ด๋“œ๋ฅผ ๋ณ‘ํ•ฉํ•ด ๋ฉ”์‹œ์ง€ ์„ธํŠธ๋ฅผ ๋ฐ˜ํ™˜
mergeImageEditorMessages์—ฌ๋Ÿฌ ์˜ค๋ฒ„๋ผ์ด๋“œ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ๋ณ‘ํ•ฉ
toImageEditorMessageOverridesInkioMessageOverrides์—์„œ ์ด๋ฏธ์ง€ ์—๋””ํ„ฐ ์˜ค๋ฒ„๋ผ์ด๋“œ๋ฅผ ์ถ”์ถœ

๊ฐ„๋‹จํžˆ ๋ผ๋ฒจ๋งŒ ๋ฐ”๊พธ๋ ค๋ฉด ImageEditorModal/ImageEditor์˜ locale prop์— Partial<ImageEditorLocale> ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ์ „๋‹ฌํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค.

<ImageEditorModal isOpen={isOpen} imageSrc={src} onSave={onSave} onClose={onClose} locale={{ save: '์ €์žฅ', cancel: '์ทจ์†Œ' }} />
Last updated on