Blob객체란?

조민호·2023년 5월 18일
4

  1. Blob은 대형 이진 객체(Binary Large Object)를 의미하며 일련의 데이터를 처리하거나 간접 참조하는 객체입니다

    Blob은 대개 바이트의 크기를 알아내거나 해당 MIME 타입이 무엇인지 요청하며,

    데이터를 작은 Blob으로 잘게 나누는 등의 작업에 사용됩니다

    "즉, 데이터 자체라기보다는 데이터를 간접적으로 접근하기 위한 객체인 것입니다"


  1. Blob은 웹에서 사용되는 데이터 형식으로, 이진 데이터를 나타내며, 텍스트, 이미지, 오디오, 비디오 등 다양한 형식을 지원합니다

    주로 파일 업로드, 이미지 프로세싱, 미디어 처리 등에서 사용됩니다.

    예를 들면, 이미지나 동영상 같은 큰 파일들을 메모리에 효율적으로 저장하고 전송할 수 있게 해주는 역할을 합니다.


  1. JS에서 Blob 객체는 데이터 덩어리를 참조하는 용도로 사용합니다.

    큰 데이터는 물론 작은 데이터도 다룰 수 있습니다.

    즉, 이진 데이터는 물론이거니와 텍스트 데이터도 다룰 수 있습니다.

    Blob 객체는 메모리상의 데이터(바이트 배열)도 참조할 수 있으며 파일의 데이터도 참조할 수 있습니다.

    웹브라우저는 메모리 또는 디스크에 Blob을 저장할 수 있으며, Blob은 비디오 파일과 같이 매우 커서, 메모리에 적재하려면 slice()를 활용하여 작은 조각으로 먼저 분리해야 할 수도 있습니다

    데이터의 크기가 매우 크기 때문에 디스크를 사용해야 하므로

    Blob API 는 비동기 방식으로 동작합니다




