pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/javascript-tutorial/ja.javascript.info/blob/master/4-binary/03-blob/article.md

ja.javascript.info/4-binary/03-blob/article.md at master · javascript-tutorial/ja.javascript.info · GitHub
Skip to content

Latest commit

 

History

History
240 lines (155 loc) · 12 KB

File metadata and controls

240 lines (155 loc) · 12 KB

Blob

ArrayBuffer とビューは ECMA 規格、JavaScript の一部です。

ブラウザには、さらに File API に記載されている高水準のオブジェクトがあります。特に Blob です。

Blob はオプションの文字列 type (通常は MIMEタイプ) と blobParts -- 一連の他の Blob オブジェクト、文字列や BufferSources から構成されます。

コンストラクタの構文は次の通りです:

new Blob(blobParts, options);
  • blobPartsBlob/BufferSource/String の値の配列です
  • options オプションのオブジェクト:
    • type -- blob タイプ, 通常は例えば image/png のような MIME タイプです,
    • endings -- blob が現在の OS の改行(\r\n or \n)に対応するように行末を変換するかどうかを意味します。デフォルトでは "transparent" (何もしません)ですが、 "native" (変換する)にすることもできます。

例:

// 文字列から Blob を作成します
let blob = new Blob(["<html>…</html>"], {type: 'text/html'});
// 注意してください: 最初の引数は配列である必要があります
// 型付き配列と文字列から Blob を作成します
let hello = new Uint8Array([72, 101, 108, 108, 111]); // 二進での "hello"

let blob = new Blob([hello, ' ', 'world'], {type: 'text/plain'});

blob の一部を抽出することもできます:

blob.slice([byteStart], [byteEnd], [contentType]);
  • byteStart -- 開始バイト、デフォルトは 0。
  • byteEnd -- 最後のバイト(このバイトは含みません。デフォルトは最後までです).
  • contentType -- 新しい blob の type です。デフォルトは元と同じになります。

引数は array.slice に似ており、負の値も許可されます。

blob のデータを直接変更することはできませんが、blob の一部を切り出したり、それらから新しい blob を作成したり、それらを新しい blob にミックスしたりすることはできます。

この振る舞いは JavaScript の文字列に似ています: 文字列内の文字を変えることはできませんが、訂正した新しい文字列を作成することはできます。

URL としての Blob

Blob はその内容を表示するのに、<a>, <img> や他のタグの URL として簡単に使うことができます。

type のおかげで blob をダウンロード/アップロードすることも可能で、それはネットワークリクエストではもちろん Content-Type になります。

簡単例から始めてみましょう。リンクをクリックすると、hello world の内容をもつ、動的に生成された blob をファイルとしてダウンロードします。:

<!-- download 属性は、ブラウザは移動する代わりにダウンロードを行います -->
<a download="hello.txt" href='#' id="link">Download</a>

<script>
let blob = new Blob(["Hello, world!"], {type: 'text/plain'});

link.href = URL.createObjectURL(blob);
</script>

また、JavaScript で動的にリンクを作成し、link.click() によりクリックをシミュレートすることもできます。すると、ダウンロードは自動的に始まります。

これは HTML なしで、動的に生成された Blob を利用者にダウンロードさせる類似のコードです:

let link = document.createElement('a');
link.download = 'hello.txt';

let blob = new Blob(['Hello, world!'], {type: 'text/plain'});

link.href = URL.createObjectURL(blob);

link.click();

URL.revokeObjectURL(link.href);

URL.createObjectURL は blob を取り、blob:<origen>/<uuid> という形式の一意なURLを生成します。

これは、link.href の値がどのように見えるかの例です:

blob:https://javascript.info/1e67e00e-860d-40a5-89ae-6ab0cbee6273

URL.createObjectURL により生成された各 URL に対して、ブラウザは url -> blob のマッピングを内部に格納します。そのため、url は短いですが、blob にアクセスすることができます。

生成された url (とそれへのリンク)は現在のドキュメント内で、かつ開いている間のみ有効です。それにより、<img>, <a> 、基本的に url を想定するあらゆるオブジェクトで blob を参照することができます。

しかし、副作用もあります。blob のマッピングがある間、blob 自身はメモリ内に存在し続けます。ブラウザはそれを解放することはできません。

マッピングは、ドキュメントがアンロードされると自動的にクリアされ、blob もそのとき解放されます。しかしアプリケーションの寿命が長ければ、すぐにはそれは起きません。

したがって、URL を作成すると、それ以上必要なくなっても、blob はメモリに溜まります。

URL.revokeObjectURL(url) は内部のマッピングから参照を削除します。これにより blob が削除され(他に参照がない場合)、メモリを解放することができます。

最後の例では、blob は即時ダウンロードのために、一度だけ使われることを意図しているので、すぐに URL.revokeObjectURL(link.href) を呼び出します。

しかし、クリック可能な HTML リンクのある前の例では、URL.revokeObjectURL(link.href) を呼び出しません。なぜなら、これは blob url を無効にするからです。失効後は、マッピングが削除されているので、url は機能しなくなります。

