Language/JavaScript (WEB)

๐Ÿ“ Base64 / Blob / ArrayBuffer / File ๋‹ค๋ฃจ๊ธฐ ์ด์ •๋ฆฌ

์ธํŒŒ_ 2022. 7. 21. 13:00

Base64-Blob-ArrayBuffer

์›น ๊ฐœ๋ฐœ์„ ์ง„ํ–‰ํ•˜๋‹ค ๋ณด๋ฉด ์ด์ง„ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ์–ด์•ผ ํ•  ๋•Œ๋ฅผ ๊ฐ„ํ˜น ๋งˆ์ฃผ์น  ์ˆ˜ ์žˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์—์„  ์ฃผ๋กœ ํŒŒ์ผ ์ƒ์„ฑ, ์—…๋กœ๋“œ, ๋‹ค์šด๋กœ๋“œ ๋˜๋Š” ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ์™€ ๊ด€๋ จ์ด ๊นŠ๊ณ , ์„œ๋ฒ„ ์‚ฌ์ด๋“œ์ธ node.js ์—์„  ํŒŒ์ผ ๋ถ€ํ„ฐ ๋ฒ„ํผ ๊นŒ์ง€ ์›์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๋Š” ์ƒํ™ฉ์ด ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ํ‰์†Œ์— ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํ•˜๋ฉด์„œ ์ง์ ‘ ์ด์ง„ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๋Š” ์ผ์€ ๋ณ„๋กœ ์—†๋‹ค. ๊ณ ๊ธ‰ ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•ด ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ๋žŒ์ด ์ฝ์„์ˆ˜์žˆ๋Š” ์ž์—ฐ์–ด๋กœ ์ฝ”๋”ฉํ•ด๋‘๋ฉด, ๋‚ด๋ถ€์ ์œผ๋กœ ํ”„๋กœ๊ทธ๋žจ์ด ์•Œ์•„์„œ ์ด์ง„ ๋ฐ์ดํ„ฐ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์ฝ๊ณ  ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ํ•˜์ง€๋งŒ ์ •์ˆ˜, ์‹ค์ˆ˜, ๋ฌธ์ž๊ฐ€ ์•„๋‹Œ ํŒŒ์ผ์ด๋‚˜ ์ด๋ฏธ์ง€, ๋น„๋””์˜ค ๊ฐ™์€ ๋ฉ€ํ‹ฐ๋ฏธ๋””์–ด ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ์–ด์•ผ ํ• ๋•Œ๋Š” ๋‚œ๊ฐํ•ด์ง„๋‹ค.

์ด ๋ฉ€ํ‹ฐ๋ฏธ๋””์–ด ๋ฐ์ดํ„ฐ๋ฅผ ์ •์ˆ˜, ๋ฌธ์ž ๋‹ค๋ฃจ๋“ฏ์ด ํ•ด์•ผ๋˜๋Š”๋ฐ ์ด์ง„ ๋ฐ์ดํ„ฐ๋ฅผ 0๊ณผ 1๋กœ ๋‹ค๋ฃฐ์ˆ˜์žˆ๋Š” ๊ฒƒ๋„ ์•„๋‹ˆ๊ณ  ์–ด๋–ป๊ฒŒ ํ• ๊นŒ

 

์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” ํ•œ๋ฒˆ์ฏค IT์—…๊ณ„์— ์ข…์‚ฌํ•ด๋ดค์œผ๋ฉด ๋“ค์–ด๋ณธ binary, base64, blob, arraybuffer, buffer, file ํƒ€์ž…์— ๋Œ€ํ•ด์„œ ๊ฐœ๋…์„ ์•Œ์•„๋ณด๊ณ  ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ์ง€์›ํ•˜๋Š” ๋‚ด์žฅ ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด ์ด๋ฏธ์ง€ ๋ฉ€ํ‹ฐ๋ฏธ๋””์–ด ํŒŒ์ผ์„ ์–ด๋–ค ๋ฌธ๋ฒ•์„ ์ด๋“ค์„ ๋ณ€ํ™˜ํ•˜๊ณ  ์ด์šฉํ• ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์•„๋ณด๋Š” ์‹œ๊ฐ„์„ ๊ฐ€์ ธ๋ณผ ๊ฒƒ์ด๋‹ค.


Binary

์—ฌ๋Ÿฌ๋ถ„๋„ ์•„์‹œ๋‹ค์‹ถ์ด, ์ปดํ“จํ„ฐ๋Š” ์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ 0๊ณผ 1๋กœ ์ €์žฅํ•œ๋‹ค.

Binary(๋ฐ”์ด๋„ˆ๋ฆฌ)๋ž€ ์ด์ง„ ๋ฐ์ดํ„ฐ๋ฅผ ์˜๋ฏธํ•˜๋ฉฐ, '1'๊ณผ '0'๋งŒ์„ ์‚ฌ์šฉํ•˜์—ฌ 2๊ฐœ์˜ ์ˆ˜๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ง„๋ฒ•์„ ๋œปํ•˜๋Š”, ์ปดํ“จํ„ฐ(ํ”„๋กœ๊ทธ๋ž˜๋ฐ)์„ ๋‹ค๋ฃจ๋Š”๋ฐ ์žˆ์–ด ๊ฐ€์žฅ ๊ทผ๋ณธ์ด ๋˜๋Š” ์ฒด๊ณ„๋ผ๊ณ  ๋ณผ์ˆ˜ ์žˆ๋‹ค.

Base64-Blob-ArrayBuffer


Base64

์ปดํ“จํ„ฐ๋Š” ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ 0๊ณผ 1๋กœ ์ €์žฅํ•œ๋‹ค๊ณ  ๋งํ–ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์ง€๊ธˆ ๋ณด๊ณ  ์žˆ๋Š” ๋ธŒ๋ผ์šฐ์ € ์—ญ์‹œ 0๊ณผ 1๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋Š” ๊ฒƒ์ด๋ฉฐ ํด๋”๋‚˜ ํŒŒ์ผ ์—ญ์‹œ ์ด์ง„ ๋ฐ์ดํ„ฐ๋กœ ์ด๋ฃจ์–ด์ง„ ๊ฒƒ์ด๋‹ค.

๊ทธ๋Ÿผ ์ปดํ“จํ„ฐ ์•ˆ์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๊บผ๋‚ด ์“ฐ๊ณ  ์‹ถ์„๋•Œ ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ?

์šฐ๋ฆฌ๊ฐ€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ๋ฐฐ์šฐ๋Š” ๋ณ€์ˆ˜ ๊ฐœ๋…์ด ๋ฐ”๋กœ ์ด ๊ฐœ๋…์ด๋‹ค. ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ๋œ 0๊ณผ 1๋กœ ์ด๋ฃจ์–ด์ง„ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€์ˆ˜์— ์ ์žฌํ•ด๋†“๊ณ , ํ•„์š”ํ•˜๋ฉด ์šฐ๋ฆฌ๋Š” ๋ณ€์ˆ˜๋ฅผ ๋ถˆ๋Ÿฌ ๋ง์…ˆ, ๋บ„์…ˆ์„ ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์ปดํ“จํ„ฐ ์•ˆ์˜ ์ด์ง„ ๋ฐ์ดํ„ฐ(๋ฐ”์ด๋„ˆ๋ฆฌ)๋ฅผ ๋‹ค๋ฃจ๊ณ  ์žˆ์—ˆ๋˜ ๊ฒƒ์ด๋‹ค.

์ˆซ์ž๋‚˜ ์ŠคํŠธ๋ง์ด ์•„๋‹Œ, ์ด๋ฏธ์ง€๋‚˜ ๋น„๋””์˜ค ๊ฐ™์€ ๋ณต์žกํ•œ ๋ฉ€ํ‹ฐ๋ฏธ๋””์–ด ํŒŒ์ผ๋“ค์€ ์–ด๋–ป๊ฒŒ ๋ณ€์ˆ˜์— ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ• ๊นŒ?

๋ณ€์ˆ˜์— ์ด๋ฏธ์ง€ url์„ ์ €์žฅํ•˜๋Š”๊ฑด ๋งํฌ๋ผ๋Š” ์ง•๊ฒ€๋‹ค๋ฆฌ๋ฅผ ์ €์žฅํ•˜๋Š”๊ฑฐ์ง€ ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ ๊ทธ ์ž์ฒด๋ฅผ ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค.

์ด๋•Œ ๋“ฑ์žฅํ•˜๋Š” ๊ฒƒ์ด Base64 ๋ผ๋Š” ๊ฐœ๋…์ด๋‹ค. Base64๋Š” 0๊ณผ 1๋กœ ์ด๋ฃจ์–ด์ง„ ์ด์ง„ ๋ฐ์ดํ„ฐ(๋ฐ”์ด๋„ˆ๋ฆฌ)๋ฅผ ์ธ์ฝ”๋”ฉํ•˜์—ฌ ํ…์ŠคํŠธ ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค.

Base64-Blob-ArrayBuffer

 

์˜ˆ๋ฅผ๋“ค์–ด ์•„๋ž˜ ์‚ฌ์ง„๊ณผ ๊ฐ™์ด ์‹ค์ œ html์— img์˜ src์— ์ด๋ฏธ์ง€ url์ด ์•„๋‹Œ ์ˆซ์ž์™€ ๋ฌธ์ž๋กœ ๊ตฌ์„ฑ๋œ ๊ธด ์ฝ”๋“œ(data:image/png;base64)๊ฐ€ ๋“ค์–ด๊ฐ„ ๊ฒฝ์šฐ๋ฅผ ๋ณธ์ ์ด ์žˆ์„ ํ…๋ฐ ์ด๊ฒƒ์ด ๋ฐ”๋กœ base64 ์ด๋‹ค. 0๊ณผ 1๋กœ ์ด๋ฃจ์–ด์ง„ ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ ์ž์ฒด๋ฅผ base64 ํ…์ŠคํŠธ ๊ธฐ๋ฐ˜ ํฌ๋งท์œผ๋กœ ๋ณ€ํ™˜ํ•ด์คŒ์œผ๋กœ์„œ ์šฐ๋ฆฌ๊ฐ€ ์ง์ ‘ ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃฐ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

