BLOB이란?
- Binary Large OBject
- 이미지, 미디어, html 등의 객체를 바이너리 형태로 저장할 때 사용되는 데이터 타입
- 짐 스타키라는 데이터 베이스 설계자가 1970년대에 처음 발명
- BLOB이라는 이름의 유래는 스티브 매퀸 주연의 1958년 작, The Blob 영화에 나오는 괴물의 이름이라고...
BLOB 생성
const newBlob = new Blob(array, options);
new Blob([new ArrayBuffer(8)], { type: 'video/mp4' });
new Blob(new Uint8Array(buffer), { type: 'image/png' });
new Blob(['<div>Hello Blob!</div>'], {
type: 'text/html',
endings: 'native'
});
- array
- ArrayBuffer, TypedArray, Blob, File, DOMString 등 객체들이 저장될 수 있는 데이터 타입
- ArrayBuffer: 고정된 길이의 연속된 메모리 공간 (레퍼런스 타입)
- TypedArray: ArrayBuffer를 조작할 수 있는 데이터 타입
- Uint8Array, Uint16Array, Uint32Array, Float64Array, …
- File: name, lastModifiedDate만 추가된 Blob
- options
- type: 데이터의 MIME 타입을 설정
- MIME 타입: 전송 데이터의 타입으로, 보통 데이터 응답자가 리소스를 내려받았을 때에 어떤 동작을 기본적으로 해야 하는지를 결정하도록 만들어주는 지표
- text/plain, text/html, image/jpeg, audio/*
- endings: 데이터가 텍스트일때 개행 문자 '\n'을 어떻게 해석할지를 지정
- transparent: 개행 문자를 바꾸지 않고 블록 데이터로 복사
- native: 사용 중인 OS에 맞춰서 줄 바꿈 문자 인식하여 데이터를 삽입
BLOB 메소드
- slice: Blob을 작은 조각으로 분리시키기 위한 메소드
blob.slice(start, end, type);
const chunks = [];
const numberOfSlices = 10;
const chunkSize = Math.ceil(blob.size / numberOfSlices);
for (let i = 0; i < numberOfSlices; i += 1) {
const startByte = chunkSize * i;
chunks.push(
blob.slice(
startByte,
startByte + chunkSize,
blob.type
)
);
}
const mergedBlob = new Blob(
chunks,
{ type: blob.type }
);
- createObjectURL: blob객체를 가리키는 URL
- DOM, CSS에서 활용 가능 = 이미지 표시 가능
- revokeObjectURL: createObjectURL()을 통해 생성한 URL을 폐기
Canvas란?
- html5에서 새롭게 등장한 그래픽을 그리기 위한 수단을 제공 (특히 2d)
Canvas 메소드
- getContext: 실제로 그림을 그릴 수 있는 context를 갖고오는 메소드
var ctx = canvas.getContext(contextType, contextAttributes);
- contextType: 드로잉 컨텍스트를 정의하는 컨텍스트 식별자
- 2d, webgl, webgl2, bitmaprenderer
- contextAttributes:
- drawImage
drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)

- image: 이미지를 그리는데 활용할 원본 객체
- sx: 이미지 내 x 좌표
- sy: 이미지 내 y좌표
- sWidth: 이미지 가로 길이
- sHeight: 이미지 세로 길이
- dx: 캔버스의 x좌표
- dy: 캔버스의 y좌표
- dWidth: 캔버스 위에 그려질 이미지의 가로 길이
- dHeight: 캔버스 위에 그려질 이미지의 세로 길이
- toDataURL: 캔버스에 그려진 이미지를 base64 문자열로 변환하는 메소드
Base64란?
- 바이너리 데이터를 문자 코드에 영향을 받지 않는 공통 ASCII 문자로 표현하기 위해 만들어진 인코딩
- 8비트 짜리를 6비트 짜리로 쪼개서 아래 문자열표 기반으로 표현함

- 바이너리 데이터와 base64간 변환은 atob (ascii to binary), btoa (binary to ascii) 를 통해서 가능
이미지 정방형 Crop 하는 예제 코드
<input
name={'image'}
type="file"
onChange={cropAndUploadFile}
/>
const cropAndUploadFile = async (e, target) => {
const file = e.target.files[0];
const image = document.createElement('img');
image.src = URL.createObjectURL(file);
image.onload = async () => {
const { width, height } = image;
const files = await cropImage(image, width, height, width);
};
};
const cropImage = async (image, imageWidth, imageHeight, cropSize) => {
const files = [];
const cropX = 0;
const cropWidth = cropSize;
let cropY = 0;
let cropHeight = cropSize;
const count = Math.ceil(imageHeight / imageWidth);
for (let i = 0; i < count; i++) {
const canvas = document.createElement('canvas');
canvas.width = cropWidth;
cropHeight = Math.min(cropHeight, imageHeight - cropY);
canvas.height = cropHeight;
const ctx = canvas.getContext('2d');
ctx.drawImage(
image,
cropX,
cropY,
cropWidth,
cropHeight,
0,
0,
cropWidth,
cropHeight,
);
const url = await new Promise((resolve) => {
resolve(canvas.toDataURL('image/jpeg'))
});
const file = dataURItoBlob(url);
file.name = `${i}.jpg`;
files.push(file);
cropY += cropHeight;
}
return files;
};
dataURItoBlob = (dataURI) => {
const binary = atob(dataURI.split(',')[1]);
const array = [];
for (let i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
return new Blob([new Uint8Array(array)], { type: 'image/jpeg' });
};