Blob 객체 생성하는 방법


  1. new Blob()이라는 생성자 사용하기

    이 생성자에는 두 가지 주요한 부분이 있습니다. 첫 번째 부분은 Blob 객체에 들어갈 데이터이고, 두 번째 부분은 그 데이터의 형식에 대한 정보입니다.

    예를 들어, "Hello, World!" 라는 텍스트를 Blob 객체로 만들고 싶다면, 다음과 같이 작성합니다

    let helloWorldBlob = new Blob(["Hello, World!"], {type : "text/plain"});

    여기서 "Hello, World!" 이라는 텍스트가 Blob 객체의 첫 번째 부분에 들어가게 되고,

    이 텍스트가 일반 텍스트임을 나타내는 "text/plain"이라는 정보가 두 번째 부분에 들어가게 됩니다

    위의 경우는 “Hello , World!”라는 문자열 타입을 버퍼의 요소로 지정했지만

    문자열 뿐만 아니라 , 다음과 같은 데이터 타입을 버퍼의 요소로 지정할 수 있습니다.

    • ArratBuffer
    • TypedArray
    • DataView
    • Blob
    • String
    • 기타 모든 데이터 타입

    단, String 타입은 UTF-8 바이너리로 변환됩니다. 그 외의 모든 데이터 타입의 값은 toString메서드로 문자열로 변환한 UTF-8바이너리로 변환됩니다.

    이렇게 생성된 Blob 객체의 프로퍼티와 메서드는 아래와 같습니다

    프로퍼티 이름/ 메서드이름걸명
    sizeBlob 객체가 참조하는 데이터 크기(바이트 단위)
    typeBlob 객체가 참조하는 데이터의 MIME 타입을 뜻하는 문자열
    slice(start, end, contentType)버퍼의 start 부터 end 까지의 복사본을 MIME 타입이contentType인 Blob 객체로 반환한다. 즉 , 블롭의 일부에서 새로운 블롭을 생성할 때 사용하는 것이다

    • 문자열에서 일반 json객체 생성
      const obj = {hello: 'world'};
      const blob = new Blob([JSON.stringify(obj, null, 2)], {type : 'application/json'});
    • 빈 Blob 객체 생성
      var blob = new Blob();
      console.log(blob.size, blob.type); // -> 0 ""
    • 문자열을 가리키는 Blob 객체를 생성
      var blob = new Blob(["Javascript"], {type: "text/plain"});
      console.log(blob.size, blob.type); // 10 "text/plain"
    • 형식화 배열을 가리키는 Blob 객체를 생성
      var a = new Uint8Array([0, 1, 2, 3]);
      var blob = new Blob(a, {type: "application/octet-stream"});
      console.log(blob.size, blob.type); // 4 "application/octet-stream"

    (Blob 객체를 일반 이진 데이터로 다루고자할 때는

    contentType을 {type: "application.octet-stream" }으로 설정)


  1. HTTP 통신으로 가져오기

    비동기 HTTP 통신 메소드를 사용할 때 Blob객체로 받아올 수 있습니다

    responseType: 'blob' 으로 설정함으로써

    비동기 요청 데이터를 Blob객체 형태로 반환 받는 것입니다

    const imgurl = 'https://play-lh.googleusercontent.com/hYdIazwJBlPhmN74Yz3m_jU9nA6t02U7ZARfKunt6dauUAB6O3nLHp0v5ypisNt9OJk';
    
    axios({
       url: imgurl,
       method: 'GET',
       responseType: 'blob' **// blob 데이터로 이미지 리소스를 받아오게 지정**
    })
    .then((response) => {
       const url = URL.createObjectURL(response.data); // blob 데이터를 객체 url로 변환
       
       // 이미지 자동 다운 로직
       const link = document.createElement('a');
       link.href = url 
       link.setAttribute('download', `sample.png`)
       document.body.appendChild(link)
       link.click()
     })

  1. 로컬 파일에서 가져오기

    <input type="file"> 을 사용하면 사용자가 로컬 파일 시스템에서 파일을 선택할 수 있습니다.

    사용자가 파일을 선택하면, 이 파일은 File 객체로 접근합니다

    File 객체는 Blob을 확장한 형태 (=파일 이름과 수정일 정보가 추가된 Blob 객체) 입니다

    그러므로 File 객체는 Blob 객체와 동일한 메소드와 프로퍼티를 가지며, 추가적으로 파일 이름과 변경 날짜와 같은 파일 정보에 접근할 수 있습니다.

    <input type="file" id="fileInput">
    let fileInput = document.getElementById('fileInput');
    fileInput.addEventListener('change', function(e) {
        let file = e.target.files[0];  // File 객체를 가져옵니다.
        // 이제 file 객체를 Blob 객체처럼 사용할 수 있습니다.
    });



File 객체란?


  • 메모리에 있는 데이터를 참조합니다.

  • 로컬 파일을 참조하는 Blob객체 입니다.

  • 로컬 파일을 읽거나 쓸 수 있습니다.


위에서 언급했듯이 File 객체는 Blob 객체를 상속받은 객체입니다.

Blob 객체의 프로퍼티와 메서드 외에도 전용 프로퍼티 또한 존재합니다

프로퍼티설명
lastModifiedFile 객체가 마지막으로 수정된 날짜 (단위는 밀리초)
lastModifiedDateFile 객체가 마지막으로 수정된 날짜(Data 객체)
nameFile 객체가 가리키는 파일의 이름

