2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[JavaScript] ImageBitmap について

Last updated at Posted at 2023-12-16

JavaScript の Canvas で画像を扱うとき、ImageBitmap にすることで描画の遅延を減らすことができます。

ただし、ImageBitmap はメモリ消費が大きい場合があるため、注意が必要です (※具体的な扱い方は後述) 。

ImageData は CORS によって取得できないことがありますが、ImageBitmap は取得できます。

参考「ImageBitmap - Web API | MDN
参考「OffscreenCanvas: transferToImageBitmap() method - Web APIs | MDN

1. 生成

1.1. createImageBitmap() 関数

一般的な画像ソースから ImageBitmap を生成するには createImageBitmap() 関数を用います。

OffscreenCanvas の場合
const offscreenCanvas = new OffscreenCanvas(300, 150);

// ...

const imageBitmap = await createImageBitmap(offscreenCanvas);
HTMLCanvasElement の場合
const canvas = document.createElement('canvas');

// ...

const imageBitmap = await createImageBitmap(canvas);

※他にも createImageBitmap() 関数が使える型があります。

位置や大きさ等を指定することもできます。

OffscreenCanvas の場合
const offscreenCanvas = new OffscreenCanvas(300, 150);

// ...

const imageBitmap = await createImageBitmap(offscreenCanvas, 100, 0, 100, 75);

※他の操作に関しては公式ドキュメント等参照。

参考「createImageBitmap() - Web API | MDN

1.2. transferToImageBitmap() メソッド

OffscreenCanvas から ImageBitmap を取得して OffscreenCanvas を初期化するには transferToImageBitmap() メソッドを用います。

const offscreenCanvas = new OffscreenCanvas(300, 150);

// ...

const imageBitmap = offscreenCanvas.transferToImageBitmap();

参考「OffscreenCanvas: transferToImageBitmap() method - Web APIs | MDN

※後述する transferFromImageBitmap() メソッドは transferToImageBitmap() メソッドと異なり、通常の HTMLCanvasElement でも使用可能です。
transferToImageBitmap()OffscreenCanvas 型のメソッドですが、transferFromImageBitmap()ImageBitmapRenderingContext 型のメソッドです。

1.3. createImageBitmap() 関数と transferToImageBitmap() メソッドの違い

OffscreenCanvas に関しては createImageBitmap() 関数でも transferToImageBitmap() メソッドでも ImageBitmap を得ることができますが、以下の表のような違いがあります。

createImageBitmap() 関数 transferToImageBitmap() メソッド
画像ソースの型 HTMLImageElement
SVGImageElement
HTMLVideoElement
HTMLCanvasElement
Blob
ImageData
ImageBitmap
OffscreenCanvas
OffscreenCanvas
画像ソースの扱い そのまま 初期化
位置や大きさ等を指定 不可
処理方法 非同期 同期

2. 描画および破棄

2.1. transferFromImageBitmap() メソッド

HTMLCanvasElement または OffscreenCanvasImageBitmap 全体を描画して ImageBitmap を破棄するには transferFromImageBitmap() メソッドを用います。

HTMLCanvasElement の場合
const context = canvas.getContext('bitmaprenderer');

context.transferFromImageBitmap(imageBitmap);
OffscreenCanvas の場合
const offscreenContext = offscreenCanvas.getContext('bitmaprenderer');

offscreenContext.transferFromImageBitmap(imageBitmap);

ちなみに、Canvas と大きさが一致しない ImageBitmaptransferFromImageBitmap() メソッドで描画すると内部的には ImageBitmap の大きさで扱われますが、Canvas の width および height は更新されないため注意が必要です。

// 
const offscreenCanvasA = new OffscreenCanvas(300, 300);

const imageBitmapA = await createImageBitmap(offscreenCanvasA);
console.log(imageBitmapA.width, imageBitmapA.height);

// 
const offscreenCanvasB = new OffscreenCanvas(300, 150);
const offscreenContextB = offscreenCanvasB.getContext('bitmaprenderer');

offscreenContextB.transferFromImageBitmap(imageBitmapA);
console.log(offscreenCanvasB.width, offscreenCanvasB.height);

const imageBitmapB = await createImageBitmap(offscreenCanvasB);
console.log(imageBitmapB.width, imageBitmapB.height);
実行結果
300 300
300 150
300 300

transferFromImageBitmap() メソッドは transferToImageBitmap() メソッドと異なり、通常の HTMLCanvasElement でも使用可能です。
transferToImageBitmap()OffscreenCanvas 型のメソッドですが、transferFromImageBitmap()ImageBitmapRenderingContext 型のメソッドです。

参考「ImageBitmapRenderingContext: transferFromImageBitmap() method - Web APIs | MDN

2.2. close() メソッド

drawImage() メソッド等、transferFromImageBitmap() メソッド以外でも ImageBitmap を描画することができますが、その場合は ImageBitmap が破棄されないため、close() メソッドを呼ぶことで明示的に破棄します。

HTMLCanvasElement の場合
const context = canvas.getContext('2d');

context.drawImage(imageBitmap, 0, 0);
imageBitmap.close();
OffscreenCanvas の場合
const offscreenContext = offscreenCanvas.getContext('2d');

offscreenContext.drawImage(imageBitmap, 0, 0);
imageBitmap.close();

参考「CanvasRenderingContext2D: drawImage() メソッド - Web API | MDN
参考「WebGLRenderingContext: texImage2D() method - Web APIs | MDN

参考「ImageBitmap.close() - Web API | MDN

2.3. transferFromImageBitmap() メソッドと drawImage() メソッドの違い

transferFromImageBitmap() メソッドでも drawImage() メソッドでも ImageBitmap を描画することができますが、以下の表のような違いがあります。

transferFromImageBitmap() メソッド drawImage() メソッド
Context の型 ImageBitmapRenderingContext CanvasRenderingContext2D
画像ソースの型 ImageBitmap HTMLImageElement
SVGImageElement
HTMLVideoElement
HTMLCanvasElement
ImageBitmap
OffscreenCanvas
VideoFrame
画像ソースの扱い 破棄 そのまま
位置や大きさ等を指定 不可

3. ImageBitmap を使うべきでない状況

頻繁に ImageBitmap を生成しつつ drawImage() メソッドで描画するような使い方だと ImageBitmap の恩恵を得にくいため、直接 Canvas を drawImage() メソッドで描画した方が良いです。

const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');

const offscreenCanvas = new OffscreenCanvas(300, 150);

// ...

context.drawImage(offscreenCanvas, 0, 0);

参考「CanvasRenderingContext2D: drawImage() メソッド - Web API | MDN
参考「WebGLRenderingContext: texImage2D() method - Web APIs | MDN

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?