2016-12-30 59 views
0

System.Drawing.BitmapSystem.Windows.Forms.PictureBoxを使用するC#で書かれた、いくつかの小さなWinFormsアプリケーションは、アプリケーションが時間の経過とともに維持する生のバイトバッファからビットマップを表示します。ある意味では、それは貧しい人のアニメーションに似ています。WPFでのビットマップ描画

私はこれらのアプリケーションをWPFに移植したいと思いますが、変更したくないバイトバッファー書き込みのカスタムロジックがたくさんあります。いくつかのグーグルの後、私はSystem.Windows.Media.Imaging.WriteableBitmapクラスを使ってみましたが、動作させることができませんでした。このクラスはどのように使用されるのですか?私のオリジナルのデザインに合っていますか?ここで

が累積的にビットマップ上のランダムな位置にランダムな色を書き込み、元のWinFormsアプリからの抜粋です:

private void Form1_Load(object sender, EventArgs e) 
{ 
    _timer.Tick += new EventHandler(Timer_Tick); 
    _timer.Interval = 25; 
    _timer.Enabled = true; 
} 

private void Timer_Tick(object sender, EventArgs e) 
{ 
    Animate(); 
} 

private void Animate() 
{ 
    Bitmap bitmap = (Bitmap)pictureBox1.Image; 

    if (bitmap != null) 
    { 
     bitmap.Dispose(); 
    } 

    bitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height); 

    var data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); 

    if (_buffer == null) 
    { 
     _buffer = new byte[data.Stride * bitmap.Height]; 
    } 

    for (int i = 0; i < 1000; i++) 
    { 
     var x = _random.Next(bitmap.Width); 
     var y = _random.Next(bitmap.Height); 

     var red = (byte)_random.Next(byte.MaxValue); 
     var green = (byte)_random.Next(byte.MaxValue); 
     var blue = (byte)_random.Next(byte.MaxValue); 
     var alpha = (byte)_random.Next(byte.MaxValue); 

     _buffer[y * data.Stride + x * 4] = blue; 
     _buffer[y * data.Stride + x * 4 + 1] = green; 
     _buffer[y * data.Stride + x * 4 + 2] = red; 
     _buffer[y * data.Stride + x * 4 + 3] = alpha; 
    } 

    Marshal.Copy(_buffer, 0, data.Scan0, _buffer.Length); 

    bitmap.UnlockBits(data); 

    pictureBox1.Image = bitmap; 
} 
+1

'[(よく文書)を使用しますBitmapSource.Create'](https://msdn.microsoft.com/en-us/library/ms616045(v = vs.110).aspx)メソッドを使用します。 BitmapSourceを['Image']の' Source'プロパティに割り当てます(https://msdn.microsoft.com/en-us/library/system.windows.controls.image(v = vs.110).aspx)コントロール。 – Clemens

+1

私は 'WriteableBitmap'を使ってこれを行う方法について答えを投稿しようとしていましたが、質問は閉じられました。 FWIW、私はここにそれを置く:http://pastebin.com/Ufmx4giD –

+0

ありがとう、@クレメンス。あなたの簡潔な答えが私の足を見つけるのを助けました。 – Jono

答えて

1

すでに既存のコードをしている場合は、私は多分(最も簡単かつ最速はいえ、最速処理していないと思いますあなたが画像を表示する必要がある場合)あなたのコードを維持したBitmapSourceに変換するために、次のようになります。

BitmapImage bmpImage = new BitmapImage(); 
    MemoryStream stream = new MemoryStream(); 
    bitmap.Save(stream, ImageFormat.MemoryBmp); 
    bmpImage.BeginInit(); 
    bmpImage.StreamSource = stream; 
    bmpImage.EndInit(); 
    bmpImage.Freeze(); 

    return bmpImage; 

別のオプション、より効率的になりますが、ポート多くのコードにあなたを必要とするかもしれない、WritableBitmapを使用することです。 Bitmapオブジェクトで行ったのと同じ方法でWritableBitmapを作成し、元のバッキングバッファ(およびIntPtr)にアクセスでき、必要に応じてイメージデータを操作できます。このリンクは、あなたがWritableBitmap必要なすべての情報についてを与える必要があります。 はここWriteableBitmap

は(あなたがあなたの解像度を知っている必要があります注意してください)あなたのケースのための例です:

 WriteableBitmap bitmap = new WriteableBitmap(pictureBox1.Width, pictureBox1.Height, dpi, dpi, System.Windows.Media.PixelFormat.Bgra32, null); 

    if (_buffer == null) 
    { 
    _buffer = new byte[bitmap.BackBufferStride * pictureBox1.Height]; 
    } 

    for (int i = 0; i < 1000; i++) 
    { 
    var x = _random.Next(bitmap.Width); 
    var y = _random.Next(bitmap.Height); 

    var red = (byte)_random.Next(byte.MaxValue); 
    var green = (byte)_random.Next(byte.MaxValue); 
    var blue = (byte)_random.Next(byte.MaxValue); 
    var alpha = (byte)_random.Next(byte.MaxValue); 

    _buffer[y * bitmap.BackBufferStride + x * 4] = blue; 
    _buffer[y * bitmap.BackBufferStride + x * 4 + 1] = green; 
    _buffer[y * bitmap.BackBufferStride + x * 4 + 2] = red; 
    _buffer[y * bitmap.BackBufferStride + x * 4 + 3] = alpha; 
    } 

    bitmap.WritePixels(new System.Windows.Int32Rect(0, 0, bitmap.PixelWidth, bitmap.PixelHeight), 
     _buffer, bitmap.PixelWidth * bitmap.Format.BitsPerPixel/8, 0); 
+0

ありがとうございます。私はあなたとClemensの提案(それぞれWriteableBitmapとBitmapSource.Create)を試してみました。どちらも私の仕事です。 PixelFormats.Bgra32を使用するようにコードサンプルを変更しようとしましたが、私の提案はstackoverflowが私の提案を受け入れるのに十分な長さではありませんでした。私はあなたの最初の提案をまったく試してみませんでした - 私はそれが最初の場所で(*&%^を混乱させたクラスの1つに関係していると思います:) – Jono

関連する問題