Base64-Blob-ArrayBuffer

์‰ฝ๊ฒŒ ์ดํ•ดํ•ด ๋ณด์ž๋ฉด, ๋งŒ์ผ ์šฐ๋ฆฌ๊ฐ€ ์†Œ์Šค ์ฝ”๋“œ๋‹จ์— ์ด๋ฏธ์ง€๋ฅผ ๋ถˆ๋Ÿฌ์™€ ๋‹ค๋ฃจ์–ด์•ผ ํ•œ๋‹ค๊ณ  ํ•˜์ž.

๋ณดํ†ต์ด๋ผ๋ฉด, ๋งํฌ๋ฅผ ํ†ตํ•ด ๋ถˆ๋Ÿฌ์˜ค๊ฑฐ๋‚˜ ํ˜น์€ ๋กœ์ปฌ ํด๋”์— ์ €์žฅ๋˜์–ด์žˆ๋Š” ์ด๋ฏธ์ง€ ํŒŒ์ผ์„, ์ฝ”๋“œ์—์„œ ์ œ๊ณตํ•˜๋Š” ํŒŒ์ผ์‹œ์Šคํ…œ์„ ํ†ตํ•ด ์ƒ๋Œ€๊ฒฝ๋กœ๋กœ ๋ถˆ๋Ÿฌ์™€ ๋‹ค๋ค„๋ณธ ๊ฒฝํ—˜์ด ์žˆ์„ ๊ฒƒ์ด๋‹ค. ํ•˜์ง€๋งŒ ํŒŒ์ผ๋„ ๊ฒฐ๊ตญ url๊ณผ ๊ฐ™์ด OS์— ์ €์žฅ๋œ ์ง•๊ฒ€๋‹ค๋ฆฌ๋ฅผ ๋ถˆ๋Ÿฌ์˜จ ๊ฒƒ ๊ณผ ๋‹ค๋ฆ„์ด ์—†๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ base64๋กœ ๋ณ€ํ™˜ํ•ด์ฃผ๋ฉด ์šฐ๋ฆฌ๊ฐ€ ์ง์ ‘ ์†Œ์Šค ์ฝ”๋“œ๋‹จ์— ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ ์ž์ฒด๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ๋ณ€์ˆ˜์— ๋ฌธ์ž์—ด์ด๋‚˜ ์ˆซ์ž๋ฅผ ์ €์žฅํ•˜๋Š” ๊ฒƒ ์ฒ˜๋Ÿผ, ๋ณ€์ˆ˜์— ์ด๋ฏธ์ง€๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

base64๋Š” ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ ๊ฐ’์„ ๋ณ€ํ™˜ํ•˜๋Š”๊ฒŒ ์•„๋‹Œ ๊ทธ๋ƒฅ ์ถœ๋ ฅ ํ˜•์‹์„ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฏธ์ง€ ์ž์ฒด๊ฐ€ ๋ฐ”๋€Œ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ˆ ๊ฐ€๋Šฅํ•œ ๊ฒƒ์ด๋‹ค. ์ฆ‰, ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ ์ •๋ณด๋Š” ์ด๋ฏธ base64 ํ…์ŠคํŠธ ์ž์ฒด์— ํฌํ•จ๋˜์–ด ์žˆ๊ธฐ๋•Œ๋ฌธ์—, ๊ฒฐ๊ณผ์ ์œผ๋กœ ๋งํฌ url์„ ํ†ตํ•ด  ์„œ๋ฒ„์— ์š”์ฒญํ•˜์ง€ ์•Š๊ณ ๋„ ์ง์ ‘ ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. (์†Œ์Šค ์ฝ”๋“œ ๋‹จ์— ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋˜์–ด ์žˆ๋Š” ํ˜•ํƒœ ์ด๋‹ˆ๊นŒ!)

 

๋ณดํ†ต ์œ„์™€ ๊ฐ™์ด html์—์„œ ์ง์ ‘ base64 ์ด๋ฏธ์ง€ ํฌ๋งท์„ ๋‹ค๋ฃจ๋Š” ๊ฒฝ์šฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • ํฌ๊ธฐ๊ฐ€ ์ž‘์€ ์ด๋ฏธ์ง€๋ฅผ url์ด๋‚˜ ํŒŒ์ผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ฒƒ ์—†์ด html์— ์ง์ ‘ ์‚ฝ์ž…ํ•˜๋Š” ๊ฒฝ์šฐ
  • ๊ฐ„๋‹จํ•œ ํŽ˜์ด์ง€๋ฅผ ์ž‘์„ฑํ•ด ์ž„์‹œ๋กœ ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ
  • ์ด๋ฏธ์ง€๊ฐ€ ๋“ค์–ด๊ฐ„ ๋ฉ”์ผ ๋‚ด์šฉ์„ html์œผ๋กœ ์ž‘์„ฑํ•ด์„œ ๋ณด๋‚ด๋Š” ๊ฒฝ์šฐ

Base64-Blob-ArrayBuffer
์ด๋ฏธ์ง€ ๊ฐ™์€ ํŒŒ์ผ์„ ๋ฌธ์„œ (Html, JS, CSS) ์— ์ธ๋ผ์ธ์œผ๋กœ ์ž‘์„ฑํ•˜์—ฌ ์‚ฌ์šฉ

 

์ด๋ ‡๊ฒŒ base64๋กœ ๋ณ€ํ™˜ํ•˜๋ฉด ์ง์ ‘ ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ๋‹ค๋ฃฌ๋‹ค๋Š” ํŠน์ง•๋„ ์žˆ์ง€๋งŒ, ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ๋ฅผ ํ…์ŠคํŠธ๋กœ ๋ฐ”๊พธ๋Š” 64์ง„๋ฒ• ์ธ์ฝ”๋”ฉ์„ ํ†ตํ•ด, ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ ๋Œ€๋น„ 33%์˜ ๋ฐ์ดํ„ฐ์˜ ์–‘ ์ฆ๊ฐ€ํ•˜๊ฒŒ ๋œ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฐ์ดํ„ฐ์˜ ๊ธธ์ด๊ฐ€ ์ฆ๊ฐ€ํ•จ์—๋„, Base64๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฐ€์žฅ ํฐ ์ด์œ ๋Š” ์•ž์„œ ์†Œ๊ฐœํ•˜๋“ฏ์ด Binary ๋ฐ์ดํ„ฐ๋ฅผ ํ…์ŠคํŠธ ๊ธฐ๋ฐ˜ ๊ทœ๊ฒฉ์œผ๋กœ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋˜ํ•œ ์ˆœ์ˆ˜ ๋ฐ”์ด๋„ˆ๋ฆฌ ํ˜•์‹์œผ๋กœ ๋‚จ์•„์žˆ๋Š”๋ณด๋‹ค ์ „์†ก/์ €์žฅ์ด ํ›จ์”ฌ ์‰ฝ๋‹ค๋Š” ์ ๋„ ๊ผฝ์„ ์ˆ˜ ์žˆ๋‹ค. (์ด์ง„ ๋ฐ์ดํ„ฐ๋Š” ์†์ƒ๋  ํ™•๋ฅ ์ด ๋†’๋‹ค)

์ธ์ฝ”๋”ฉ ํ• ์‹œ, ๋ฌธ์ž ํฌ๋งท์„ A-Z,a-z,0–9,/+ ๋งŒ์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋ฌธ์ž ํฌ๋งท์ด ๋‹ฌ๋ผ ๋ฐ์ดํ„ฐ๋ฅผ ์†์ƒ์‹œํ‚ฌ ์ˆ˜์žˆ๋Š” ์‹œ์Šคํ…œ ๊ฐ„์—๋„ ์•ˆ์ •์ ์œผ๋กœ ์ „์†ก ๋  ์ˆ˜ ์žˆ๋‹ค.

 

์ง€๊ธˆ๊นŒ์ง€์˜ base64 ํฌ๋งท์— ๋Œ€ํ•ด ์ •๋ฆฌํ•˜์ž๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • ๋ณ„๋„ ์ด๋ฏธ์ง€ ํŒŒ์ผ์ด ํ•„์š”์—†๋‹ค. ์™œ๋ƒํ•˜๋ฉด base64 ๋ฐ์ดํ„ฐ ์ž์ฒด๊ฐ€ ์ด๋ฏธ์ง€์ด๊ธฐ ๋•Œ๋ฌธ.
  • ๋ธŒ๋ผ์šฐ์ € ๋ Œ๋”๋ง์‹œ, ๋ฌธ์„œ๋กœ๋”ฉ๊ณผ ๊ฐ™์ด ๋กœ๋”ฉ ๋˜๊ธฐ์— ๋Š๊ธฐ์ง€ ์•Š๊ณ  ๋ถˆ๋Ÿฌ์˜จ๋‹ค. ๋˜ํ•œ ๋„คํŠธ์›Œํฌ๊ฐ€ ์ข‹์ง€์•Š์•„๋„ ์œ„์™€ ๊ฐ™์€ ํŠน์ง•์œผ๋กœ ์ด๋ฏธ์ง€๋ฅผ ๋กœ๋”ฉํ• ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ๋„ ์žˆ๋‹ค.
  • ๋ฌธ์ž์—ด์ด ๋งค์šฐ๋งค์šฐ ๊ธธ๊ธฐ์— ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์ง„๋‹ค.
  • Base64 ์ธ์ฝ”๋”ฉ์„ ์‚ฌ์šฉํ•˜๋ฉด ์›๋ณธ๋ณด๋‹ค 33%์˜ ์šฉ๋Ÿ‰์ด ์ปค์ ธ์„œ, ๋‚จ์šฉํ• ๊ฒฝ์šฐ ์˜คํžˆ๋ ค ๋กœ๋”ฉ ์†๋„๊ฐ€ ์ €ํ•˜๋  ์ˆ˜ ์žˆ๋‹ค.