로컬 파일을 File 객체로 불러들이는 방법

  1. type = "file" 속성을 지정한 input 요소를 불러오는 방법

    <input type="file" id="fileInput">
    let fileInput = document.getElementById('fileInput');
    fileInput.addEventListener('change', function(e) {
        let file = e.target.files[0];  // File 객체를 가져옵니다.
        // 이제 file 객체를 Blob 객체처럼 사용할 수 있습니다.
    });

    input 요소로 선택한 File 객체는 input요소 객체의 files 프로퍼티에 저장됩니다.

    files 프로퍼티는 File 객체의 배열입니다.

    Input 요소에 multiple 속성을 지정하면 사용자가 Shift를 눌렀을때 파일 여러개를 선택할 수 있습니다.

    <input type="file" multiple>

    input요소에 accept속성에는 선택할 수 있는 파일 유형을 MIME 타입으로 설정할 수 있습니니다.

    <input type="file" accept="image/*"> 
  2. 드래그 앤 드롭으로 불러들이기

    파일을 드래그해서 다른 요소에 드롭하면 파일 정보를 드롭타깃 요소에 전달 할 수있습니다.

    드래그 앤 드롭으로 드래그한 파일을 File 객체는 이벤트 객체의 DataTransfer 프로퍼티 안에 있는 files 프로퍼티에 저장됩니다.

    element.ondrop = function(e){
    	let files = e.dataTrnasfer.files;
    	....
    };



Blob에서 객체 URL을 반환하기

URL.createObjectURL() , URL.revokeObjectURL() 메소드를 사용하면 됩니다

  • URL.createObjectURL()

    Blob 객체나 File 객체를 사용하여 생성한 URL을 반환합니다

    이 URL은 브라우저에서만 접근 가능하며 브라우저에서 해당 객체의 데이터에 접근할 수 있습니다

    이 주소를 사용하여 웹 페이지의 이미지, 다운로드 링크 등에 접근할 수 있게 됩니다
    예를 들어, 이 메소드를 사용해 이미지 Blob의 URL을 생성하면,
    이 URL을 <img> 태그의 src 속성에 설정해 브라우저에서 이 이미지를 표시할 수 있습니다

    let blob = new Blob(['Hello, world!'], {type : 'text/plain'});
    let url = URL.createObjectURL(blob);
    
    // "blob:http://example.com/12345678-1234-1234-1234-123456789abc"
    // 와 같은 형태의 URL을 출력합니다.
    console.log(url);
  • URL.revokeObjectURL()

    URL.createObjectURL() 메소드에 의해 생성된 URL을 해제합니다

    이 메소드를 호출하면 해당 URL은 더 이상 해당 객체의 데이터를 참조하지 않게 되며,

    이 URL을 통해 데이터에 접근하는 것은 불가능해집니다

    이 메소드는 더 이상 필요하지 않은 URL을 정리하고, 브라우저의 메모리를 효율적으로 관리하는 데 사용됩니다

    // Blob 생성자를 사용해서 data 변수 텍스트 파일의 blob 객체를 저장
    const data = new Blob(["blablabla"], { type: "text/plain" });
    
    // Blob 객체에 대한 URL 생성
    const url = URL.createObjectURL(data);
    
    // 생성된 URL을 사용하여 웹 페이지의 다운로드 링크 설정
    const downloadLink = document.createElement("a");
    downloadLink.href = url;
    downloadLink.download = "example.txt";
    document.body.appendChild(downloadLink);
    
    // 필요한 작업 완료 후 URL 해제
    URL.revokeObjectURL(url);

위의 개념들을 바탕으로 실제 개인 프로젝트에 적용한 예시입니다

  • axios에서 기본적으로 responseType을 지원하므로 blob객체 형태로 반환받고
  • 받은 blob 데이터를 URL.createObjectURL()을 사용하여 URL로 변환해서 리턴 합니다
  • 그리고 이 리턴값을 img태그의 src속성 값으로 사용해서 웹에서 이미지를 띄웁니다
// getActionImg 는 클래스 내부의 메소드로 선언된 변수입니다

getActionImg = async (spid: number): Promise<String> => {
    const result = await axios.get(`live/externalAssets/common/playersAction/p${spid}.png`, {
      headers: {
        Authorization: import.meta.env.REACT_APP_API_KEY_FIFA,
      },
      responseType: 'blob',
    });

    const imgUrl = URL.createObjectURL(result.data);
    return imgUrl;
  };

이미지가 제대로 나옵니다




Blob에서 데이터 읽어들이기

가장 유명한 방법은 바로 FileReader를 사용하는 것입니다
FileReader를 사용하는 방법에 대해선 아래 링크에 작성한 설명을 참조하세요

