최근 사내 프로젝트를 진행하던 도중, ai 인식을 위해 키오스크 기기에서 촬영한 이미지 파일을 서버로 보내야 하는 상황이 있었다. 이미지 파일을 blob 형식으로 보냈는데, 서버에서 정상 인식이 되지 않는 상황이 발생해 디깅을 하다, File 형식으로 보내야 한다는 것을 깨닫고...
두 형식의 차이점이 무엇인지 궁금해졌다.
결론부터 말하자면, File 객체는 Blob 의 확장이다. 만약 input 을 통해 file 을 업로드 하면, 이 데이터의 형식이 바로 File 형식이다.
테스트를 위해 임시로 input 을 통해 file 을 받아 업로드 했을 때 정상 동작했던게 바로 이런 차이가 있기 때문이다...
그렇다면 Blob 객체란 무엇이냐?
Blob 은 Binary Large Object 의 약자로, 이진 데이터의 원시 형식을 의미한다. 큰 파일 데이터를 이진 데이터로 효율적으로 처리하기 위해 사용하는 데이터 타입이다. Blob 객체는 이미지 뿐만 아니라 텍스트, 사운드, 비디오 같은 다양한 형식의 데이터를 나타낼 수 있다.
앞서 File 형식 데이터가 Blob의 확장이라고 했는데, 그럼 어떤 차이점이 있을까? File 객체는 메타 데이터를 포함한다. 메타 데이터에는 파일명, 수정 시간 등이 포함된다...
어쨌든 이미지를 주고받기 위해서 Blob 이든 File 이든 어떤 형식이든 상관 없었겠지만 서버에서 어떤 타입의 데이터를 필요로 하냐에 달렸기 때문에 그에 맞는 형식을 주어야 한다..
추가로, 나는 canvas 를 통해 video 태그의 이미지를 추출해 이 데이터를 Blob 으로 변환하고 다시 File 형식으로 변환해 서버로 전송하는 아래와 같은 로직을 작성할 수 있었다... 참고로 canvas 로 추출한 데이터는 ArrayBuffer 형식으로 들어온다.
const captureAsFile = async (): Promise<File | null> => {
const canvas = canvasRef.current;
const context = canvas?.getContext('2d');
if (!canvas || !context || !videoRef.current) return null;
context.drawImage(videoRef.current, 0, 0, canvas.width, canvas.height);
const blob = await createBlobFromCanvas(canvas);
if (blob) {
const file = new File([blob], 'captured_image.png', {
type: 'image/png',
});
return file;
} else {
return null;
}
};
const createBlobFromCanvas = async (
canvas: HTMLCanvasElement,
): Promise<Blob | null> => {
return new Promise((resolve) => {
canvas.toBlob(resolve, 'image/png');
});
};
위 로직을 통해 얻은 파일 데이터는 formData 형식으로 서버에 전송할 수 있다.
export const imageFileToFormData = (image: File) => {
const formData = new FormData();
formData.append('file', image, '테스트용 이미지');
return formData;
};
'프로젝트 > work' 카테고리의 다른 글
프론트엔드 e2e 테스트 도입기: 구조화가 필요해..! (feat. cypress) (0) | 2023.12.02 |
---|---|
CRA to Vite 마이그레이션 및 테스트환경 세팅하기 (0) | 2023.09.21 |