์ด๋ฏธ์ง€ URL์„ base64๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ

base64 ๊ฐœ๋… ์ด๋ก ์— ๋Œ€ํ•ด ์•Œ์•˜์œผ๋‹ˆ ์ด์ œ ์ง์ ‘ ์‹ค์ œ๋กœ ๋‹ค๋ค„๋ณด์ž.

 

์ธ์ฝ”๋”ฉ ์‚ฌ์ดํŠธ ์ด์šฉ

๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์€ ์•„๋ž˜์˜ ์˜จ๋ผ์ธ ์‚ฌ์ดํŠธ๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋ฏธ์ง€๋ฅผ ์—…๋กœ๋“œ ํ•˜๋ฉด ๋ณ„๋‹ค๋ฅธ ์ž‘์—… ์—†์ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด base64 ๋กœ ๋ณ€ํ™˜ํ•ด์ค€๋‹ค.

 

Base64 Image Encoder - Convert any image file or URL online

With Base64 Image Encoder, you can convert any image file or URL to either Base64, HTML, CSS, JSON, or XML online. Everything happens in the browser.

elmah.io

Base64-Blob-ArrayBuffer

 

ํ”„๋กœ๊ทธ๋ž˜๋ฐ

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋ฅผ ์ด์šฉํ•ด ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

๋จผ์ € fetch api๋กœ ์ด๋ฏธ์ง€๋ฅผ ์ฝ์–ด๋“ค์ด๊ณ , ์ด๋ฏธ์ง€๋ฅผ blob ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  FileReader ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด blob ๋ฐ์ดํ„ฐ๋ฅผ base64 ํ˜•์‹์œผ๋กœ ์ฝ์–ด๋“ค์–ด ๋ณ€ํ™˜์‹œํ‚จ๋‹ค. (blob์€ ๋ฐ”๋กœ ๋’ค์—์„œ ๋ฐฐ์šด๋‹ค)

FileReader๋Š” Blob ๋˜๋Š” File๊ณผ ๊ฐ™์€ ์ž๋ฃŒํ˜• ๊ฐ์ฒด๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด ๋“ค์ด๊ธฐ์œ„ํ•œ ๋ชฉ์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ฐ์ฒด์ด๋‹ค.
์ฝ์–ด๋“ค์ธ ๋ฐ์ดํ„ฐ๋Š” ์ฃผ๋กœ ์ด๋ฒคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•„์š”ํ•œ ํƒ€์ด๋ฐ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•œ๋‹ค. (๋ฐ‘์—์„œ ์ž์„ธํžˆ ๋ฐฐ์šด๋‹ค)
(async () => {
    const data = await fetch('https://play-lh.googleusercontent.com/hYdIazwJBlPhmN74Yz3m_jU9nA6t02U7ZARfKunt6dauUAB6O3nLHp0v5ypisNt9OJk');
    const blob = await data.blob();
    const reader = new FileReader();
    reader.onload = () => {
        const base64data = reader.result;
        console.log(base64data)
    }
    reader.readAsDataURL(blob);
})()

Base64-Blob-ArrayBuffer

์‹ค์ œ๋กœ ์ถœ๋ ฅ๋œ base64 ๋ฐ์ดํ„ฐ๊ฐ’์„ ๋ธŒ๋ผ์šฐ์ €์— ์ณ๋ณด๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ด๋ฏธ์ง€๊ฐ€ ์ถœ๋ ฅ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

Base64-Blob-ArrayBuffer


Blob (Binary Large Object)

BLOB์€ Binary Large OBject์˜ ์•ฝ์ž๋กœ ์ฃผ๋กœ ์ด๋ฏธ์ง€, ์˜ค๋””์˜ค, ๋น„๋””์˜ค์™€ ๊ฐ™์€ ๋ฉ€ํ‹ฐ๋ฏธ๋””์–ด ํŒŒ์ผ ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ์ €์žฅํ•œ ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. ๋ฉ€ํ‹ฐ๋ฏธ๋””์–ด ํŒŒ์ผ๋“ค์€ ๋Œ€๋‹ค์ˆ˜ ์šฉ๋Ÿ‰์ด ํฐ ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๊ธฐ ๋•Œ๋ฌธ์—, ์ด๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ํšจ๊ณผ์ ์œผ๋กœ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด ๊ณ ์•ˆ๋œ ์ž๋ฃŒํ˜•์ด๋ผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. (string ํƒ€์ž…, number ํƒ€์ž…์ด ์žˆ๋“ฏ์ด blob ํƒ€์ž…์ด ์žˆ๋‹ค๊ณ  ์ดํ•ดํ•˜๋ฉด ๋œ๋‹ค)

์˜ˆ๋ฅผ๋“ค์–ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ๊ทธ๋Œ€๋กœ ๋ฐ์ดํ„ฐ๋กœ ์ €์žฅํ•˜๊ณ  ์‹ถ์„๋•Œ, ๋ฐ”๋กœ blob ํฌ๋งท์œผ๋กœ ๋ณ€ํ™˜ํ•œ ๋’ค ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ๋„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ด์šฉํ•ด ์ด๋Ÿฌํ•œ blob ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฃผ๋กœ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ํ…์ŠคํŠธ, ์ด๋ฏธ์ง€, ์‚ฌ์šด๋“œ, ๋น„๋””์˜ค์™€ ๊ฐ™์€ ๋ฉ€ํ‹ฐ๋ฏธ๋””์–ด ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃฐ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

Base64-Blob-ArrayBuffer
blob์œผ๋กœ ๋ณ€ํ™˜๋œ ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ

 

์ข€๋” ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ฒŒ, base64์™€ ์–ด๋–ค์ ์ด ๋‹ค๋ฅธ์ง€ ๋น„๊ตํ•ด๋ณด์ž.

  • base64๋Š” ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด ํ…์ŠคํŠธ(๋ฌธ์ž์—ด) ํ˜•ํƒœ๋กœ ์ €์žฅํ•œ ํฌ๋งท์ด๋ผ๊ณ  ํ–ˆ์—ˆ๋‹ค.
  • blob์ด๋ž€ ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด ๊ฐ์ฒด(Object) ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

์•ž์„œ base64 ํฌ๋งท์œผ๋กœ ์ด๋ฏธ์ง€ ๋ฐ”์ด๋„ˆ๋ฆฌ ํŒŒ์ผ์„ ๋ธŒ๋ผ์šฐ์ €์—์„œ ํ‘œํ˜„ํ•˜๋ ค๋ฉด, FileReader ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด ๋ณ€ํ™˜ํ›„ <img> ํƒœ๊ทธ์˜ src ์†์„ฑ์— ๋„ฃ์œผ๋ฉด ๊ฐ€๋Šฅํ–ˆ์—ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฌธ์ž์—ด์ด ๊ต‰์žฅํžˆ ๊ธธ์–ด์ ธ ๊ฐ€๋…์„ฑ์ด ์•ˆ์ข‹์„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, base64 ์ด๋ฏธ์ง€๋ฅผ ์ด๊ณณ์ €๊ณณ ์—ฌ๋Ÿฌ๊ฐœ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ๊ฒฐ๊ณผ์ ์œผ๋กœ ์šฉ๋Ÿ‰ ๋ฌธ์ œ ๋•Œ๋ฌธ์—(33% ์ปค์ง„๋‹ค) ๋ฌธ์„œ ์ž์ฒด๋ฅผ ๋กœ๋”ฉํ•˜๋Š”๋ฐ ๋งŽ์€ ์‹œ๊ฐ„์ด ๊ฑธ๋ ค ์˜คํžˆ๋ ค ๋Š๋ ค์งˆ์ˆ˜ ์žˆ๋‹ค๋Š” ๋‹จ์ ์„ ์ง€๋‹ˆ๊ณ  ์žˆ๋‹ค. 

Base64-Blob-ArrayBuffer

ํ•˜์ง€๋งŒ blob ๋ฐ์ดํ„ฐ๋Š” ์ ์ ˆํ•˜๊ฒŒ object url๋กœ ๋ณ€ํ™˜๋งŒ ํ•ด์ฃผ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‹ฌํ”Œํ•˜๊ฒŒ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‚ฌ์šฉํ• ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  blob์€ ๊ฐ์ฒด์ด๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์–‘ํ•œ ์ฝ”๋“œ ํ™œ์šฉ์„ฑ์„ ์ง€๋‹ˆ๊ณ  ์žˆ์–ด, base64๋กœ ๋ณ€ํ™˜ํ• ์ˆ˜๋„ ์žˆ๊ณ  ๋’ค์—์„œ ๋ฐฐ์šธ buffer๋กœ๋„ ๋ณ€ํ™˜ํ• ์ˆ˜๋„ ์žˆ๋‹ค.

Base64-Blob-ArrayBuffer


blob ์ด๋ฏธ์ง€ ๋‹ค๋ฃจ๊ธฐ

