編集:返信に深く感謝します。ここで何よりも必要なのは、ネストされたループ内の数行のコードで行うことのサンプル コードです。これは、GetPixel/SetPixel で正しく機能するものですが、Lockbits を使用しても正しく機能しないものでもあるためです。ありがとうございました
処理時間を改善するために、画像処理フィルターを GetPixel / SetPixel から Lockbits に変換しようとしています。 ここの Stack Overflow、MSDN、およびその他のサイトでも Lockbits のチュートリアルを見てきましたが、何か間違ったことをしています。 緑を減らして赤と紫の効果を作成する、非常に単純なフィルターから始めます。これが私のコードです:
private void redsAndPurplesToolStripMenuItem_Click(object sender, EventArgs e)
{
// Get bitmap from picturebox
Bitmap bmpMain = (Bitmap)pictureBoxMain.Image.Clone();
// search through each pixel via x, y coordinates, examine and make changes. Dont let values exceed 255 or fall under 0.
for (int y = 0; y < bmpMain.Height; y++)
for (int x = 0; x < bmpMain.Width; x++)
{
bmpMain.GetPixel(x, y);
Color c = bmpMain.GetPixel(x, y);
int myRed = c.R, myGreen = c.G, myBlue = c.B;
myGreen -= 128;
if (myGreen < 0) myGreen = 0;
bmpMain.SetPixel(x, y, Color.FromArgb(255, myRed, myGreen, myBlue));
}
// assign the new bitmap to the picturebox
pictureBoxMain.Image = (Bitmap)bmpMain;
// Save a copy to the HD for undo / redo.
string myString = Environment.GetEnvironmentVariable("temp", EnvironmentVariableTarget.Machine);
pictureBoxMain.Image.Save(myString + "\\ColorAppRedo.png", System.Drawing.Imaging.ImageFormat.Png);
}
そのため、GetPixel / SetPixel コードは正常に動作しますが、遅いです。だから私はこれを試しました:
private void redsAndPurplesToolStripMenuItem_Click(object sender, EventArgs e)
{
// Get bitmap from picturebox
Bitmap bmpMain = (Bitmap)pictureBoxMain.Image.Clone();
Rectangle rect = new Rectangle(Point.Empty, bmpMain.Size);
BitmapData bmpData = bmpMain.LockBits(rect, ImageLockMode.ReadOnly, bmpMain.PixelFormat);
// search through each pixel via x, y coordinates, examine and make changes. Dont let values exceed 255 or fall under 0.
for (int y = 0; y < bmpMain.Height; y++)
for (int x = 0; x < bmpMain.Width; x++)
{
bmpMain.GetPixel(x, y);
Color c = new Color();
int myRed = c.R, myGreen = c.G, myBlue = c.B;
myGreen -= 128;
if (myGreen < 0) myGreen = 0;
bmpMain.SetPixel(x, y, Color.FromArgb(255, myRed, myGreen, myBlue));
}
bmpMain.UnlockBits(bmpData);
// assign the new bitmap to the picturebox
pictureBoxMain.Image = (Bitmap)bmpMain;
// Save a copy to the HD for undo / redo.
string myString = Environment.GetEnvironmentVariable("temp", EnvironmentVariableTarget.Machine);
pictureBoxMain.Image.Save(myString + "\\ColorAppRedo.png", System.Drawing.Imaging.ImageFormat.Png);
}
ネストされたループの最初の行に到達すると、「 「System.InvalidOperationException」タイプの未処理の例外が System.Drawing.dll で発生しました追加情報:ビットマップ領域は既にロックされています」というエラーがスローされます。
これは初心者のエラーに違いないと思います。誰かがこの非常に単純なフィルターをロックビットに変換する正しい方法を示してくれれば幸いです。どうもありがとうございました