Base64 , Data URL , FileReader 에 대해...





(혹시 헷갈릴까봐)

Blob의 데이터를 읽는데 Base64로 인코딩을 하는데 사용되는 FileReader를 사용한다고?

그렇다면 Blob객체와 base64의 관계는 무엇일까?


  • Blob 객체는 큰 이진 데이터를 처리하는 데 사용되는 JavaScript 객체입니다. 이미지, 비디오, 오디오 파일 등의 데이터를 Blob 객체로 관리할 수 있으며 주로 웹 브라우저에서 파일을 다루는 데 사용됩니다.

  • Base64는 바이너리 데이터를 문자열로 표현하는 인코딩 방식입니다. 이 방식은 텍스트 형식만 처리할 수 있는 시스템에서 이미지같은 바이너리 데이터를 안전하게 전송하기 위해 사용됩니다.


웹 브라우저에서 이미지나 비디오 같은 파일을 다룰 때, 이 파일들은 Blob 객체로 처리됩니다.

이 Blob 객체는 원시 바이너리 데이터를 포함하고 있습니다.

그러나, 이 바이너리 데이터를 그대로 전송하거나 저장하는 것은 어렵기 때문에 Base64 인코딩 방식이 사용되는 것입니다

그리고 그 Base64의 인코딩 방식을 사용하기 위해 FileReader 의 메소드를 사용하는 것입니다


그러므로 Blob 객체와 Base64는 웹 브라우저에서 파일을 안전하게 다루는 데 함께 사용되는 것입니다

Blob 객체는 파일 데이터를 관리하는 데 사용되며,

Base64는 이 데이터를 안전하게 전송하거나 저장하는 데 사용되는 것입니다




URL.createObjectURL() VS FileReader의 메소드 둘 중 뭘 사용해야 할까?

Blob에서 객체 URL을 반환하는 URL.createObjectURL() 과

Blob에서 데이터를 직접 읽는 FileReader의 메소드 둘 다

Blob객체를 다룬다는 맥락은 동일한데 둘 중 뭘 사용해야 할까요?


이들의 사용 목적과 방식에는 몇 가지 중요한 차이점이 있습니다



FileReader 객체는 Blob 객체나 파일의 내용을 읽어서 이를 사용할 수 있게 하는 API입니다.

그러므로 파일의 내용을 직접 읽어서 처리하는 데 사용됩니다

그렇지만 파일의 내용을 전부 읽은 후에야 결과를 반환하므로, 큰 파일을 처리할 때는 비효율적일 수 있으므로

작은 파일의 내용을 , 직접 읽어서 처리해야 하는 경우에는 FileReader를 사용합니다




URL.createObjectURL() 는 Blob 객체나 파일의 내용을 직접 읽지 않고,

파일을 직접 읽지 않고, 브라우저가 필요한 시점에 해당 파일을 참조하는 URL을 생성합니다

따라서 URL.createObjectURL() 메소드는 FileReader에 비해 더 효율적으로 큰 파일을 처리할 수 있습니다.

또한 브라우저가 파일의 데이터를 필요한 시점에 자동으로 읽어오므로, 이를 처리하는 코드가 간단해집니다.

예를 들어 <img> 태그의 src 속성 같은 곳에 URL을 직접 연결할 수 있는 것이며 , 큰 파일을 효율적으로 처리할때 사용됩니다

그렇지만 , 파일의 데이터를 직접 다루지 않기 때문에

파일의 내용을 분석하거나 수정하는 등의 작업을 수행하려면 FileReader 객체를 사용해야 합니다.

예를 들어, 텍스트 파일의 내용을 읽어서 이를 분석하거나 변환해야 하는 경우, FileReader 객체를 사용해 파일의 데이터를 직접 읽어와야 합니다.




참고 :

Blob - Web API | MDN

[Javascript] API 활용 - Blob

profile
웰시코기웰시코기웰시코기

0개의 댓글