2

アプリケーションを展開する前に、アプリケーションのスモーク テストに XP VM と Vista VM を使用しています。これらの VM はどちらも 32 ビット カラーを使用しています。違いがあるかどうかはわかりませんが、VirtualBoxを使用しています。各マシンには、2 GB の RAM、2 つのプロセッサも割り当てられます。XP には 128MB のビデオ RAM、Vista 256 (いずれの場合も、私が設定できる最大値) があります。マシンを実行するデスクトップには、6 コアと 16 GB の RAM があります。繰り返しますが、この情報が関連しているかどうかはわかりませんが、誰が知っていますか.

Bitmap以下は、aを直接操作できる一連のピクセルに変換するために使用する拡張メソッドです。結局のところ、スピードが必要だからです。私たちが必要としているのはスピードです。脂っこい、スピードが速い!そして、Bitmap.GetPixel はそのアンチテーゼです。

public static ArgbColor[] GetPixels(this Bitmap bitmap)
{
  ArgbColor[] results;
  int width;
  int height;
  BitmapData bitmapData;

  width = bitmap.Width;
  height = bitmap.Height;
  results = new ArgbColor[width * height];
  bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);

  unsafe
  {
    ArgbColor* pixelPtr;

    pixelPtr = (ArgbColor*)(void*)bitmapData.Scan0;

    for (int row = 0; row < height; row++)
    {
      for (int col = 0; col < width; col++)
      {
        results[row * width + col] = *pixelPtr;

        pixelPtr++;
      }
    }
  }

  bitmap.UnlockBits(bitmapData);

  return results;
}

このコードは、以前に Windows 8 と Windows 7 を使用していたときと同様に、Windows 8.1 の「実際の」マシンで完全に機能します。

しかし、VM では、「パラメーターが無効です」というメッセージが表示されて失敗します。ArgumentException:

System.Drawing.Bitmap.LockBits(Rectangle rect, ImageLockMode flags, PixelFormat format, BitmapData bitmapData)
System.Drawing.Bitmap.LockBits(Rectangle rect, ImageLockMode flags, PixelFormat format)
Cyotek.Drawing.ImageExtensions.GetPixels(Bitmap bitmap)

ドキュメントによると、これは、PixelFormat 値が特定のピクセルあたりのビット数ではない、 bitmap に対して正しくない PixelFormat が渡されたためです。

これらの VM に VS をインストールしていませんが、イメージを開いてその形式を印刷するテスト プログラムをドロップしました...これは予想どおりでしたPixelFormat.Format32bppArgb。3 つのシステムすべてで同じテスト イメージ セットを使用しています。

私の次の仮定は、VM のビデオ ハードウェアの制限ですが、結局のところ、3D シーンではなくビットマップであるということです...それで作業できるはずだと確信しています。

誰でもこの問題に光を当てることができますか? 「自分のマシンで動作する」ということだけに頼るのではなく、このコードの一部を適切にテストできるようにしたいのですが、とにかく VM に VS をインストールする必要はありません (確信があるわけではありません)。 XPにインストールします(Vistaよりも作業が目に見えて速いため、Vistaよりも好みます))。

他の誰かがこの問題に遭遇し、解決策を持っていることを願っています.Google検索は私を失望させました.

4

1 に答える 1

6

はあ...まあ、私は今この質問に答えることができます、ユーザーエラーです。

VMMap をいじってみましたが、あまり役に立たなかったので、VM に VS をインストールして完全なデバッグを行う前に、コードに追加のチェックを追加してみることにしました。ArgumentException渡された画像が 32 ビット ARGB でないかどうかのチェックを追加しました。結局のところ、開発マシンで例外がスローされましたが、これはやや予想外でした。テストに使用した画像の 1 つは 32 ビット ARGB ではなかったようですが、それでも 32 ビット ARGB にロックされていました。正しいピクセル データが返されたのと同じように、ビットを操作した後に画像が歪んでいることに気付いたと思います。

Windowsの新しいバージョンは、実際にはビットを完全に異なる形式にロックできるようです-単純にPNGを開いて、すべての単一の形式で機能Bitmap.LockBitsするすべての値を呼び出そうとする簡単なテストプログラムでPixelFormat、奇妙なもの(接頭辞が付いていないもの)を除外しますフォーマット付き)。まあ、少なくとも例外はスローされません。私の場合、フォーマットFormat8bppIndexedがロックされた画像Format32bppArgbは正しいピクセルデータを返しました。XP と Vista ではそれができないようで、例外をスローするだけです。私が実際に前者の動作を好むのか後者の動作を好むのかはわかりませんが、明らかに前者の方が便利ですが、ほとんど後者に傾いています。

ソース画像が32ビットARGBでない場合、ソースから新しい一時画像が生成され、それを使用してピクセルを取得するという醜いハックに行き詰まりました。これで、私のコードは目立った問題なく VM で動作しますが、メソッドの速度が低下することはありません。これで 1 つの問題が解決されました。あとは、そのハッキングを取り除く必要があるだけです。

于 2014-01-02T14:11:24.503 に答える