0
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.

UWP SoftwareBitmapの画素データをbyte配列に格納する

Last updated at Posted at 2022-11-16

実現したい内容

画像について、画素(ピクセル)の情報の確認や、色や明るさなどの変更を行いたい。そのため、SoftwareBitmapで管理する画像の画素情報をbyte配列に格納し、BGRAの操作をできるようにする。

対処その1

SoftwareBitmapから、WritableBitmapIBufferにデータをコピーし、IBufferからstreamを介して、byte配列に読み込む。

Microsoft DocsのSoftwareBitmap.CopyToBuffer()のRemarksをヒントにした方法

WriteableBitmapのIBufferを活用
WriteableBitmap wb = new WriteableBitmap(_SourceBitmap.PixelWidth, _SourceBitmap.PixelHeight);

using (SoftwareBitmap sb = SoftwareBitmap.Copy(_SourceBitmap))
{
    sb.CopyToBuffer(wb.PixelBuffer);
}

int n = (int)wb.PixelBuffer.Length;
_SourceByteArray = new byte[n];

using (Stream stream = wb.PixelBuffer.AsStream())
{
    await stream.ReadAsync(_SourceByteArray,0,n);
}
  • _SourceBitmap: コピー元のSoftwareBitmap
  • _SourceByteArray: コピー先のbyte配列

逆手順:byte配列からSoftwareBitmapの生成

同様にWritableBitmapを用いて逆の手順を実現できる。

WriteableBitmapIBufferstreamを介してbyte配列からデータを読み込み、IBufferからSoftwareBitmapにデータをコピーする。

byte配列からSoftwareBitmapを生成
WriteableBitmap wb = new WriteableBitmap(w, h);
SoftwareBitmap tgt = new SoftwareBitmap(BitmapPixelFormat.Bgra8, w, h);

using (var stream = wb.PixelBuffer.AsStream())
{
    await stream.WriteAsync(_TargetByteArray, 0, _TargetByteArray.Length);
    tgt.CopyFromBuffer(wb.PixelBuffer);
    _TargetBitmap = SoftwareBitmap.Copy(tgt);
}
  • _TargetByteArray: コピー元のbyte配列
  • _TargetBitmap: コピー先のSoftwareBitmap

対処その2

以前、やや苦し紛れに書いたもの。対処その1より効率は落ちると思うが、何らか別の用途があるかもしれない。

  • SoftwareBitmapBitmapEncoderにセットしstreamに書き出し。
  • streamを用いてBitmapDecoderを生成。
  • BitmapDecoderからPixelDataProviderを生成。
  • PixelDataProviderからbyte配列を得る。
BitmapEncoder,BitmapDecoderを活用
using (SoftwareBitmap sb = SoftwareBitmap.Copy(_SourceBitmap))
{
    BitmapEncoder encoder;
    InMemoryRandomAccessStream ras = new InMemoryRandomAccessStream();
    encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, ras);
    encoder.SetSoftwareBitmap(sb);

    try
    {
        await encoder.FlushAsync();
    }
    catch (Exception e)    {
        Debug.WriteLine("err in encoding image: {0}", e.Message);
        return 0;
    }

    ras.Seek(0);

    BitmapDecoder decoder;
    decoder = await BitmapDecoder.CreateAsync(BitmapDecoder.BmpDecoderId, ras);
    PixelDataProvider provider = await decoder.GetPixelDataAsync();

    _SourceByteArray = provider.DetachPixelData();
}
  • _SourceBitmap: コピー元のSoftwareBitmap
  • _SourceByteArray: コピー先のbyte配列
0
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
0
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?