๋ณธ๊ฒฉ์ ์œผ๋กœ ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ blob์œผ๋กœ ๋ณ€ํ™˜ํ•ด ๋‹ค๋ค„๋ณด๋Š” ์‹ค์Šต์„ ๊ฐ€์ ธ๋ณด์ž. ๋‹ค์Œ์€ ์ด๋ฏธ์ง€๋ฅผ fetch api๋กœ ๋ฐ›์•„์™€ blob ํฌ๋งท์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์ฝ”๋“œ์ด๋‹ค.

const data = await fetch('https://play-lh.googleusercontent.com/hYdIazwJBlPhmN74Yz3m_jU9nA6t02U7ZARfKunt6dauUAB6O3nLHp0v5ypisNt9OJk');
const blob = await data.blob(); // ์ด๋ฏธ์ง€ blob ๊ฐ์ฒด ์–ป๊ธฐ

Base64-Blob-ArrayBuffer

 

Blob → ObjectURL ๋ณ€ํ™˜

์ด๋ ‡๊ฒŒ ๋งŒ๋“ค์–ด์ง„ Blob ๊ฐ์ฒด๋Š” ๊ณง๋ฐ”๋กœ ์‚ฌ์šฉํ• ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๊ณ , <a>, <img> ํƒœ๊ทธ์˜ src ์†์„ฑ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” url ํƒ€์ž…์œผ๋กœ ๋”ฐ๋กœ ๋ณ€ํ™˜์„ ํ•ด์•ผํ•œ๋‹ค.

<img src="" alt="" style="width:150px; display: block;"> 
<a download="img.jpg" href="#">์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ</a>

<script>
    fetch('https://www.business2community.com/wp-content/uploads/2014/04/Free.jpg')
      .then((response) => response.blob())
      .then((blob) => {
        const url = URL.createObjectURL(blob);
        document.querySelector('img').src = url;
        document.querySelector('a').href = url;
      });
</script>

See the Pen blob image by barzz12 (@inpaSkyrim) on CodePen.

 

URL.createObjectURL ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜๋ฉด Blob ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๊ณ  ๊ณ ์œ ํ•œ URL์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋•Œ ์ƒ์„ฑ๋˜๋Š” URL์˜ ํ˜•ํƒœ๋Š” blob:/์˜ ํ˜•ํƒœ๋ฅผ ๋„๊ฒŒ ๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ณ€ํ™˜๋œ URL์€ source(src)๋ฅผ ์†์„ฑ์œผ๋กœ ๊ฐ€์ง€๋Š” ๋ชจ๋“  HTML ํƒœ๊ทธ์™€ CSS ์†์„ฑ์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.

Blob ๊ฐ์ฒด์—๋Š” ๋ณ„๋„๋กœ type(image/png) ์„ ๋ช…์‹œํ•˜๊ธฐ ๋•Œ๋ฌธ์— Blob ๊ฐ์ฒด๋ฅผ ๋‹ค์šด๋กœ๋“œ/์—…๋กœ๋“œ ํ•˜๋Š” ๊ณผ์ •์—์„œ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์—์„œ์˜ Content-Type์€ ์ž์—ฐ์Šค๋ ˆ ๋ช…์‹œ๋œ type์œผ๋กœ ๋งค์นญ๋œ๋‹ค.

Base64-Blob-ArrayBuffer

์ด๋•Œ ๋ณ€ํ™˜๋œ URL์€ ํ˜„์žฌ ํƒญ์˜ ๋ธŒ๋ผ์šฐ์ € ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ๋˜๊ณ , ์ €์žฅ๋œ URL์€ ๋งคํ•‘๋œ Blob ๊ฐ์ฒด๋ฅผ ์ฐธ๊ณ ํ•˜๊ณ  ์žˆ๋Š” ํ˜•ํƒœ์ด๋‹ค. ์ด๋Ÿฌํ•œ ์›๋ฆฌ ๋•Œ๋ฌธ์—, base64์™€๋Š” ๋‹ฌ๋ฆฌ ์งง์€ ๋ฌธ์ž์—ด๋งŒ์œผ๋กœ๋„ ์›๋ž˜์˜ Blob ๊ฐ์ฒด์— ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๊ณ  ๊ทธ์— ๋”ฐ๋ฅธ ์ด๋ฏธ์ง€ ๋“ฑ์˜ ํŒŒ์ผ์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋ž˜์„œ ๋ณ€ํ™˜๋œ URL์€ ํ•ญ์ƒ ํ˜„์žฌ ๋ฌธ์„œ์—์„œ๋งŒ ์œ ํšจํ•˜๋‹ค. (ํ˜„์žฌ ๋ธŒ๋ผ์šฐ์ € ๋ฉ”๋ชจ๋ฆฌ์— ์ ์žฌ๋œ ์ƒํƒœ๋‹ˆ๊นŒ)

๋ณ€ํ™˜๋œ URL์„ ํ˜„์žฌ ๋ฌธ์„œ๋ฅผ ์ƒˆ๋กœ๊ณ ์นจํ•˜๊ฑฐ๋‚˜ ์•„๋‹ˆ๋ฉด ๋‹ค๋ฅธ ํŽ˜์ด์ง€์—์„œ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•œ๋‹ค๋ฉด ์ œ๋Œ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

 

๊ทธ๋Ÿฌ๋‚˜ ์ด์™€ ๊ด€๋ จํ•œ ๋ฉ”๋ชจ๋ฆฌ ์ด์Šˆ๊ฐ€ ์กฐ์žฌํ•œ๋‹ค.

Blob ๊ฐ์ฒด๊ฐ€ URL๋กœ ๋ณ€ํ™˜๋˜์–ด ๋งคํ•‘์ด ์ด๋ฃจ์–ด์ง„ ์ฑ„ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ๋˜๊ฒŒ ๋˜๋ฉด, ๋ช…์‹œ์ ์œผ๋กœ ํ•ด๋‹น URL์ด ํ•ด์ œ๋˜๊ธฐ ์ „๊นŒ์ง€ ๋ธŒ๋ผ์šฐ์ €๋Š” ํ•ด๋‹น URL์ด ์œ ํšจํ•˜๋‹ค๊ณ  ํŒ๋‹จํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์—์„œ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์ด ์ด๋ฃจ์–ด์ง€์ง€ ์•Š๋Š”๋‹ค.

๋”ฐ๋ผ์„œ blob URL์„ ์‚ฌ์šฉํ•œ ์ดํ›„, ๋” ์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ์‹œ์ ์ด๋ผ๊ณ  ํŒ๋‹จ๋˜๋ฉด ๋ช…์‹œ์ ์œผ๋กœ ํ•ด์ œํ•ด ์ฃผ๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

// Create Blob URL
const objectURL = window.URL.createObjectURL(blob);

// Revoke Blob URL after DOM updates..
window.URL.revokeObjectURL(objectURL);

๋ณ€ํ™˜์€ URL.createObjectURL ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ง„ํ–‰ํ–ˆ๊ณ , ํ•ด์ œ์˜ ๊ฒฝ์šฐ์—๋Š” URL.revokeObjectURL ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

์ด๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ๋งคํ•‘๋˜์–ด ์žˆ๋Š” ์ฐธ์กฐ๋ฅผ ์ง€์šฐ๋Š” ๋ฉ”์„œ๋“œ๋กœ, ๋ฉ”๋ชจ๋ฆฌ์— ์ƒ์ฃผํ•˜๊ณ  ์žˆ๋Š” Blob ๊ฐ์ฒด๋ฅผ ์ง€์šธ ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์ด๋ฏธ์ง€๋ฅผ ํ™”๋ฉด์— ์ถœ๋ ฅ์ด ์•„๋‹Œ ์˜ค๋กœ์ง€ ์ด๋ฏธ์ง€ ๋‹ค์šด์œผ๋กœ blob์„ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•˜๋ฉด, ๋™์ ์œผ๋กœ ์ƒ์„ฑํ•œ Blob ๊ฐ์ฒด๋Š” ์˜ค์ง ๋‹ค์šด๋กœ๋“œ ํด๋ฆญ ์ˆœ๊ฐ„์—๋งŒ ํ•„์š”ํ•˜๊ณ  ๊ทธ ์ดํ›„์—” ํ•„์š”ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ํ•ด์ œ๋ฅผ ํ†ตํ•ด ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

Blob → Base64 ๋ณ€ํ™˜

์•ž์„œ ๋งํ–ˆ๋“ฏ์ด Blob ๊ฐ์ฒด๋กœ base64์˜ ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜์ด ๊ฐ€๋Šฅํ•˜๊ณ , ๋ณ€ํ™˜๋œ ๋ฌธ์ž์—ด์„ ๋ฐ”๋กœ src ๋กœ์จ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ URL์€ ๋ณดํ†ต data url ์ด๋ผ๊ณ  ๋ถ€๋ฅด๋Š”๋ฐ, ์ด๋ ‡๊ฒŒ ๋ณ€ํ™˜๋œ base64 ํ˜•ํƒœ์˜ URL์€ ์œ„์—์„œ URL.createObjectURL ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๋ณ€ํ™˜ํ•œ ํ˜•ํƒœ์™€๋Š” ๋‹ฌ๋ฆฌ ์–ด๋””์—์„œ๋‚˜ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. (๋ฌธ์ž์—ด ์ž์ฒด๊ฐ€ ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ ์ด๊ธฐ ๋•Œ๋ฌธ์—)

Blob ๊ฐ์ฒด๋ฅผ base64๋กœ ์ธ์ฝ”๋”ฉ ํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์€ ์œ„ base64 ์†Œ๊ฐœ ํŒŒํŠธ์—์„œ ๋‹ค๋ค˜์—ˆ๋‹ค.

