画像を編集する方法 (HTML)
[ この記事は、Windows ランタイム アプリを作成する Windows 8.x および Windows Phone 8.x 開発者を対象としています。Windows 10 向けの開発を行っている場合は、「最新のドキュメント」をご覧ください]
ここでは、既にある画像を BitmapEncoder で編集する方法について説明します。BitmapEncoder を使うと、変換 (拡大/縮小、トリミングなど) を適用したり、メタデータやプロパティを設定したりできるほか、必要なピクセルだけを編集して、それ以外のデータをすべて維持することができます。ここでは、原本となる画像データで BitmapEncoder を初期化し、編集操作を適用した後、保存して元のファイルを更新する方法を紹介します。
BitmapEncoder を使って新しい画像をゼロから作成することもできます。詳しくは、「新しい画像をエンコードする方法」をご覧ください。
理解しておく必要があること
テクノロジ
必要条件
- JavaScript を使った基本的な Windows ランタイム アプリを作成できることを前提としています。詳しくは、「JavaScript を使った初めての Windows ランタイム アプリの作成」をご覧ください。
- BitmapDecoder オブジェクトが必要です。「画像をデコードする方法」では、この処理について説明しています。
手順
ステップ 1: 元の画像からデコーダー オブジェクトを取得する
編集する画像ファイルから初期化された BitmapEncoder オブジェクトと、そのファイルから開いた IRandomAccessStream を受け取る関数の先頭部分を記述します。この例では元の画像を上書きするので、ReadWrite 特権で開いたストリームを使う必要があります。
function (decoder, fileStream) {
注 デコーダーとストリーム オブジェクトを取得する方法については、「画像をデコードする方法」をご覧ください。
OpenAsync を呼び出す際、必ず、FileAccessMode パラメーターを ReadWrite に変更してください。
ステップ 2: 編集対象のエンコーダー オブジェクトを初期化する
エンコーディングの出力先として InMemoryRandomAccessStream を作成し、トランスコードを行う BitmapEncoder を CreateForTranscodingAsync メソッドで作成します。
InMemoryRandomAccessStream は、エンコードしたファイルの一時的な格納場所として使います。そのようにしないと、同じストリームへの読み取りと書き込みをデコーダーとエンコーダーが同時に行うこととなり、正常に機能しません。
// Keep variables in-scope across multiple async
var memStream = new Windows.Storage.Streams.InMemoryRandomAccessStream();
var encoder;
Windows.Graphics.Imaging.BitmapEncoder
.createForTranscodingAsync(memStream, decoder).then(function (_encoder) {
encoder = _encoder;
注 CreateForTranscodingAsync では、元のファイルと同じ形式の画像に対してのみ、データのコピーがサポートされます。形式の異なるファイルの変換はできません。
これで、ソースの BitmapDecoder のデータで初期化した BitmapEncoder ができました。
ステップ 3: 画像の変換
作成したエンコーダーを使って、メタデータやピクセル データの設定など、さまざまな操作を実行できます。この例では、BitmapTransform メソッドを使って画像の拡大/縮小と回転を行います。メタデータの設定について詳しくは、「イメージ メタデータを書き込む方法」をご覧ください。ピクセル データの設定について詳しくは、「新しい画像をエンコードする方法」をご覧ください。
// Scaling occurs before flip/rotation.
encoder.bitmapTransform.scaledWidth = 640;
encoder.bitmapTransform.scaledHeight = 480;
// Fant is a relatively high quality interpolation algorithm.
encoder.bitmapTransform.interpolationMode =
Windows.Graphics.Imaging.BitmapInterpolationMode.fant;
// Generate a new thumbnail from the updated pixel data.
// Note: Only JPEG, TIFF and JPEG-XR images support encoding thumbnails.
encoder.isThumbnailGenerated = true;
encoder.bitmapTransform.rotation =
Windows.Graphics.Imaging.BitmapRotation.clockwise90Degrees;
注 CreateForTranscodingAsync を使って BitmapEncoder を作成した場合、エンコーダーは、損失の生じない方法で元のデータ全体をコピーしようと試みます。たとえば、JPEG をトランスコードし、一部のイメージング プロパティを編集する (ただし、変換の適用やピクセル データの編集は行わない) 場合、画像が無損失でコピーされます。しかし、デコーダーのピクセル データを取得した後、エンコーダー上にそれを設定して、画像処理を実行すると、ピクセル データの再エンコードが必要になるため、必然的に損失を伴うプロセスになります。
ステップ 4: エンコーダーのフラッシュとエラーの処理
使い終えたエンコーダーは、フラッシュしてエンコーディング操作を完了させる必要があります。また、画像形式がサムネイルのエンコーディングをサポートしていない場合もあり、そのようなケースに対応する処理も必要です。JPEG など、サムネイルを確実にサポートする画像形式だけを編集対象とする場合は、このエラー処理は省略してかまいません。
return encoder.flushAsync();
}).then(null, function (error) {
switch (error.number) {
// If the encoder doesn't support writing a thumbnail, then try again
// but disable thumbnail generation.
case -2003292287: // WINCODEC_ERR_UNSUPPORTEDOPERATION
encoder.isThumbnailGenerated = false;
return encoder.flushAsync();
default:
throw error;
}
ステップ 5: エンコードした画像をファイルに保存し、クリーンアップを行う
最後に、インメモリ ストリームの内容を元のファイルのストリームにコピーし、すべてのストリームを閉じます。
}).then(function () {
// Overwrite the contents of the file with the updated image stream.
memStream.seek(0);
fileStream.seek(0);
fileStream.size = 0;
return Windows.Storage.Streams.RandomAccessStream.copyAsync(memStream, fileStream);
}).done(function () {
memStream.close();
fileStream.close();
});