일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Git
- adb connect
- github pdf
- dvh
- html
- github lfs
- react-native-dotenv
- npm package
- camera permission
- Recoil
- Failed to compiled
- Can't resolve
- ELECTRON
- electron-packager
- rolldown
- github 100mb
- silent printing
- nextjs
- Each child in a list should have a unique "key" prop.
- animation
- 이미지 데이터 타입
- device in use
- camera access
- 티스토리 성능
- custom printing
- adb pair
- react-native
- vercel git lfs
- ffi-napi
- augmentedDevice
- Today
- Total
Bleeding edge
Image date 다루기(data 변환에 관하여) 본문
Intro
이번에 카메라 앱에서 이미지를 crop하는 기능을 만들려고 canvas를 사용했다. canvas에서 이미지를 사용하려고 하니 input에서 받은 파일의 데이터 형식으로는 canvas에서 이미지를 바로 그릴 수 없다는 것을 알게 되었다.
우리가 웹을 만들면서 바로 받는 타입은 [URL, File] 두 가지이다.
이 두타입에 대해 간략하게 이야기하자면..
URL : 일반적으로 우리가 이미 알고 있거나 외부의 엔드포인트로부터 받은 이미지의 주소의 값을 말한다.
File : Input type file을 사용하면 Input의 event.target.value로 들어오는 값이다.
Image data map
canvas의 이미지에 대해서 이해를 잘하기 위하여 구글링을 해보았더니 다음과 같은 관계도가 있었다.
(출처 : https://observablehq.com/@ehouais/how-to-get-image-data-from-an-url-or-a-file)
이미지 데이터 타입 통일
canvas에 이미지를 그릴 때도 image.src를 이용하고, canvas에서도 이미지를 수정하고 변환을 할 때 toDataURL 그리고 img에서도 src를 사용하기에 이미지는 url로 변환해서 사용하는 것이 가장 편안하다고 생각해서 파일 데이터가 들어오면 이미지 데이터를 url로 통일하도록 하겠다.
File 타입 변환하기
우선 파일이 한 개가 input에 들어온다고 가정하고 코드를 작성하겠다.
function handleFileChange(event: React.ChangeEvent<HTMLInputElement>){
const file = event.target.files?.[0];
//...
};
위의 그래프에는 써있는 방법은 아니지만, File로 파일이 들어오면 다음과 같은 방법으로 base64 데이터타입으로 변환할 수 있다.
function fileToBase64String(file: File) {
return new Promise<string>((res, rej) => {
const reader = new FileReader();
reader.onload = () => {
if (typeof reader.result === 'string') res(reader.result || '');
};
reader.readAsDataURL(file);
reader.onerror = () => '';
});
}
function handleFileChange(event: React.ChangeEvent<HTMLInputElement>){
//현재 이미지의 데이터 타입은 File
const file = event.target.files?.[0];
if(!file) return
//현재 이미지의 데이터 타입은 base64 string으로 인코딩 되었다.
const base64String = await fileToBase64String(file);
//...
};
우리가 이미지 혹은 canvas에서 바로 사용할 수 있도록 url을 만들어야한다. 이 때 우리는 base64 string에서 url로 바꾸기 위해서 Blob으로 변환을 해야한다.
async function base64StringToBlob(base64String: string) {
const base64 = await fetch(base64String);
return base64.blob();
}
function fileToBase64String(file: File) {
return new Promise<string>((res, rej) => {
const reader = new FileReader();
reader.onload = () => {
if (typeof reader.result === 'string') res(reader.result || '');
};
reader.readAsDataURL(file);
reader.onerror = () => '';
});
}
async function handleFileChange(event: React.ChangeEvent<HTMLInputElement>){
//현재 이미지의 데이터 타입은 File
const file = event.target.files?.[0];
if(!file) return
//현재 이미지의 데이터 타입은 base64
const base64String = await fileToBase64String(file);
//현재 이미지의 데이터 타입은 Blob
const jpgBlob = await base64StringToBlob(base64String);
//...
};
드디어 이미지의 그래프에 있는대로 URL.createObjectURL를 이용하여 데이터 url만들 수 있다. (위의 그래프가 정말 다양한 데이터 타입에 대해 이해를 할 수 있지만, 아마 저 그래프는 한 개의 메서드로 바로 변환할 수 있는 경우만 적어놓은 것 같다)
async function base64StringToBlob(base64String: string) {
const base64 = await fetch(base64String);
return base64.blob();
}
function fileToBase64String(file: File) {
return new Promise<string>((res, rej) => {
const reader = new FileReader();
reader.onload = () => {
if (typeof reader.result === 'string') res(reader.result || '');
};
reader.readAsDataURL(file);
reader.onerror = () => '';
});
}
async function handleFileChange(event: React.ChangeEvent<HTMLInputElement>){
//현재 이미지의 데이터 타입은 File
const file = event.target.files?.[0];
if(!file) return
//현재 이미지의 데이터 타입은 base64
const base64String = await fileToBase64String(file);
//현재 이미지의 데이터 타입은 Blob
const jpgBlob = await base64StringToBlob(base64String);
//현재 이미지의 데이터 타입은 URL
const objectURL = URL.createObjectURL(jpgBlob);
console.log(objectURL)
};
Retro
이전에 contentEditable이 가장 성가신 친구인 줄 알았는데 이미지나 canvas를 다루는 것도 이미지 데이터 타입부터 이미지를 변환하고나서의 화질저하와 같은 성가신 것들이 많았다. 간만에 공부할 것이 많아서 재밌었다.
'Javascript' 카테고리의 다른 글
[Electron]Error accessing the camera: DOMException: Could not start video source - 맥북 (0) | 2023.12.19 |
---|---|
Window에서 chrome으로 자동 인쇄하기(silent printing) (0) | 2023.12.18 |
자바스크립트로 모든 이벤트를 확인하기 (0) | 2023.10.21 |
prerendering page "/" ReferenceError: window is not defined (0) | 2023.10.21 |
Axios로 간이 api mocking 세팅하기 (0) | 2023.08.14 |