fetch('https://play-lh.googleusercontent.com/hYdIazwJBlPhmN74Yz3m_jU9nA6t02U7ZARfKunt6dauUAB6O3nLHp0v5ypisNt9OJk')
    .then((res) => res.blob())
    .then((blob) => {
        const reader = new FileReader();
        reader.onload = () => {
            const base64data = reader.result;
            console.log(base64data)
        }
        reader.readAsDataURL(blob);
    })
Blob ๊ฐ์ฒด๋ฅผ URL๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ์‹ ๋ชจ๋‘ ํ™œ์šฉ๋„๊ฐ€ ๋†’๋‹ค. ํ•˜์ง€๋งŒ base64๋กœ ์ธ์ฝ”๋”ฉ ํ•˜๋Š” ๊ฒฝ์šฐ์—” ๋ฌธ์ž์—ด์˜ ๊ธธ์ด๊ฐ€ ๋งค์šฐ ๊ธธ์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ๊ณผ URL.craeteObjectURL ๋ฉ”์„œ๋“œ๋ณด๋‹ค ๋” ๋Š๋ฆฌ๋‹ค๋Š” ์ ์ด ์žˆ๋Š” ๋ฐ˜๋ฉด, ๋ณ€ํ™˜๋œ data url์€ ํ˜„์žฌ ํƒญ์˜ ๋ฌธ์„œ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์–ด๋””์—์„œ๋„ ์œ ํšจํ•˜๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.

ArrayBuffer

ArrayBuffer ๊ฐ์ฒด๋Š” ์ด๋ฏธ์ง€, ๋™์˜์ƒ๊ณผ ๊ฐ™์€ ๋ฉ€ํ‹ฐ๋ฏธ๋””์–ด ๋ฐ์ดํ„ฐ ๋ฉ์–ด๋ฆฌ๋ฅผ ํ‘œ์ค€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ(๋ธŒ๋ผ์šฐ์ €)์—์„œ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด ๋„์ž…๋ฌ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ ์‹ค์‹œ๊ฐ„ ๋ฐฉ์†ก๊ณผ ๊ฐ™์ด ์˜์ƒ๋‚ด์šฉ์„ ์†ก์ถœํ•  ๋•Œ์—๋Š”, ์˜์ƒ์ด๋ผ๊ณ  ํ•˜๋Š” ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณ„์†ํ•ด์„œ ์ „๋‹ฌํ•ด์ค˜์•ผ ์œ ์ €๋“ค์ด ์ด๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, ์–ด๋–ค ์‹์œผ๋กœ๋“  ์ปค๋‹ค๋ž€ ๋ฐ์ดํ„ฐ๋ฅผ ์ž˜๊ฐœ ์ชผ๊ฐœ์„œ ์ „์†กํ•ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

Base64-Blob-ArrayBuffer

์—ฌ๊ธฐ์„œ ๋ฒ„ํผ(buffer) ๋ผ๋Š” ๊ฐœ๋…์ด ๋“ฑ์žฅ ํ•˜๋Š”๋ฐ, ์ผ์ • ๊ตฌํš๋งŒํผ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ชผ๊ฐœ์„œ ์ „๋‹ฌ๋˜๋Š” stream์„ ์ €์žฅํ•œ ํ›„ ์ผ์ • ํฌ๊ธฐ๊ฐ€ ๋„๋‹ฌํ•˜๋ฉด ์ถœ๋ ฅ์žฅ์น˜๋‚˜ ๋™์˜์ƒ ํ”Œ๋ ˆ์ด์–ด๋กœ ์ „๋‹ฌํ•ด์ฃผ๋Š” ์ค‘๊ฐœ์ž ์—ญํ• ์„ ํ•˜๋Š” ๊ฐ์ฒด๋ผ๊ณ  ๋ณด๋ฉด ๋œ๋‹ค. (๋ฒ„ํผ๋ง์ด ๋ฐ”๋กœ ์ด ๊ฐœ๋…์ด๋‹ค)

๋”ฐ๋ผ์„œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์šฉ๋„๊ฐ€ ๋‹ค์–‘ํ•ด์ง€๋ฉด์„œ ์ด์ฒ˜๋Ÿผ ์˜ค๋””์˜ค๋‚˜ ๋น„๋””์˜ค์™€ ๊ฐ™์€ binary data๋“ค ์—ญ์‹œ ๋‹ค๋ฃฐ ํ•„์š”์„ฑ์ด ์ƒ๊ธฐ๊ฒŒ ๋˜์ž, ํ•„์š”ํ•œ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ์ ์ ˆํ•˜๊ฒŒ ํ• ๋‹นํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์—ฐ์„ฑ์ด ํ•„์š”ํ•ด ArrayBuffer๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋˜์—ˆ๋‹ค๊ณ  ์ดํ•ดํ•˜๋ฉด ๋œ๋‹ค.

 

ArrayBuffer๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ์›์‹œ ๋ฐ์ดํ„ฐ(๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ)๋ฅผ ์ง์ ‘ ๋‹ค๋ฃจ๋Š” ์ˆ˜๋‹จ์œผ๋กœ ์‚ฌ์šฉ๋˜๋ฉฐ, ์ด๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ˆ˜๋™์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ ๋ฐฐ์šด base64์™€ blob์€ ์‚ฌ๋žŒ์ด ์ฝ๊ณ  ๋‹ค๋ฃจ๊ธฐ ํŽธํ•˜๊ฒŒ ๊ฐ€๊ณต๋œ ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด๋ผ๋ฉด,  ArrayBuffer ๋ณด๋‹ค ์˜ค๋ฆฌ์ง€๋„์— ๊ฐ€๊น๋‹ค๊ณ  ๋ณด๋ฉด ๋œ๋‹ค. ๋ ˆํผ๋Ÿฐ์Šค ํƒ€์ž…์œผ๋กœ ๋˜์–ด์žˆ๊ณ , ๊ณ ์ •๋œ ๊ธธ์ด์˜ ์—ฐ์†๋œ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ํ• ๋‹นํ•ด ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค๊ณ  ์•Œ๋ ค์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค. (์ฐธ๊ณ ๋กœ, ์˜ค๋””์˜ค ์ „์šฉ์ธ AuidoBuffer, ๋ฏธ๋””์–ด ์ „์šฉ์ธ SourceBuffer๋„ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค)

ํŠนํžˆ ์„ฑ๋Šฅ์— ๋ฏผ๊ฐํ•œ ์ด์Šˆ๋ฅผ ๋‹ค๋ฃฌ๋‹ค๊ฑฐ๋‚˜, ์•„๋‹ˆ๋ฉด Blob ๋“ฑ์˜ ํฐ ์šฉ๋Ÿ‰์˜ ํŒŒ์ผ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ฒฝ์šฐ์— ArrayBuffer๋ฅผ ์‚ฌ์šฉํ•ด ์œ ์—ฐํ•˜๊ณ  ํšจ์œจ์ ์œผ๋กœ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

ArrayBuffer๋Š” ์—ฐ์†๋œ ๊ณต๊ฐ„์˜ ๋ฉ”๋ชจ๋ฆฌ์— ํ• ๋‹น๋˜๋Š” ๊ณ ์ • ๊ธธ์ด์— ๋Œ€ํ•œ ์ฐธ์กฐ ๊ฐ์ฒด์ด๋‹ค. ํ•ด๋‹น ๊ฐ์ฒด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

let buffer = new ArrayBuffer(16); // 16 ๋ฐ”์ดํŠธ ํฌ๊ธฐ์˜ buffer๋ฅผ ์ƒ์„ฑ
buffer.byteLength; // 16

์ด๋•Œ ์ƒ์„ฑ๋œ buffer ๊ฐ์ฒด๋Š” ์—ฐ์†๋œ 16 ๋ฐ”์ดํŠธ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ์ฐจ์ง€ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ์ดˆ๊ธฐ๊ฐ’์€ ๋ชจ๋‘ 0์œผ๋กœ ์ฑ„์›Œ์ ธ ์žˆ๋‹ค. 

์ฐธ๊ณ ๋กœ, ์ด๋ฆ„์— array๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•˜์—ฌ ArrayBuffer๊ฐ€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฐฐ์—ด์ด๋ผ๊ณ  ์ฐฉ๊ฐํ•˜๋ฉด ์•ˆ๋œ๋‹ค.
ArrayBuffer๋Š” ๊ทธ์ € ๋ฉ”๋ชจ๋ฆฌ์˜ ์—ฐ์†๋œ ๊ณต๊ฐ„์„ ์ฐจ์ง€ํ•˜๊ณ  ์žˆ๋Š” ์ถ”์ƒ์ ์ธ ๋ฉ”๋ชจ๋ฆฌ ๊ณ„์ธต๊ณผ๋„ ๊ฐ™๋‹ค.

ArrayBuffer๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๋ฐฐ์—ด๊ณผ ๋น„๊ตํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฐจ์ด์ ์ด ์žˆ๋‹ค.
 - ๊ณ ์ •๊ธธ์ด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , ์ด๋ฅผ ๋Š˜์ด๊ฑฐ๋‚˜ ์ค„์ผ ์ˆ˜ ์—†๋‹ค.
 - ์ •ํ™•ํžˆ ๋ช…์‹œ๋œ ํฌ๊ธฐ๋งŒํผ์˜ ๊ณต๊ฐ„์„ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์ฐจ์ง€ํ•œ๋‹ค.
 - ๊ฐ๊ฐ์˜ ๋ฐ”์ดํŠธ์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š”, ์ผ๋ฐ˜ ๋ฐฐ์—ด์ฒ˜๋Ÿผ buffer[index]์™€ ๊ฐ™์ด ์ธ๋ฑ์Šค๋ฅผ ํ†ตํ•ด ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค. ๋Œ€์‹ ์— view๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” ๋ณ„๋„์˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์„œ ์ ‘๊ทผํ•ด์•ผ ํ•œ๋‹ค.

 

