김춘식의 짱쎈 블로그.

Blob 이란?

2021년 04월 12일
#web_api#javascript#programming

JS에서 Blob(Binary Large OBject)은 주로 이미지, 오디오, 영상 등의 데이터를 다룰 때 사용한다. (물론 꼭 미디어 관련해서만 사용하는 것이 아니라 html, plain text 등 바이너리로 표현 가능한 많은 데이터에서 쓸 수 있다.)

역사

짐 스타키라는 데이터베이스 설계자가 1970년대에 처음 발명했다. Blob은 기존 DB 시스템에서 정의되지 않은 데이터를 정의하기 위해 탄생했는데, 탄생 당시에는 데이터를 저장하기에 너무 컸기 때문에 잘 사용되지 않았지만 이후 기술이 발전함에 따라 디스크 공간이 점점 저렴해지면서 사용되게 되었다.

Blob이라는 이름의 유래는 스티브 매퀸 주연의 1958년 작, The Blob2영화에 나오는 괴물의 이름이었다. 나중에 Apollo Computer3의 마케팅 담당자인 테리 매키버가 이를 보고 두문자어가 되어야 한다고 느꼈고, 배크로님4을 활용해 Basic Large OBject로 변경되었다. 그 이후 한 번 더 변경된 뜻이 지금 우리가 아는 Binary Large OBject이다.

(역시 개발자들의 작명 센스는 언제나 공감하기 어려운 것 같다.)

Blob의 사용법

MDN의 설명을 참고하자면 아래의 형태로 생성되고 있다.

// 생성자
const blob = new Blob(ArrayBuffer || ArrayBufferView || Blob(File) || DOMString, [, options])

// html
const html = ['<p>HEEEEELLO WORLD!</p>']
const htmlBlob = new Blob(html, { type: 'text/html', endings: 'native' })

// 이미지
const image = [new Uint64Array(someImgData)]
const imageBlob = new Blob(image, { type: 'image/jpeg' })

위 코드를 보면 아실 수 있듯이, option에는 해당 파일의 type, endings을 사용할 수 있다. (설명은 위 MDN의 설명 클릭하시면 보실 수 있다.)

Blob의 생김새

Blob의 생김새 size를 통해 해당 파일의 bytes를 확인 할 수 있고 type을 통해 MIME5을 알 수 있다.

관련 Method를 활용해보자!

  1. slice method

Blob 객체를 지정한 bytes 만큼 잘라내어 새로운 blob 객체로 만든다. 보통 큰 Blob을 작게 조각내야할 때 사용한다.

const blob = new Blob()
blob.slice(start, end, type)

start는 시작할 bytes 범위, end는 종료할 bytes 범위, type은 새롭게 생성될 Blob의 MIME 타입을 뜻한다.

// blob을 개수대로 잘라주는 함수
function sliceBlob(blob, sliceCount) {
  const blobs = []
  const chunkSize = Math.ceil(blob.size / sliceCount)
  for (let i = 0; i < sliceCount; ++i) {
    const startBytes = chunkSize * i
    const slicedBlob = blob.slice(startBytes, startBytes + chunkSize, blob.type)
    blobs.push(slicedBlob)
  }
  return blobs
}

const someBlob = new Blob(~~~~)
const slicedBlobs = sliceBlob(someBlob, 2)
console.log(slicedBlobs)

Blob의 생김새에서 얻은 Blob을 2개로 나눠 보았다.

잘려진 Blob

Blob들의 size를 보니 잘 나눠진 것을 볼 수 있다.

그럼 이쯤에서 예상할 수 있듯이, 자른 Blob은 다시 합칠 수 있다.

// ... 위의 코드에서 이어집니다.
const mergedBlob = new Blob(
  slicedBlobs,
  { type: someBlob.type }
)
console.log(mergedBlob)

다시 합쳐진 Blob

이렇게 하면 Blob이 합쳐진 것을 볼 수 있다.

여기서 주의할 점은, Blob 객체는 immutable 하다. 즉, 수정 등을 할 수는 없다.. 대신 Blob 객체를 slice, merge 하는 과정에서 Blob을 변경할 수 있다.

이 점은 우리가 평소에 많이 쓰는 문자열과 비슷하다. 문자열의 문자를 변경할 수는 없지만, 수정된 문자열은 만들 수 있는 것처럼 말이다.

Blob URL

위에서 사용한 Blob들을 img 태그등에 넣어 DOM에서 보여주기 위해서는 URL.createObjectURL(blob)를 활용해, 브라우저 내의 Blob 객체를 가르키는 고유한 DOMString형태의 URL로 변환 작업이 필요하다.

// ... 위의 코드에서 이어집니다.
const blobURL = URL.createObjectURL(mergedBlob)
console.log(blobURL) // blob:http://localhost/{hash 값}

마지막으로, createObjectURL로 생성된 Blob URL은 URL.revokeObjectURL(blobURL)을 호출하기 전까지는 브라우저 메모리에 상주한다. 즉, 메모리 누수가 발생할 수 있다.

따라서 꼭 URL.createObjectURL(blob) 메소드를 사용한 후에는 URL.revokeObjectURL(blobURL) 메소드를 호출해야한다.

References


  1. Irvin Yeaworth 감독, 스티브 매퀸 주연의 1958년작 SF 호러 영화.
  2. 1980년대의 컴퓨터 제조업체, 그래픽 워크 스테이션의 최초의 공급 업체 중 하나
  3. backronym, 단어의 각 문자를 사용하여 새로운 약어의 의미를 갖게하는 것
  4. Multipurpose Internet Mail Extensions의 줄임말. 이메일을 위한 인터넷 표준 포멧이다. 위 내용에서는 MIME의 content-type을 뜻한다. text/plain, image/png...

Copyright ⓒ 2022 김춘식 All rights reserved.

Powered By Gatsby