2017-03-15 19 views
-1

グラフィックスオブジェクトに何かを描画するように指示すると、何が起こるのかをよりよく理解したいと思っています。より具体的にはどのようにGDI +画像のピクセルの色を設定します。GDI +はバイト配列のイメージでどのように機能しますか?

ソースコードを検索しましたが、明らかにまだリリースされていません(実際には、https://referencesource.microsoft.comの回答を検索した後、.dllが実際の図面を処理することが判明しました)。

この全体のポイントは、描画するときにピクセルの色を変更する独自の方法を定義できるようにすることです。

私はこのコードの正しい軌道に乗っていますかどうかわからないです:

ここ
public unsafe Bitmap enlargeImg(Bitmap source, int newWidth, int newHeight) 
    { 
     int resMod = (int)Math.Min(newWidth/source.Width, newHeight/source.Height); 
     Bitmap res = new Bitmap(source.Width * resMod, source.Height * resMod, System.Drawing.Imaging.PixelFormat.Format32bppPArgb); 
     Graphics larGfx = Graphics.FromImage(res); 
     SolidBrush br; 
     int pxsz = 4;//for 32 bits per pixel 
     System.Drawing.Imaging.BitmapData btd = source.LockBits(
      new Rectangle(0, 0, source.Width, source.Height), 
      System.Drawing.Imaging.ImageLockMode.ReadOnly, source.PixelFormat); 
     for (int r = 0; r < source.Height; r++) 
     { 
      byte* bfrw = (byte*)btd.Scan0 + r * btd.Stride; 
      for (int c = 0; c < source.Width; c++) 
      { 
       byte B = bfrw[c * pxsz + 0]; 
       byte G = bfrw[c * pxsz + 1]; 
       byte R = bfrw[c * pxsz + 2]; 
       byte A = bfrw[c * pxsz + 3]; 
       br = new SolidBrush(Color.FromArgb(A, R, G, B)); 
       larGfx.FillRectangle(br, c * resMod, r * resMod, resMod, resMod); 
      } 
     } 
     source.UnlockBits(btd); 
     return res; 
    } 

私は、画像をスキャンし、各画素が大きくなっている新しい画像を描画してみてください。しかし、これは単に画像のサイズをGraphics.DrawImageとするよりもはるかに遅いです。はい、私はSetPixelを試しましたが、それは軽い年の遅いです。

私は2Dゲームエンジンのためにこれをやっているので(ゲームサイクルがあるので)、できるだけ速くする必要があります。

GDI +はどのようにイメージのバイト配列で動作しますか?

+0

これを試してください:https://github.com/LuizZak/FastBitmap – Trey

+0

できるだけ速くする必要がある場合は、おそらくGDI/.netが最悪の組み合わせかもしれません。 – Aron

+0

@Aron私は知らない、私は多くの悪い方法を考えることができます。 – Abion47

答えて

0

以下の方法は、はるかに高速になります。

  • 最初元の同じサイズのビットマップ上の色(だけ各色用の1つの画素を変更する必要があるように)変更 - または変更をそれが許可されている場合、元の色。色を変更するには、元のビットマップのバイトを読み取るのと同じように、2番目(または元の)ビットマップのバッファで直接作業します。つまり、B G R A bytesをイメージバッファに直接書き込んでください。

  • StretchBltを使用して、更新された色のビットマップをより大きなものにコピーします。これによりピクセルが大きくなります。

このようにして、内部ループに高価なnew SolidBrush()を避けることもできます。

また、ビットマップの色を変更するには、すべてのピクセルにわたって単一のループを使用できます(つまり、ビットマップを1つの大きな1D配列として扱うことができます)。この方法で、内部ループ内の乗算を排除することもできます(最初から最後までバイトをループするだけです)。

関連する問題