์ผ๋ฐ˜์ ์œผ๋กœ Array ๊ฐ™์€๊ฒฝ์šฐ ๊ทธ๋ƒฅ ๊ณง๋ฐ”๋กœ ์ ‘๊ทผํ•ด์„œ ๋ฐฐ์—ด ์•ˆ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐ์ž‘ํ• ์ˆ˜ ์žˆ์ง€๋งŒ, ArrayBuffer์— ๋Œ€ํ•œ ์ ‘๊ทผ ๋ฐ ์กฐ์ž‘์€ ํ•ญ์ƒ view๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” ๊ฐ์ฒด๋ฅผ ๋”ฐ๋กœ ์ƒ์„ฑํ•ด์„œ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•œ๋‹ค.

view ๊ฐ์ฒด๋Š” ์ž๊ธฐ ์Šค์Šค๋กœ๋Š” ์–ด๋– ํ•œ ๋ฐ์ดํ„ฐ๋„ ์ €์žฅํ•˜๊ณ  ์žˆ์ง€ ์•Š๊ณ , ๊ทธ์ € ArrayBuffer์˜ ๋‚ด๋ถ€๋ฅผ ๋“ค์—ฌ๋‹ค๋ณด๊ธฐ ์œ„ํ•œ ์ˆ˜๋‹จ์œผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค. (์ด๋“ค์€ ๋ณดํ†ต TypedArray ๋ผ๋Š” ์šฉ์–ด๋กœ ํ‘œํ˜„ํ•œ๋‹ค)

๋‹ค์Œ์€ ArrayBuffer์— ์žˆ๋Š” ๊ฐ ๋ฐ”์ดํŠธ๋ฅผ ๊ฐœ๋ณ„์ ์œผ๋กœ ๋‹ค๋ฃจ๋Š” view ๊ฐ์ฒด ์ข…๋ฅ˜์ด๋‹ค.

  • Uint8Array : ์ˆซ์ž 8์€ ๋น„ํŠธ๋ฅผ ์˜๋ฏธํ•˜๊ณ  8๋น„ํŠธ = 1๋ฐ”์ดํŠธ์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ ๋ฐ”์ดํŠธ๋ณ„๋กœ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. 1๋ฐ”์ดํŠธ ํฌ๊ธฐ์ด๊ธฐ ๋•Œ๋ฌธ์— 0 - 255 ๋ฒ”์œ„์˜ ์ˆ˜๋ฅผ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋‹ค. (Uint8์˜ ์˜๋ฏธ๋Š” Unsigned 8bit Int์™€๋„ ๊ฐ™๋‹ค)
  • Uint16Array : 2๋ฐ”์ดํŠธ(16๋น„ํŠธ) ๋‹จ์œ„ ์ •์ˆ˜ํ˜•์œผ๋กœ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•œ view ๊ฐ์ฒด์ด๋‹ค. ๋”ฐ๋ผ์„œ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋Š” ๋ฒ”์œ„๋Š” 0 - 65535์— ํ•ด๋‹นํ•œ๋‹ค.
  • Uint32Array : 4๋ฐ”์ดํŠธ(32๋น„ํŠธ) ๋‹จ์œ„ ์ •์ˆ˜ํ˜•์œผ๋กœ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•œ view ๊ฐ์ฒด์ด๋‹ค. ๋”ฐ๋ผ์„œ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋Š” ๋ฒ”์œ„๋Š” 0 - 4294967295์— ํ•ด๋‹นํ•œ๋‹ค.
  • Float64Array : 8๋ฐ”์ดํŠธ(64๋น„ํŠธ) ๋‹จ์œ„๋กœ ๋ถ€๋™ ์†Œ์ˆ˜์  ๋ฐฉ์‹์œผ๋กœ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•œ view ๊ฐ์ฒด์ด๋‹ค. ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋Š” ๋ฒ”์œ„๋Š” 5.0x10^-324 ๋ถ€ํ„ฐ 1.8x10^308 ๊นŒ์ง€์ด๋‹ค.

Base64-Blob-ArrayBuffer

let buffer = new ArrayBuffer(16);
let view = new Uint32Array(buffer);

// buffer์€ [00000000 00000000 ...... (์ด 16๊ฐœ)] ๋กœ ํ˜•์„ฑ๋˜์–ด์žˆ๊ณ 
// view๊ฐ€ ์ด๊ฒƒ์„ ์ธ์‹ํ•  ๋•Œ 4๋ฐ”์ดํŠธ์”ฉ, ์ฆ‰ 8๊ฐœ์งœ๋ฆฌ 4๊ฐœ์”ฉ ๋‹จ์œ„๋กœ ๋Š์–ด ์ฝ๋Š”๋‹ค๋Š” ์†Œ๋ฆฌ๋‹ค.
// [00000000 00000000 00000000 00000000, 00000000 00000000 ......]

console.log(view.length); // ๋ถ„ํ• ํ•ด์„œ ์ฝ๋Š” ๊ณต๊ฐ„์˜ ๊ฐฏ์ˆ˜๊ฐ€ ์ด 4๊ฐœ (16๋ฐ”์ดํŠธ / 4๋ฐ”์ดํŠธ)
console.log(view.byteLength); // ์ด ๋ฐ”์ดํŠธํฌ๊ธฐ๋Š” 16๋ฐ”์ดํŠธ

// view๋ฅผ ํ†ตํ•ด ๊ฐ’์„ ์ž…๋ ฅ
view[0] = 123456; // ๋ถ„ํ• ๊ณต๊ฐ„ ์ค‘ ์ฒซ๋ฒˆ์งธ์— 123456์ด๋ผ๋Š” ์ˆซ์ž๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ๋Š”๋‹ค

for (let num of view) {
  console.log(num);	// 123456, 0, 0, 0
}
ArrayBuffer์— ์˜ํ•ด ๊ตฌํ˜„๋œ ๊ฐ์ฒด๋Š” ๋ฐ์ดํ„ฐ ๋ถ€๋ถ„์„ ๋‚˜ํƒ€๋‚ด๊ณ , view๋Š” ๋ฌธ๋งฅ์„ ์ œ๊ณตํ•ด ์‹ค์ œ ๋ฐ์ดํ„ฐ ํ˜•์‹ํ™” ๋ฐฐ์—ด๋กœ ๋ฐ”๊พผ๋‹ค.

 

Base64  ArrayBuffer Blob

base64 ๋ฐ์ดํ„ฐ๋ฅผ blob์œผ๋กœ ๋ฐ”๊พธ๊ธฐ ์œ„ํ•ด ์ค‘๊ฐ„ ๊ณผ์ •์œผ๋กœ arrayBuffer๊ฐ€ ์“ฐ์ธ๋‹ค.

// bas64๋ฅผ blob์œผ๋กœ ๋ณ€ํ™˜ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜
function b64toBlob(b64Data, contentType = '', sliceSize = 512) {
   const image_data = atob(b64Data.split(',')[1]); // data:image/gif;base64 ํ•„์š”์—†์œผ๋‹ˆ ๋–ผ์ฃผ๊ณ , base64 ์ธ์ฝ”๋”ฉ์„ ํ’€์–ด์ค€๋‹ค

   const arraybuffer = new ArrayBuffer(image_data.length);
   const view = new Uint8Array(arraybuffer);

   for (let i = 0; i < image_data.length; i++) {
      view[i] = image_data.charCodeAt(i) & 0xff;
      // charCodeAt() ๋ฉ”์„œ๋“œ๋Š” ์ฃผ์–ด์ง„ ์ธ๋ฑ์Šค์— ๋Œ€ํ•œ UTF-16 ์ฝ”๋“œ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” 0๋ถ€ํ„ฐ 65535 ์‚ฌ์ด์˜ ์ •์ˆ˜๋ฅผ ๋ฐ˜ํ™˜
      // ๋น„ํŠธ์—ฐ์‚ฐ์ž & ์™€ 0xff(255) ๊ฐ’์€ ์ˆซ์ž๋ฅผ ์–‘์ˆ˜๋กœ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ์„ค์ •
   }

   return new Blob([arraybuffer], { type: contentType });
}

const contentType = 'image/png';
const b64Data =
   'data:image/gif;base64,R0lGODlhAAEAAcQAALe9v9ve3/b393mDiJScoO3u74KMkMnNz4uUmKatsOTm552kqK+1uNLW18DFx3B7gP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjAxODAxMTc0MDcyMDY4MTE5QjEwQjYyNTc4MkUxRURBIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjEzN0VEMDZBQjMyNzExRTE4REMzRUZGMkFCOTM1NkZBIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjEzN0VEMDY5QjMyNzExRTE4REMzRUZGMkFCOTM1NkZBIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzUgTWFjaW50b3NoIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MDI4MDExNzQwNzIwNjgxMTlCMTBCNjI1NzgyRTFFREEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MDE4MDExNzQwNzIwNjgxMTlCMTBCNjI1Nzgy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';

const blob = b64toBlob(b64Data, contentType); // base64 -> blob
const blobUrl = URL.createObjectURL(blob); // object url ์ƒ์„ฑ

const img = document.createElement('img');
img.src = blobUrl;
document.body.appendChild(img);

 

Blob → ArrayBuffer

์ •ํ†ต์ ์ธ FileReader ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ• ์ˆ˜๋„ ์žˆ๊ณ ,

let fileReader = new FileReader();

fileReader.readAsArrayBuffer(blob); // ArrauBuffer ํ˜•ํƒœ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด ๋ณ€ํ™˜