Blob を base64 にする

URL.createObjectURL の代替は blob を base64 エンコードされた文字列に変換する方法です。

このエンコーディングは、0 から 64 までの ASCII コードを用いて、バイナリデータを安全で "読み出し可能な" 文字列として表現します。そしてより重要なことは、"data-url" でこのエンコーディングが使用できることです。

data urldata:[<mediatype>][;base64],<data> の形式です。このような url は "通常の" url と同等に、あらゆる場所で使用することができます。

例えば、これはスマイリーです:

<img src="data:image/png;base64,R0lGODlhDAAMAKIFAF5LAP/zxAAAANyuAP/gaP//github.com/wAAAAAAACH5BAEAAAUALAAAAAAMAAwAAAMlWLPcGjDKFYi9lxKBOaGcF35DhWHamZUW0K4mAbiwWtuf0uxFAgA7">

ブラウザは文字列をデコードし、イメージを表示します:

blob を base64 に変換するためには、組み込みの FileReader オブジェクトを使用します。それは複数のフォーマットで blob からデータを読むことができます。次のチャプターでは、より詳しく説明します。

これは、blob をダウンロードするで、base64 経由です:

let link = document.createElement('a');
link.download = 'hello.txt';

let blob = new Blob(['Hello, world!'], {type: 'text/plain'});

*!*
let reader = new FileReader();
reader.readAsDataURL(blob); // blob を base64 へ変換し onnload を呼び出します
*/!*

reader.onnload = function() {
  link.href = reader.result; // data url
  link.click();
};

blob の URL を作成する方法は両方とも使用可能です。しかし、通常は URL.createObjectURL(blob) がよりシンプルで速いです。

+ メモリを気にする場合は、無効にする必要があります。
+ blob への直接アクセス、"encoding/decoding" はありません。
- 何も無効にする必要はありません。
- 巨大な blob のエンコーディングでは、パフォーマンスとメモリを失います。

Image を blob にする

画像、画像の一部、あるいはページのスクリーンショットの blob を作成することもできます。どこかにアップロードするときに便利です。

画像操作は <canvas> 要素を通して行われます:

  1. canvas.drawImage を使って、canvas 上で画像(または一部)を書きます。
  2. blob を作成し、完了時に callback を実行する canvas メソッド .toBlob(callback, format, quality) を呼び出します。

下記の例では、画像を単にコピーしていますが、blob を作成する間に canvas 上で切り取ったり変形させることができます。:

// 画像を取ります
let img = document.querySelector('img');

// 同じサイズの <canvas> を作ります
let canvas = document.createElement('canvas');
canvas.width = img.clientWidth;
canvas.height = img.clientHeight;

let context = canvas.getContext('2d');

// 画像をコピーします (このメソッドで画像をカットすることができます)
context.drawImage(img, 0, 0);
// canvas 上では、context.rotate(), やその他様々なことができます

// toBlob は非同期操作で、callback は完了時に呼ばれます
canvas.toBlob(function(blob) {
  // blob の準備ができたのでダウンロードします
  let link = document.createElement('a');
  link.download = 'example.png';

  link.href = URL.createObjectURL(blob);
  link.click();

  // ブラウザがメモリをクリアできるよう、内部の blob への参照を削除します。
  URL.revokeObjectURL(link.href);
}, 'image/png');

コールバックより async/await を好む場合は次のようになります:

let blob = await new Promise(resolve => canvasElem.toBlob(resolve, 'image/png'));

ページをスクリーンショットするには、https://github.com/niklasvh/html2canvas のようなライブラリが使えます。これがしていることは、単にページを見て <canvas> 上にそれを描いているだけです。そして、上と同じ方法でその blob を取得することができます。

Blob から ArrayBuffer へ

Blob コンストラクタは、BufferSource を含め、ほぼ何からでも blob を作成することができます。

しかし、低レベルの処理を実行する必要がある場合、FileReader を使って、最も低レベルである ArrayBuffer を取得することもできます。:

// blob から arrayBuffer を取得
let fileReader = new FileReader();

*!*
fileReader.readAsArrayBuffer(blob);
*/!*

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

サマリ

ArrayBuffer, Uint8Array やその他の BufferSource が "バイナリデータ" である一方、Blob は "タイプを持つバイナリデータ" を表します。

これは Blob のアップロード/ダウンロード操作を便利にし、ブラウザでは一般的です。

XMLHttpRequest, fetch などの webリクエストを行うメソッドは、他のバイナリタイプと同様に、Blob をネイティブに使用することができます。

Blob と低レベルのバイナリデータ型の間の変換は容易に行うことができます。:

  • new Blob(...) コンストラクタを使用して、型付き配列から Blob を作成することができます。
  • FileReader を使用して、Blob から ArrayBuffer に戻すことができ、低レベルのバイナリ処理のためにビューを作成することもできます。
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy