- base64 데이터를 이미지로 변환하여 화면에 띄우기 -
일단 xhr 을 호출하여 서버로부터 데이터를 받아온다.
이때 데이터는 base64 문자열이다.
이 base64 문자열을 이미지 파일로 변환하여 화면에 띄우는 방법은 여러 가지가 있다.
여기서는 총 3가지 방법을 보려고 한다.
1. base64 문자열을 그대로 src 속성에 박아버리기
2. base64 문자열을 파일로 변환하여 참조 url 을 생성하기
3. base64 문자열을 blob 으로 변환하여 참조 url 을 생성하기
- Base64란? -
데이터를 64진법 문자로 인코딩하거나 디코딩하는 방식이다.
컴퓨터에서 다루는 모든 데이터는 0과 1로 이루어진 조합이다.
0과 1들을 모아서 그 데이터들을 어떻게 해석할지 데이터 타입이 바뀔 뿐이다.
문자열로 해석할지, 배열로 해석할지, 이미지로 해석할지에 따라 바뀐다.
이미지 파일도 결국 0과 1들이 모여 있는 조합이다.
이 데이터 덩어리를 통째로 들고다니기에는 무겁다.
메모리에 0과 1로 조합된 이미지 파일 데이터는 그대로 두고서
평소에는 그 이미지 파일을 가리키는 주소만 가지고 연산을 한다.
이게 '변수'라는 개념을 사용하는 원리이고 이유이다.
그런데 연산 주체가 바뀌면 데이터를 통째로 옮길 수밖에 없다.
내 컴퓨터 메모리에서 들고 있는 이미지를 내 컴퓨터가 아니라 다른 사람 컴퓨터에 띄우려고 해보자.
0과 1로 조합된 이미지 데이터를 어쨌든 그 사람 컴퓨터 메모리로 옮겨놓아야 한다.
그런데 0과 1로 조합된 데이터 그 자체를 그대로 통째로 옮기려면 비효율적이다.
옮기는 과정에서 훼손될 위험도 높다.
이때 자주 쓰는 방식이 base64이다.
0과 1로 조합된 데이터를 미리 약속된 문자 64개로 바꿔서 주고 받는다.
이때 컴퓨터끼리 데이터를 주고 받아도 운영체제마다 공통적으로 쓰는 문자열이기 때문에 호환도 되고 손실될 위험도 낮아진다.
- 1. base64 문자열을 그대로 src 속성에 박아버리기 -
첫 번째 방식은 이 base64 데이터를 그대로 src에 박아버리는 방법이다.
src 속성 안에 이 이미지 데이터를 통째로 넣어두는 방법이다.
한 번 쓰고 버리는 이미지라면 오히려 이게 간편할 수도 있다.
그러나 똑같은 이미지를 여러 군데에서 쓰려면 비효율적이다.
이곳 저곳에서 똑같은 데이터를 들고 있으므로 메모리가 낭비된다.
그래서 두 번째 방법을 쓴다.
// 넘어오는 데이터를 그대로 src에 박아서 document에 띄움
function xhrCallback1(xhrResponse) {
const response = xhrResponse.currentTarget.response;
const targetImg = document.querySelector("img#result");
targetImg.src = "data:image/;base64,"+response;
}
- 2. base64 문자열을 파일로 변환하여 참조 url 을 생성하기 -
앞에서 설명했던 '변수'라는 개념을 사용하는 원리와 같은 원리다.
일단 base64 데이터를 이미지 파일로 변환한다.
그리고 이 이미지 파일을 가리키는 url 을 임시로 생성한다.
문서 안에서 이 이미지를 사용하려면 url 만 가지고 연산하면 된다.
이미지 파일을 만드는 그 큰 데이터를 통째로 들고다닐 필요가 없다.
이미지 파일은 이미 만들어서 브라우저 메모리에 올려두었다.
그리고 그 파일을 가리키는 url 만 가지고 연산하기로 한다.
이미지 src 속성에는 임시로 만들어 둔 이 url 만 넣어주면 된다.
단 이 url 은 문서 안에서 임시로 만들어둔 변수이기 때문에 다른 문서로 옮겨가면 쓸 수 없게 된다.
이에 따라서 더 이상 사용하지 않을 때는 revoke 해줘야 한다.
// base64 string 을 파일 객체로 만들어서 img 요소에 렌더링하기
function xhrCallback2(xhrResponse) {
// base64 string 을 파일 객체로 만들어서 img 요소에 렌더링하기
const response = xhrResponse.currentTarget.response;
const bstr = atob(response);
let len = bstr.length;
const u8arr = new Uint8Array(len);
while(len > 0) {
len--;
u8arr[len] = bstr.charCodeAt(len);
}
//
const tempFile = new File([u8arr], "tempFile", {type: "image/png"});
const tempUrl = Window.URL.createObjectUrl(tempFile);
const targetImg = document.querySelector("img#result");
targetImg.src = tempUrl;
}
- 3. base64 문자열을 blob 으로 변환하여 참조 url 을 생성하기 -
3번 방법은 사실상 2번 방법과 거의 똑같다.
JavaScript 에서 File 객체는 Blob 을 상속하여 확장한 개념이다.
그냥 base64 를 JavaScript 에서 사용하는 객체로 변환하는 과정을 여러 가지 로직으로 표현해보고자 추가한 정도다.
// base64 string 을 blob 객체로 변환해서 img 렌더링하기
function xhrCallback3(xhrResponse) {
// base64 string 을 blob 객체로 변환해서 img 렌더링하기
const response = xhrResponse.currentTarget.response;
const byteCharacters = atob(response);
const byteArrays = [];
const sliceSize = 512;
for(let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const sliced = byteCharacters.slice(offset, offset+sliceSize);
const byteNumbers = new Array(sliced.length);
for(let i=0; i<sliced.length; i++) {
byteNumbers[i] = sliced.charCodeAt(i);
}
}
//
const tempBlob = new Blob(byteArrays, {type: "image/png"});
const tempUrl = window.URL.createObjectUrl(tempBlob);
const targetImg = document.querySelector("img#result");
targetImg.src = tempUrl;
}
- ArrayBuffer 란? -
이미지나 동영상, 소리 등 큰 데이터는 한 번에 주고 받기 어렵다.
통신할 때는 잘게 쪼개서 조각 조각 주고 받는다.
메모리에서 다룰 때도 이렇게 잘게 쪼갠 조각들을 단위로 다루어야 할 때가 있다.
JavaScript 에서는 이럴 때 쓰려고 ArrayBuffer 라는 개념이 있다.
메모리에 일정한 크기를 단위로 연결된 데이터 모음이다.
Array 라는 이름은 JavaScript 에서 쓰는 그 '배열'이 아니다.
메모리상에 데이터들을 일정한 크기로 엮어두어서 array 로 부르는 것이다.
blob 데이터를 다룰 때는 이 ArrayBuffer 를 사용한다.
Uint8Array / Uint16Array / Uint32Array / Float64Array 등이 있다.
- 250116
// 참고 사이트
https://velog.io/@hyerin0930/Base64-Blob-ArrayBuffer-File-개념-알아보기
https://inpa.tistory.com/entry/JS-%F0%9F%93%9A-Base64-Blob-ArrayBuffer-File-%EB%8B%A4%EB%A3%A8%EA%B8%B0-%EC%A0%95%EB%A7%90-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-%EC%89%BD%EA%B2%8C-%EC%84%A4%EB%AA%85
https://jw910911.tistory.com/119
'JavaScript' 카테고리의 다른 글
| [JavaScript] hex 문자열로 받은 데이터를 이미지로 띄우기 (0) | 2025.01.30 |
|---|---|
| [JavaScript] HTML 요소 안에서 inline 으로 이벤트 걸어줄 때 이벤트 객체 받아오기 (0) | 2025.01.30 |
| [JavaScript] 목록 채우기 - 퍼블리싱이 적용된 템플릿을 복사하여 채우기 (0) | 2025.01.30 |
| [JavaScript] XMLHttpRequest 로 URL 호출해서 팝업창 띄우기 (0) | 2025.01.30 |
| [JavaScript] 숫자만 입력 가능한 정규식 조건 만들기 (0) | 2023.04.11 |