ここから本文です

C#で画像の特定の色のピクセルを削除して保存するプログラムを教えて下さい。

try********さん

2013/9/406:56:53

C#で画像の特定の色のピクセルを削除して保存するプログラムを教えて下さい。

private void Form1_DragEnter(object sender, DragEventArgs e)
{ e.Effect = DragDropEffects.All; }

private void Form1_DragDrop(object sender, DragEventArgs e)
{ foreach (string item in (string[])e.Data.GetData(DataFormats.FileDrop))
{
Bitmap Color_Palet = new Bitmap(item);


Color_Palet.Save(@"test.png", System.Drawing.Imaging.ImageFormat.Png);
} }

閲覧数:
908
回答数:
1

違反報告

ベストアンサーに選ばれた回答

oha********さん

2013/9/411:54:52

画素情報自体は削除できませんので画素値を0,透過情報を0(透明)すると見かけ上削除されたようになります
画素値は0にしなくても透過情報を0にしただけでよいのですが削除ということで画素値も0にしております

以下例のコードです
BitmapクラスのGetPixcel() SetPixcel()でもできますが処理が遅いので(こちらの環境では倍以上差がありました)
BitmapクラスのLockBitsを使いBitmapDataのオブジェクトを取得しMarshalクラスのCopy()で画素値データをコピーして
処理しています
透過情報がない画像では見かけ上画素の削除ができないので元画像が透過情報無なし場合は透過情報付の画像として読み込んでいます
※実際の処理は元画像と同じサイズの透過情報付の空のBitmapクラスを生成し元画像から画素値だけをコピーしています


この2行をファイル先頭のusingの最後に追加してください
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

// 画素の削除
private void DeletePixcel(Bitmap bitmap, Color c)
{
BitmapData bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
byte[] pixcel = new byte[bitmap.Width * bitmap.Height * 4];
Marshal.Copy(bmpdata.Scan0, pixcel, 0, pixcel.Length);

for (int y = 0; y < bitmap.Height; y++)
{
for (int x = 0; x < bitmap.Height; x++)
{
int idx = (x + y * bitmap.Width) * 4;
byte a, r, g, b;
b = pixcel[idx];
g = pixcel[idx + 1];
r = pixcel[idx + 2];
a = pixcel[idx + 3];
if (c.B == b && c.G == g && c.R == r)
{
// 次の2行のどちらかをご使用下さい
pixcel[idx] = pixcel[idx + 1] = pixcel[idx + 2] = pixcel[idx + 3] = 0; // 画素値,透過情報を0にする場合
pixcel[idx+3] = 0; // 透過情報だけ0にする場合
}

}
}
Marshal.Copy(pixcel, 0, bmpdata.Scan0, pixcel.Length);
bitmap.UnlockBits(bmpdata);
}

// 画像の読み込み 透過情報なしの画像の場合透過情報付に変更する
private Bitmap ChangeToFormat32bppArgb(string filename)
{
Bitmap bmp = new Bitmap(filename);
if (bmp.PixelFormat != PixelFormat.Format32bppArgb)
{
BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
int width = bmp.Width, height = bmp.Height;
byte[] pixcel = new byte[width * height * 4];
Marshal.Copy(bmpdata.Scan0, pixcel, 0, pixcel.Length);
bmp.UnlockBits(bmpdata);
bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
bmpdata = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
Marshal.Copy(pixcel, 0, bmpdata.Scan0, pixcel.Length);
bmp.UnlockBits(bmpdata);
}
return bmp;
}


使い方
try_hartmannさんのコードに当てはめると
※ファイルの保存時のファイル名ですがそのままだと全部同じになりますので変更しております

private void Form1_DragEnter(object sender, DragEventArgs e)
{ e.Effect = DragDropEffects.All; }

private void Form1_DragDrop(object sender, DragEventArgs e)
{ foreach (string item in (string[])e.Data.GetData(DataFormats.FileDrop))
{
Bitmap Color_Palet = ChangeToFormat32bppArgb(item);
//保存用ファイル名 読み込んだファイル名に_を付ける
string savefilename = string saveFileName =
System.IO.Path.Combine(Path.GetDirectoryName(item), Path.GetFileNameWithoutExtension(item) + "_" + Path.GetExtension(item));

// Color.FromArgb(0,255,0)は赤0 緑255 青0 で緑となります
//Color.FromArgb(0,255,0)の部分はtry_hartmannさんのコードの仕様に合わせて変更してください
DeletePixcel(Color_Palet, Color.FromArgb(0,255,0));

Color_Palet.Save(savefilename, System.Drawing.Imaging.ImageFormat.Png);
}
}

参考になれば幸いです

質問した人からのコメント

2013/9/4 22:16:56

ありがとうございました!

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる