diff --git a/4-binary/03-blob/article.md b/4-binary/03-blob/article.md index 84cf6f1cca..132199915d 100644 --- a/4-binary/03-blob/article.md +++ b/4-binary/03-blob/article.md @@ -1,30 +1,30 @@ # Blob -`ArrayBuffer` and views are a part of ECMA standard, a part of JavaScript. +`ArrayBuffer`와 뷰는 ECMA 표준의 일부이며 자바스크립트의 일부입니다. -In the browser, there are additional higher-level objects, described in [File API](https://www.w3.org/TR/FileAPI/), in particular `Blob`. +브라우저에는 `Blob` 같이 [File API](https://www.w3.org/TR/FileAPI/)에 설명된 상위 수준 객체가 추가로 존재합니다. -`Blob` consists of an optional string `type` (a MIME-type usually), plus `blobParts` -- a sequence of other `Blob` objects, strings and `BufferSource`. +`Blob`은 선택사항인 문자열 `type`(보통 MIME형)과 `blobParts`로 구성됩니다. `blobParts`는 다른 `Blob` 객체, 문자열, `BufferSource`의 나열로 이루어집니다. ![](blob.svg) -The constructor syntax is: +생성자 문법은 다음과 같습니다. ```js new Blob(blobParts, options); ``` -- **`blobParts`** is an array of `Blob`/`BufferSource`/`String` values. -- **`options`** optional object: - - **`type`** -- `Blob` type, usually MIME-type, e.g. `image/png`, - - **`endings`** -- whether to transform end-of-line to make the `Blob` correspond to current OS newlines (`\r\n` or `\n`). By default `"transparent"` (do nothing), but also can be `"native"` (transform). +- **`blobParts`** 는 `Blob`/`BufferSource`/`String` 값의 배열입니다. +- **`options`** 선택사항 객체 + - **`type`** -- `Blob`형으로 보통 MIME형, 예) `image/png`, + - **`endings`** -- `Blob` 생성 시 현재 OS 줄 바꿈(`\r\n` or `\n`)에 맞추어 줄의 끝을 변환할지 여부. 기본값은 `"transparent"`(아무것도 하지 않음)이나`"native"`(변환함)도 가능합니다. -For example: +예를 들면, ```js -// create Blob from a string +// Blob을 문자열로부터 생성합니다 let blob = new Blob(["…"], {type: 'text/html'}); -// please note: the first argument must be an array [...] +// 주의 : 첫 번째 인수는 배열 [...]이어야 합니다. ``` ```js @@ -35,34 +35,34 @@ let blob = new Blob([hello, ' ', 'world'], {type: 'text/plain'}); ``` -We can extract `Blob` slices with: +`Blob`은 다음과 같이 잘라내어 추출할 수 있습니다. ```js blob.slice([byteStart], [byteEnd], [contentType]); ``` -- **`byteStart`** -- the starting byte, by default 0. -- **`byteEnd`** -- the last byte (exclusive, by default till the end). -- **`contentType`** -- the `type` of the new blob, by default the same as the source. +- **`byteStart`** -- 시작 바이트로 기본값은 0. +- **`byteEnd`** -- 끝 바이트(지정한 값 이전 값까지 포함하며(exclusive) 기본값은 끝까지). +- **`contentType`** -- 새 blob의 `type`으로 기본값은 원본과 같음. -The arguments are similar to `array.slice`, negative numbers are allowed too. +인수는 `array.slice`와 비슷하며 음수도 허용됩니다. -```smart header="`Blob` objects are immutable" -We can't change data directly in a `Blob`, but we can slice parts of a `Blob`, create new `Blob` objects from them, mix them into a new `Blob` and so on. +```smart header="`Blob` 객체는 불변입니다" +`Blob` 안에서 직접 데이터를 변경할 수는 없지만 `Blob` 일부를 잘라내어 새 `Blob` 객체를 생성하거나 새 `Blob`으로 합쳐 넣는 작업 등이 가능합니다. -This behavior is similar to JavaScript strings: we can't change a character in a string, but we can make a new corrected string. +이런 동작 방식은 JavaScript 문자열과 비슷합니다. 문자열 안의 문자는 변경할 수 없지만 수정된 문자열을 새로 만들 수 있습니다. ``` -## Blob as URL +## Blob을 URL로 사용하기 -A Blob can be easily used as an URL for ``, `` or other tags, to show its contents. +Blob을 손쉽게 ``, `` 등 태그의 URL로 사용하여 내용을 보여줄 수 있습니다. -Thanks to `type`, we can also download/upload `Blob` objects, and the `type` naturally becomes `Content-Type` in network requests. +`type` 덕분에 `Blob` 객체를 다운로드/업로드할 수 있으며 `type`은 자연스럽게 네트워크 요청 시 `Content-Type`이 됩니다. -Let's start with a simple example. By clicking on a link you download a dynamically-generated `Blob` with `hello world` contents as a file: +간단한 예제로 시작해 봅시다. 링크를 클릭하면 `Blob`이 동적 생성되며 `hello world` 내용을 가진 파일로 다운로드됩니다. ```html run - + Download ``` -We can also create a link dynamically in JavaScript and simulate a click by `link.click()`, then download starts automatically. +자바스크립트로 링크를 동적 생성하고 `link.click()`으로 클릭처럼 동작하게 하여 다운로드를 자동으로 시작할 수도 있습니다. -Here's the similar code that causes user to download the dynamicallly created `Blob`, without any HTML: +다음은 HTML 없이 동적 생성된 `Blob`을 사용자가 다운로드하는 유사한 코드입니다. ```js run let link = document.createElement('a'); @@ -89,51 +89,51 @@ link.click(); URL.revokeObjectURL(link.href); ``` -`URL.createObjectURL` takes a `Blob` and creates a unique URL for it, in the form `blob:/`. +`URL.createObjectURL`은 `Blob`으로 `blob:/` 형태의 고유 URL을 만듭니다. -That's what the value of `link.href` looks like: +이 형태를 `link.href` 값으로 사용합니다. ``` blob:https://javascript.info/1e67e00e-860d-40a5-89ae-6ab0cbee6273 ``` -For each URL generated by `URL.createObjectURL` the browser stores a URL -> `Blob` mapping internally. So such URLs are short, but allow to access the `Blob`. +`URL.createObjectURL`로 만든 URL마다 브라우저는 URL -> `Blob` 매핑을 내부적으로 저장하므로 짧은 URL로 `Blob`에 접근할 수 있게 됩니다. -A generated URL (and hence the link with it) is only valid within the current document, while it's open. And it allows to reference the `Blob` in ``, ``, basically any other object that expects an url. +생성된 URL(링크 포함)은 현재 열려있는 document 안에서만 유효하며 ``, `` 등 기본적으로 URL이 들어가는 모든 객체에서 `Blob`을 참조할 수 있습니다. -There's a side-effect though. While there's a mapping for a `Blob`, the `Blob` itself resides in the memory. The browser can't free it. +그러나 부작용이 있습니다. `Blob`으로 매핑이 있기 때문에 `Blob` 자체는 메모리에 존재합니다. 브라우저는 메모리를 해제하지 못합니다. -The mapping is automatically cleared on document unload, so `Blob` objects are freed then. But if an app is long-living, then that doesn't happen soon. +매핑은 document가 언로드될 때 자동으로 정리되고 `Blob` 객체도 그때 해제됩니다. 만약 앱이 오랫동안 살아있다면 곧바로 해제되지는 않습니다. -**So if we create a URL, that `Blob` will hang in memory, even if not needed any more.** +**따라서 URL을 생성하면 더는 필요하지 않더라도 `Blob`은 메모리에 계속 있게 됩니다.** -`URL.revokeObjectURL(url)` removes the reference from the internal mapping, thus allowing the `Blob` to be deleted (if there are no other references), and the memory to be freed. +`URL.revokeObjectURL(url)`은 내부 매핑에서 참조를 제거하므로 `Blob`이 삭제되고(다른 참조가 없는 경우) 메모리가 해제됩니다. -In the last example, we intend the `Blob` to be used only once, for instant downloading, so we call `URL.revokeObjectURL(link.href)` immediately. +마지막 예제에서는 즉시 다운로드에 `Blob`을 딱 한 번만 사용하기 위해 `URL.revokeObjectURL(link.href)`을 바로 호출합니다. -In the previous example with the clickable HTML-link, we don't call `URL.revokeObjectURL(link.href)`, because that would make the `Blob` url invalid. After the revocation, as the mapping is removed, the URL doesn't work any more. +클릭 가능한 HTML 링크가 있는 이전 예제에서는 `Blob` URL을 유효하게 두기 위해 `URL.revokeObjectURL(link.href)`을 호출하지 않았습니다. 폐기되어 매핑이 삭제되면 URL은 더이상 동작하지 않습니다. -## Blob to base64 +## Blob에서 base64로 -An alternative to `URL.createObjectURL` is to convert a `Blob` into a base64-encoded string. +`URL.createObjectURL` 대신 `Blob`을 base64 인코딩 문자열로 변환할 수 있습니다. -That encoding represents binary data as a string of ultra-safe "readable" characters with ASCII-codes from 0 to 64. And what's more important -- we can use this encoding in "data-urls". +이 인코딩은 이진 데이터를 0부터 64까지의 ASCII 코드로 구성된 매우 안전한 "읽을 수 있는" 문자열로 나타냅니다. 그리고 더 중요한 것은 이 인코딩을 "data-urls"에서 사용할 수 있다는 것입니다. -A [data url](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs) has the form `data:[][;base64],`. We can use such urls everywhere, on par with "regular" urls. +[data url](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs) 형식은 `data:[][;base64],`입니다. 이러한 URL은 '일반' URL과 동등하게 모든 곳에서 사용할 수 있습니다. -For instance, here's a smiley: +다음은 웃는 얼굴 예제입니다. ```html ``` -The browser will decode the string and show the image: +브라우저는 문자열을 디코딩하고 다음 이미지를 표시합니다. -To transform a `Blob` into base64, we'll use the built-in `FileReader` object. It can read data from Blobs in multiple formats. In the [next chapter](info:file) we'll cover it more in-depth. +`Blob`을 base64로 변환하기 위해 내장 객체 `FileReader`를 사용합니다. Blob에서 데이터를 여러 형식으로 읽을 수 있습니다. [다음 챕터](info:file)에서 더 자세히 다룹니다. -Here's the demo of downloading a blob, now via base-64: +다음은 이제 base-64를 통해 blob을 다운로드하는 데모입니다. ```js run let link = document.createElement('a'); link.download = 'hello.txt'; @@ -142,79 +142,79 @@ let blob = new Blob(['Hello, world!'], {type: 'text/plain'}); *!* let reader = new FileReader(); -reader.readAsDataURL(blob); // converts the blob to base64 and calls onload +reader.readAsDataURL(blob); // blob을 base64로 변환하고 언로드를 호출 */!* reader.onload = function() { - link.href = reader.result; // data url + link.href = reader.result; // 데이터 URL link.click(); }; ``` -Both ways of making an URL of a `Blob` are usable. But usually `URL.createObjectURL(blob)` is simpler and faster. +`Blob` URL을 만드는 두 가지 방법 모두 사용할 수 있지만 보통 `URL.createObjectURL(blob)`이 더 간단하고 빠릅니다. -```compare title-plus="URL.createObjectURL(blob)" title-minus="Blob to data url" -+ We need to revoke them if care about memory. -+ Direct access to blob, no "encoding/decoding" -- No need to revoke anything. -- Performance and memory losses on big `Blob` objects for encoding. +```compare title-plus="URL.createObjectURL(blob)" title-minus="Blob을 data URL로 사용하기" ++ 메모리를 관리해야 한다면 폐기 필요 ++ 'encoding/decoding' 없이 Blob으로 직접 액세스 +- 아무것도 폐기할 필요 없음 +- 큰 `Blob` 객체를 인코딩하기 위하여 성능 및 메모리 손실 ``` -## Image to blob +## 이미지를 Blob으로 만들기 -We can create a `Blob` of an image, an image part, or even make a page screenshot. That's handy to upload it somewhere. +이미지, 이미지의 일부, 심지어 페이지 스크린샷으로도 `Blob`을 만들 수 있습니다. 어딘가에 업로드할 때 편리합니다. -Image operations are done via `` element: +이미지 작업은 `` 요소를 통해 수행됩니다. -1. Draw an image (or its part) on canvas using [canvas.drawImage](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage). -2. Call canvas method [.toBlob(callback, format, quality)](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob) that creates a `Blob` and runs `callback` with it when done. +1. [canvas.drawImage](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage) 를 사용하여 캔버스에 이미지를(또는 그 일부를) 그립니다. +2. `Blob`을 실행하고 완료되면 `callback`을 실행하는 canvas 메소드 [.toBlob(callback, format, quality)](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob)를 호출합니다. -In the example below, an image is just copied, but we could cut from it, or transform it on canvas prior to making a blob: +아래 예제는 단순히 이미지 복사만 하지만 Blob을 만들기 전에 Canvas에서 잘라내거나 변형시킬 수도 있습니다. ```js run -// take any image +// 아무 이미지나 가져옵니다 let img = document.querySelector('img'); -// make of the same size +// 동일 크기의 를 만듭니다 let canvas = document.createElement('canvas'); canvas.width = img.clientWidth; canvas.height = img.clientHeight; let context = canvas.getContext('2d'); -// copy image to it (this method allows to cut image) +// 이미지를 복사합니다(이 메소드로 이미지를 자를 수 있습니다). context.drawImage(img, 0, 0); -// we can context.rotate(), and do many other things on canvas +// context.rotate() 등 많은 것을 canvas에서 할 수 있습니다 -// toBlob is async opereation, callback is called when done +// toBlob은 비동기 작업이며 완료되면 콜백이 호출됩니다 canvas.toBlob(function(blob) { - // blob ready, download it + // Blob이 준비되어 다운로드합니다 let link = document.createElement('a'); link.download = 'example.png'; link.href = URL.createObjectURL(blob); link.click(); - // delete the internal blob reference, to let the browser clear memory from it + // 내부 Blob 참조를 삭제하여 브라우저가 메모리를 지우도록 합니다 URL.revokeObjectURL(link.href); }, 'image/png'); ``` -If we prefer `async/await` instead of callbacks: +콜백 대신 `async/await`를 선호한다면, ```js let blob = await new Promise(resolve => canvasElem.toBlob(resolve, 'image/png')); ``` -For screenshotting a page, we can use a library such as . What it does is just walks the page and draws it on ``. Then we can get a `Blob` of it the same way as above. +페이지 스크린샷을 찍을 때 같은 라이브러리를 사용할 수 있으며 페이지를 돌아다니다가 ``에 그려줍니다. 그러면 페이지 스크린샷의 `Blob`을 위와 같은 방식으로 얻을 수 있습니다. -## From Blob to ArrayBuffer +## Blob에서 ArrayBuffer로 -The `Blob` constructor allows to create a blob from almost anything, including any `BufferSource`. +`Blob` 생성자에서는 `BufferSource`를 포함하여 거의 모든 것으로부터 Blob을 만들 수 있습니다. -But if we need to perform low-level processing, we can get the lowest-level `ArrayBuffer` from it using `FileReader`: +그러나 저수준 처리를 수행해야 하는 경우 `FileReader`를 사용하여 Blob으로부터 가장 저수준 형태인 `ArrayBuffer`을 얻을 수 있습니다. ```js -// get arrayBuffer from blob +// blob에서 arrayBuffer 얻기 let fileReader = new FileReader(); *!* @@ -227,15 +227,15 @@ fileReader.onload = function(event) { ``` -## Summary +## 요약 -While `ArrayBuffer`, `Uint8Array` and other `BufferSource` are "binary data", a [Blob](https://www.w3.org/TR/FileAPI/#dfn-Blob) represents "binary data with type". +`ArrayBuffer`, `Uint8Array`, 그 밖의 다른 `BufferSource`는 그냥 "이진 데이터"이지만 [Blob](https://www.w3.org/TR/FileAPI/#dfn-Blob)은 "타입을 가진 이진 데이터"입니다. -That makes Blobs convenient for upload/download operations, that are so common in the browser. +이런 이유로 Blob은 브라우저에서 매우 일반적인 업로드/다운로드 작업에 편리합니다. -Methods that perform web-requests, such as [XMLHttpRequest](info:xmlhttprequest), [fetch](info:fetch) and so on, can work with `Blob` natively, as well as with other binary types. +웹 요청을 수행하는 [XMLHttpRequest](info:xmlhttprequest), [fetch](info:fetch) 등과 같은 메소드에서는 다른 이진 타입과 마찬가지로 `Blob`도 기본적으로 함께 사용할 수 있습니다. -We can easily convert betweeen `Blob` and low-level binary data types: +`Blob`은 저수준 이진 데이터 타입은 서로 쉽게 변환할 수 있습니다. -- We can make a Blob from a typed array using `new Blob(...)` constructor. -- We can get back `ArrayBuffer` from a Blob using `FileReader`, and then create a view over it for low-level binary processing. +- `new Blob(...)` 생성자를 사용하여 형식화 배열을 Blob으로 만들 수 있습니다. +- `FileReader`를 사용하면 Blob을 도로 `ArrayBuffer`로 얻어 저수준 이진 처리를 위한 뷰를 생성할 수 있습니다.