fileReader.onload = function(event) {
  let arrayBuffer = fileReader.result;
};

๋Œ€์šฉ๋Ÿ‰ blob์ผ๊ฒฝ์šฐ ํ”„๋กœ๋ฏธ์Šค๋ฅผ ์ด์šฉํ•ด ๋น„๋™๊ธฐ๋กœ๋„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

const blob = new Blob(...);
const buf = await blob.arrayBuffer(); // ๋น„๋™๊ธฐ๋กœ arrayBuffer๋กœ ๋ณ€ํ™˜ (๋Œ€์šฉ๋Ÿ‰ ์ผ๊ฒฝ์šฐ)

 

ํŽธ๋ฒ•์œผ๋กœ blob์„ ObjectURL๋กœ ๋ฐ”๊พธ๊ณ  fetch๋กœ ์š”์ฒญํ•ด์„œ ํ•œ๋ฐฉ์— arraybuffer๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์กด์žฌํ•œ๋‹ค.

// ํ•œ๋ฐฉ์—๋„ ๊ฐ€๋Šฅ
fetch(URL.createObjectURL(myBlob))
	.then(res => res.arrayBuffer())

Buffer 

๋ฐ์ดํ„ฐ ๋ฉ์–ด๋ฆฌ๋ฅผ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด Node.js๋Š” ์ง„์ž‘๋ถ€ํ„ฐ Buffer ํƒ€์ž…์„ ๋„์ž…ํ–ˆ๋‹ค

๋ฒ„ํผ๋Š” ๊ณ ์ •๋œ ํฌ๊ธฐ์˜ ๋ฐ์ดํ„ฐ ๋ฉ์–ด๋ฆฌ๋ฅผ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ํƒ€์ž…์ด๋ฉฐ, Node.js ์˜ ๋งŽ์€ API๋“ค์ด Buffer ํƒ€์ž…์„ ์ง€์›ํ•œ๋‹ค.

fs ๋ชจ๋“ˆ๋กœ ๋กœ์ปฌ ํŒŒ์ผ์„ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ๋„ ์‚ฌ์‹ค ๋ฒ„ํผ๋กœ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์ด๋‹ค.

ํด๋ผ์ด์–ธํŠธ๋‹จ์—์„œ ArrayBuffer๋กœ ์ด์ง„ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ์—ˆ๋‹ค๋ฉด, ์„œ๋ฒ„๋‹จ(Node.js)์—์„œ๋Š” Buffer ๊ฐ์ฒด๋กœ ์ด์ง„ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃฌ๋‹ค๊ณ  ์ดํ•ดํ•˜๋ฉด ๋œ๋‹ค.

Node.js์—์„œ ๋ฉ€ํ‹ฐ๋ฏธ๋””์–ด ํŒŒ์ผ์„ ๋‹ค๋ฃฌ๋‹ค๊ณ  ํ•˜๋ฉด ๋ฌด์กฐ๊ฑด ๋ฒ„ํผ๋ฅผ ์ด์šฉํ•ด ๋‹ค๋ฃฌ๋‹ค ๋ผ๊ณ  ์ดํ•ดํ•˜๋ฉด ๋œ๋‹ค.

Base64-Blob-ArrayBuffer

 

[NODE] ๐Ÿ“š ๋ฒ„ํผ / ์ŠคํŠธ๋ฆผ / ํŒŒ์ดํ”„ ๋ฌธ๋ฒ• ์ •๋ฆฌ

๋ฒ„ํผ (Buffer) ๊ธฐ๋ณธ์ ์œผ๋กœ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์ด์ง„ ๋ฐ์ดํ„ฐ(binary data)๋ฅผ ๋‹ค๋ฃฐ ์ˆ˜ ์—†๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์„œ๋ฒ„๋กœ ํ™œ์šฉํ•˜๋Š” ๋…ธ๋“œ์—์„œ๋Š” TCP streams ์ด๋‚˜ ํŒŒ์ผ์„ ์ฝ๊ณ  ์“ธ ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค. ๊ทธ๋ž˜์„œ ๋“ฑ์žฅํ•œ ๊ฒƒ์ด buffer์ด

inpa.tistory.com


์„œ๋ฒ„๋‹จ์—์„œ ์ด๋ฏธ์ง€ ๊ฐ€์ ธ์™€ ๋‹ค๋ฃจ๊ธฐ

๋กœ์ปฌ์—์„œ ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ๊ฐ€์ ธ์˜ค๋ฉด ๋ฐ”๋กœ ๋ฒ„ํผ๋กœ ๋ณ€ํ™˜๋˜์„œ ๋ณต์žกํ•œ ๊ณผ์ •์—†์ด ๋ฐ”๋กœ ์„œ๋ฒ„์—์„œ ์ด๋ฏธ์ง€๋ฅผ ๋‹ค๋ฃฐ์ˆ˜ ์žˆ๊ฒ ์ง€๋งŒ, ์„œ๋ฒ„์—์„œ ajax๋กœ ์ด๋ฏธ์ง€๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ณ  ์ด๋ฅผ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด์„œ๋Š” ์œ„์—์„œ ๋ฐฐ์šด blob, arraybuffer๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

const fetch = require('node-fetch');

//* ์ด๋ฏธ์ง€ ๊ฐ€์ ธ์˜ค๊ธฐ
const img = await fetch('์ด๋ฏธ์ง€URL ํ˜น์€ base64์ด๋ฏธ์ง€') // ์ด๋ฏธ์ง€ url์„ fetch
  .then((res) => res.blob()) // ๋ฐ˜ํ™˜ ์ด๋ฏธ์ง€๋ฅผ blob์œผ๋กœ ๋ณ€ํ™˜
  .then(async (blob) => {
     const arrayBuffer = await blob.arrayBuffer(); // blob์„ arrayBuffer๋กœ ๋ณ€ํ™˜
     return Buffer.from(arrayBuffer); // ํด๋ผ์ด์–ธํŠธ์šฉ ๋ฒ„ํผ์ธ arrayBuffer๋ฃฐ ๋‹ค์‹œ ์„œ๋ฒ„์šฉ buffer๋กœ ๋ณ€ํ™˜
  });
  1. ์ด๋ฏธ์ง€๋ฅผ fetchํ•œ๋‹ค
  2. ๊ทธ๋ฆฌ๊ณ  ๊ฒฐ๊ณผ๊ฐ’์„ blob์œผ๋กœ ๋ณ€ํ™˜ํ•ด์ค€๋‹ค
  3. blob์„ ๋น„๋™๊ธฐ๋ฅผ ํ†ตํ•ด arraybuffer๋กœ ๋ณ€ํ™˜ํ•ด์ค€๋‹ค
  4. arraybuffer์„ buffer๋กœ ๋ณ€ํ™˜ํ•ด์ค€๋‹ค (blob์„ buffer๋กœ ๋ฐ”๋กœ ๋ณ€ํ™˜์ด ์•ˆ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ด์™€ ๊ฐ™์€ ๊ณผ์ •์„ ์ดํ–‰)

 

์‚ฌ์‹ค fetch ๋ชจ๋“ˆ์—์„œ ๋ฐ”๋กœ ๋ฒ„ํผ๋กœ ๋ณ€ํ™˜ํ• ์ˆ˜ ์žˆ๋Š” ํ—ฌํผ ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•˜๋‹ˆ ์•„๋ž˜์™€ ๊ฐ™์ด ๊ฐ„๋‹จํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค. (๊ทธ๋ž˜๋„ ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” ์œ„์™€ ๊ฐ™์ด ๋™์ž‘๋œ๋‹ค. ๊ณต๋ถ€ํ•จ ๋ณด๋žŒ?!)

const fetch = require('node-fetch');

const img = await fetch(์ด๋ฏธ์ง€URL ํ˜น์€ base64์ด๋ฏธ์ง€) // ์ด๋ฏธ์ง€ url์„ fetch
      .then((res) => res.buffer()) // ๋ฐ˜ํ™˜ ์ด๋ฏธ์ง€๋ฅผ blob์œผ๋กœ ๋ณ€ํ™˜

File & FileReader

ํŒŒ์ผ์€ ์šฐ๋ฆฌ์—๊ฒŒ ๋งค์šฐ ์ต์ˆ™ํ•œ ํƒ€์ž…์ด์ง€๋งŒ, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ์˜ File ๊ฐ์ฒด๋Š” Blob ๊ฐ์ฒด๋ฅผ ํ™•์žฅํ•œ ๊ฐ์ฒด๋กœ ์ฃผ๋กœ ํŒŒ์ผ์‹œ์Šคํ…œ๊ณผ ๊ด€๋ จ๋œ ๊ธฐ๋Šฅ์„ ๋‹ด๋‹นํ•œ๋‹ค.

ํŒŒ์ผ์‹œ์Šคํ…œ์€ OS/์„œ๋ฒ„๋‹จ์˜ ์˜์—ญ์ธ๋ฐ, ๋ธŒ๋ผ์šฐ์ € ์ƒ์—์„œ๋„ ํŒŒ์ผ์„ ์ฃผ๊ณ  ๋ฐ›๋Š” ๋“ฑ์˜ ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•œ ๊ทœ๊ฒฉ์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๋ธŒ๋ผ์šฐ์ €์—์„œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ด์šฉํ•ด ํŒŒ์ผ์„ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” File ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•˜๊ฑฐ๋‚˜ html์˜ inputํƒœ๊ทธ๋ฅผ ์ด์šฉํ•˜๋Š” ๋‘ ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.

new File(fileParts, fileName, [options]);
/*
- fileParts : Blob / BufferSource / String ๊ณผ ๊ฐ™์€ ๋ฐฐ์—ด
- fileName : ํŒŒ์ผ ์ด๋ฆ„ (๋ฌธ์ž์—ด)
- options : ์˜ต์…”๋„ ๊ฐ’. lastModified : ๋งˆ์ง€๋ง‰ ์ˆ˜์ •์ด ์ผ์–ด๋‚œ ๋•Œ์˜ timestamp
*/
<input type="file" onchange="showFile(this)">

<script>
  function showFile(input) {
  	// input type='file' ์˜ ๊ฒฝ์šฐ ์ถ”๊ฐ€์ ์œผ๋กœ multiple ์˜ต์…˜์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ์ด ๊ฒฝ์šฐ์—๋Š” ๋‹ค๋Ÿ‰์˜ File์ด ๋ฐฐ์—ด ํ˜•ํƒœ๋กœ ์ „๋‹ฌ๋˜๊ฒŒ ๋œ๋‹ค. 
    // ์ด๋•Œ๋ฅผ ๊ณ ๋ คํ•˜์—ฌ ๋‹จ์ผ ํŒŒ์ผ๋งŒ ์ „๋‹ฌ๋˜๋Š” ๊ฒฝ์šฐ์—๋„ File์€ ํ•ญ์ƒ ์œ ์‚ฌ ๋ฐฐ์—ด๋กœ ์ „๋‹ฌ๋˜๊ธฐ ๋•Œ๋ฌธ์— ํ•˜๋‚˜์˜ ํŒŒ์ผ๋งŒ ๋‹ค๋ฃจ๋Š” ๊ฒฝ์šฐ์—๋„ ์ธ๋ฑ์Šค๋กœ ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์— ์ฃผ์˜ํ•˜์ž
    let file = input.files[0];
    
    alert(`File name: ${file.name}`); // ํŒŒ์ผ ์ด๋ฆ„
    alert(`Last modified: ${file.lastModified}`); // ์ง€๋ง‰ ์ˆ˜์ •์ด ์ผ์–ด๋‚œ ๋•Œ์˜ timestamp
  }
</script>

FileReader ๊ฐ์ฒด

์œ„์—์„œ ์‚ฌ์šฉํ•ด๋ดค๋˜ FileReader๋Š” Blob ๋˜๋Š” File๊ณผ ๊ฐ™์€ ๊ฐ์ฒด๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด ๋“ค์ด๊ธฐ์œ„ํ•œ ๋ชฉ์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ฐ์ฒด์ด๋‹ค.

์ฝ์–ด๋“ค์ธ ๋ฐ์ดํ„ฐ๋Š” ์ฃผ๋กœ ์ด๋ฒคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•„์š”ํ•œ ํƒ€์ด๋ฐ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•œ๋‹ค. 

 

์ƒ์„ฑ๋œ FileReader ๊ฐ์ฒด์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ฃผ์š” ๋ฉ”์„œ๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

const reader = new FileReader();

reader.readAsArrayBuffer(blob) // ArrauBuffer ํ˜•ํƒœ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด ๋ณ€ํ™˜

reader.readAsText(blob, [encoding]) // encoding ๋ฐฉ์‹์— ๋งž๊ฒŒ ํ…์ŠคํŠธ ํ˜•ํƒœ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด ๋ณ€ํ™˜ (๊ธฐ๋ณธ ์ธ์ฝ”๋”ฉ ๋ฐฉ์‹ - utf-8)

reader.readAsDataURL(blob) // base64 ํ˜•ํƒœ์˜ data url๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด ๋ณ€ํ™˜
  • readAsArrayBuffer(blob) : ArrauBuffer ํ˜•ํƒœ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์Œ
    • readAsArrayBuffer์˜ ๊ฒฝ์šฐ ๋ฐ”์ด๋„ˆ๋ฆฌ ํŒŒ์ผ ๋Œ€์ƒ์œผ๋กœ ๋กœ์šฐ ๋ ˆ๋ฒจ์˜ ๋ฐ”์ด๋„ˆ๋ฆฌ ์ž‘์—…์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์— ์œ ์šฉํ•˜๋‹ค. ๋Œ€๋ถ€๋ถ„ ํ•˜์ด๋ ˆ๋ฒจ์—์„œ ํ•˜๋Š” ์ž‘์—…์˜ ๊ฒฝ์šฐ์—” File ๊ฐ์ฒด๊ฐ€ Blob์„ ์ƒ์†๋ฐ›๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ณ„๋„์˜ ์ฝ๊ธฐ ๊ณผ์ •์—†์ด ์ฆ‰๊ฐ์ ์œผ๋กœ slice ๋“ฑ์˜ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  • readAsText(blob, [encoding]) : encoding ๋ฐฉ์‹์— ๋งž๊ฒŒ ํ…์ŠคํŠธ ํ˜•ํƒœ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์Œ (๊ธฐ๋ณธ ์ธ์ฝ”๋”ฉ ๋ฐฉ์‹ - utf-8)
    • readAsText์˜ ๊ฒฝ์šฐ ํ…์ŠคํŠธ ํ˜•ํƒœ์˜ ๋ฌธ์ž์—ด์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์œ ์šฉํ•˜๋‹ค.
  • readAsDataURL(blob) : base64 ํ˜•ํƒœ์˜ data url๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์Œ
    • readAsDataURL์˜ ๊ฒฝ์šฐ img ํƒœ๊ทธ์™€ ๊ฐ™์ด src ์†์„ฑ์— ๋ฆฌ์†Œ์Šค๋ฅผ ๋‹ค๋ฃจ์–ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ์œ ์šฉํ•˜๋‹ค.
      ๋˜๋Š” ์ด์ „ ์ฑ•ํ„ฐ์—์„œ ๋‹ค๋ฃฌ๋ฐ”์™€ ๊ฐ™์ด URL.createObjectURL์„ ์ด์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ๋‹ค.
  • abort() : ์ž‘์—…์„ ์ฆ‰์‹œ ์ค‘๋‹จ

 

FileReader ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๋Š” ๊ณผ์ •์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ ๋ชฉ๋ก์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

const reader = new FileReader();
reader.readAsDataURL(blob) // base64 ํ˜•ํƒœ์˜ data url๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด ๋ณ€ํ™˜

// ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ๋‘ ์ฝ์œผ๋ฉด onload ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ
reader.onload = () => {
    const data = reader.result; // ๊ฒฐ๊ณผ ์ €์žฅ
    console.log(data)
}
  • loadstart : ๋กœ๋”ฉ์ด ์‹œ์ž‘๋  ๋•Œ
  • progress : ์ฝ๊ธฐ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ณ  ์žˆ๋Š” ์ค‘
  • load : ์—๋Ÿฌ ์—†์ด ๋ฆฌ๋”ฉ์ด ์™„๋ฃŒ๋œ ๋•Œ
  • abort : abort() ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋œ ๋•Œ
  • error : ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ๋•Œ
  • loadend : ์„ฑ๊ณต/์‹คํŒจ ์—ฌ๋ถ€ ์ƒ๊ด€์—†์ด ๋ฆฌ๋”ฉ์ด ์™„๋ฃŒ๋œ ๋•Œ

๋งŒ์•ฝ ์ฝ๊ธฐ๊ฐ€ ๋ชจ๋‘ ์™„๋ฃŒ๋˜์—ˆ๋‹ค๋ฉด ๊ทธ์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ”„๋กœํผํ‹ฐ๋กœ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

  • reader.result : ์„ฑ๊ณต ์‹œ ์ฝ์–ด๋“ค์ธ ๊ฒฐ๊ณผ
  • reader.error : ์‹คํŒจ ์‹œ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ

๋‹ค์Œ์€ FileReader๋ฅผ ์ด์šฉํ•ด, ๋ธŒ๋ผ์šฐ์ €์—์„œ ํŒŒ์ผ์ฒจ๋ถ€๋ฅผ ํ•˜๋ฉด ํŒŒ์ผ์„ base64ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜ํ•ด ์ด๋ฏธ์ง€๋กœ ๋„์šฐ๋Š” ์˜ˆ์ œ ์ฝ”๋“œ์ด๋‹ค.

<img src="">
<input type='file' onchange='readFile(this)' />

<script>
  function readFile(input) {
    const file = input.files[0]; // ์ฒจ๋ถ€๋œ ํŒŒ์ผ์„ ๊ฐ€์ ธ์˜ด
    
    const reader = new FileReader();
   
    reader.readAsDataURL(file); // ํŒŒ์ผ์„ base64๋กœ ๋ณ€ํ™˜
  
    reader.onload = function() {
      console.log(reader.result); // ์ฝ์€ ํŒŒ์ผ ์†Œ์Šค๋‹จ์— ์ถœ๋ ฅ
      document.querySelector('img').src = reader.result;
    };
  
    reader.onerror = function() {
      console.log(reader.error);
    };
  }
</script>

See the Pen FileReader to Base64 IMG by barzz12 (@inpaSkyrim) on CodePen.


# ์ฐธ๊ณ ์ž๋ฃŒ

https://ko.javascript.info/binary

https://heropy.blog/2019/02/28/blob/

https://www.csharpstudy.com/Tip/Tip-base64.aspx

https://curryyou.tistory.com/440

https://im-designloper.tistory.com/57

https://creatordev.tistory.com/97

https://velog.io/@longroadhome/%EB%AA%A8%EB%8D%98JS-%EC%8B%AC%ED%99%94-%EB%B0%94%EC%9D%B4%EB%84%88%EB%A6%AC-%EB%8D%B0%EC%9D%B4%ED%84%B0%EC%99%80-%ED%8C%8C%EC%9D%BC

https://velog.io/@yijaee/Buffer%EC%99%80-Stream