C#で画像の色を変更しようと頑張っているのですが・・・

このQ&Aのポイント
  • C#を使用して画像の色を変更しようとしていますが、うまくいきません。クリックした座標と同じ色の場所を青に変えたいです。XとYは画像の座標の大体の最大値です。
  • C#で画像の色を変更する方法に苦戦しています。クリックした場所と同じ色のピクセルを青に変換したいです。画像の座標はXとYで示されます。
  • C#を使って画像の色を変更しようと努力していますが、うまくいっていません。クリックした場所と同じ色のピクセルを青に変える方法を教えてください。座標はXとYで指定されます。
回答を見る
  • ベストアンサー

C#について

C#で画像の色を変更しようと頑張っているのですが・・・ クリックした座標と同じ色の場所を青にしたいです。 XとYは画像の座標の大体の最大値です。 public partial class Form1 : Form { Bitmap bmp; public Form1() { InitializeComponent(); bmp = new Bitmap(pB1.Image); } private void pictureBox1_MouseDown(object sender, MouseEventArgs e) { Color c = bmp.GetPixel(e.X, e.Y); for (int Y = 0; Y < 280; Y++) { for (int X = 0; X < 240; X++) { Color c2 = bmp.GetPixel(X, Y); if (c.R == c2.R && c.G == c2.G && c.B == c2.B) { bmp.SetPixel(X, Y, Color.FromArgb(0, 0, 255)); } } } } } } クリックしたところと同じ色を青(0, 0, 255)に変更したいのですが変更されません。 間違っているところなどがあれば教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
  • sean9
  • ベストアンサー率86% (26/30)
回答No.1

こんにちは 2案あります。 (1)pictureBox1のImageを置き換える for (int Y = 0; Y < 280; Y++) {  //省略// } pictureBox1.Image = bmp; //追加 (2)ImageAttributeを使う これはhanamizukiu1925様がforループでやっていることの代用です System.Drawing.Imaging.ColorMap[] maps = new System.Drawing.Imaging.ColorMap[]{ new System.Drawing.Imaging.ColorMap() }; maps[0].OldColor = c; maps[0].NewColor = Color.FromArgb(255, 0, 0, 255); System.Drawing.Imaging.ImageAttributes attributes = new System.Drawing.Imaging.ImageAttributes(); attributes.SetRemapTable(maps); Bitmap bitmap = new Bitmap(bmp.Width, bmp.Height); using (Graphics g = Graphics.FromImage(bitmap)) { g.DrawImage(bmp, new Rectangle(0, 0, bitmap.Width, bitmap.Height), 0, 0, bmp.Width, bmp.Height, GraphicsUnit.Pixel, attributes); } pictureBox1.Image = bitmap; お好きな方をどうぞ。

hanamizukiu1925
質問者

お礼

とてもたすかりました。 ありがとうございました。

関連するQ&A

  • C++での画像切り抜きについて

    こんにちは。プログラミング初心者です。 Microsoft Visual Studio C++ MFCで画像解析のプログラムを書いています。 その際、jpg画像から左上隅・右下隅の座標を指定してある領域を切り出したいのですが、 今の方法では切り出した画像の周りに黒の領域ができてしまいます。(添付画像参照) サイズを切り抜いた画像のサイズに変更して、黒の領域をなくしたいのですが、 どのように書けばいいのでしょうか? 下記のコードに追加する部分・変更する部分を具体的に教えていただけると有難いです。 説明不足で申し訳ありませんが、よろしくお願いいたします。 void CtestbView::OnUleft() //左上隅点の座標 { // TODO: ここにコマンド ハンドラー コードを追加します。 Lcpx=px; //左上隅のx座標 Lcpy=py; //左上隅のy座標 } void CtestbView::OnDright() //右下隅点を指定するサブルーチン { // TODO: ここにコマンド ハンドラー コードを追加します。 int x,y; Rcpx=px;//右下隅x座標 Rcpy=py;// y for(y=Lcpy-1; y<=Rcpy+1; y++) {//切り出し範囲を白線で囲む(白線を切り出さないため+-1を付加) img1.SetPixel(Lcpx-1,y,RGB(255,255,255)); //左側縦線 img1.SetPixel(Rcpx+1,y,RGB(255,255,255)); //右側縦線 } for(x=Lcpx-1; x<=Rcpx+1; x++) { img1.SetPixel(x,Lcpy-1,RGB(255,255,255)); //上側横線 img1.SetPixel(x,Rcpy+1,RGB(255,255,255)); //下側横線 } jpgLoadFlag1=true; Invalidate(); } void CtestbView::OnCut() //テンプレートを切り出すサブルーチン { // TODO: ここにコマンド ハンドラー コードを追加します。 int x,y; BeginWaitCursor(); for(y=0; y<jpgHeight; y++) for(x=0; x<jpgWidth; x++) img2.SetPixel(x,y,RGB(0,0,0)); //画面をクリア int xshift=0; int yshift=0; for(y=Lcpy; y<=Rcpy; y++) { for(x=Lcpx; x<=Rcpx; x++) { COLORREF color=img1.GetPixel(x,y); int RV=GetRValue(color); int GV=GetGValue(color); int BV=GetBValue(color); img2.SetPixel(x-Lcpx+xshift,y-Lcpy+yshift,RGB(RV,GV,BV)); } } xminP=xshift; xmaxP=Rcpx-Lcpx+xshift; //テンプレート上のパターンの位置 yminP=yshift; ymaxP=Rcpy-Lcpy+yshift; jpgWidth=xmaxP; jpgHeight=ymaxP; jpgLoadFlag2=true; Invalidate(); EndWaitCursor(); } void CtestbView::OnLButtonDown(UINT nFlags, CPoint point) //指定点の座標値を取り出す { // TODO: ここにメッセージ ハンドラー コードを追加するか、既定の処理を呼び出します。 CView::OnLButtonDown(nFlags, point); int i,j; int x,y; px=point.x; //マウス指定点のx座標 py=point.y; //マウス指定点のy座標 COLORREF color=img1.GetPixel(px,py); //指定点のアドレス変換 rv=GetRValue(color); //マウス指定点の赤成分 gv=GetGValue(color); //マウス指定点の緑座標 bv=GetBValue(color); //マウス指定点の青座標 img1.SetPixel(px, py, RGB(255,0,0));//指定点位置の赤点表示 for(j=0; j<=20; j++)//指定点の色を20×20の短径で表示 for(i=0; i<=20; i++) img1.SetPixel(jpgWidth-30+i,20+j,RGB(rv,gv,bv)); //指定点の色設定 jpgLoadFlag1=true; InvalidateRect(NULL); }

  • 配列を使ったビットマップクラス

    VC++を使ったフォームアプリケーションでビットマップなどの画像を表示させ、ピクセル処理を施せるプログラムを作りました。このプログラム上ではピクチャボックスを1つ用意していますが、今後もっと多くのピクチャボックスが必要になってきます。以下のプログラムではBitmapクラスのbmpをピクチャボックス1の画像に入れています。単純にBitmapクラスのbmpを増やせば(例:bmp1)、ピクチャボックスが増えても平気ですが、処理の関係上配列を使いたいと思っています。なので下に書いてあるプログラムのbmp->という部分をbmp[0]->というふうに変えたいと考えています。自分なりに調べて(1)、(2)の部分を変えればいいと思うのですがどうもうまくいきません。わかる方がいたらご教授ください、おねがいします。 #pragma once namespace bmp { using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; using namespace System::Text; using namespace System::Collections::Generic; /// <summary> /// Form1 の概要 /// /// 警告: このクラスの名前を変更する場合、このクラスが依存するすべての .resx ファイルに関連付けられた /// マネージ リソース コンパイラ ツールに対して 'Resource File Name' プロパティを /// 変更する必要があります。この変更を行わないと、 /// デザイナと、このフォームに関連付けられたローカライズ済みリソースとが、 /// 正しく相互に利用できなくなります。 /// </summary> public ref class Form1 : public System::Windows::Forms::Form { public: Form1(void) { InitializeComponent(); // //TODO: ここにコンストラクタ コードを追加します // bmp = nullptr; ……… (1) //Bitmap^ bmp[300]; }      //省略// #pragma endregion //private: array<Bitmap^>^ bmp = gcnew array<Bitmap^>(300); ……… (2) private: Bitmap^ bmp; private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) { bmp = gcnew Bitmap("C:/Documents and Settings/Owner/デスクトップ/lena.bmp",true); pictureBox1->Image = bmp; } private: System::Void pictureBox1_Click(System::Object^ sender, System::EventArgs^ e) { /*bmp = gcnew Bitmap("C:/Documents and Settings/Owner/デスクトップ/lena.bmp",true);*/ int x,y; int w = bmp->Width; int h = bmp->Height; for(x = 0; x < w; x++){ for(y = 0; y < h; y++){ if(x < (w * 0.05) || y < (h * 0.05) || (y > (h - (h*0.05)))&&(y < h) || (x > (w - (w*0.05)))&&(x < w)){ Color pixelColor = bmp->GetPixel( x, y ); Color newColor = Color::FromArgb( 255, 0, 0 ); bmp->SetPixel( x, y, newColor ); } } } pictureBox1->Image = bmp; } private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { } }; }

  • 細線化のプログラム

    細線化のプログラム C#で細線化のプログラムを作成してみましたがうまくいきません。 http://imagingsolution.blog107.fc2.com/blog-entry-138.html を参考に作成しました。 うまくいかないところは、一部に縦線がいくつも残ってしますところです。 ソース static Bitmap Shape(Bitmap bmp) { int Flag = 0; //初期化 for (int j = 0; j < bmp.Height ; j++) { for (int i = 0; i < bmp.Width ; i++) { if (bmp.GetPixel(i, j).R != 255) { bmp.SetPixel(i, j, Color.FromArgb(0, 0, 0)); } } } while(true){ //パターン1 for (int i = 1; i < bmp.Width - 1; i++) { for (int j = 1; j < bmp.Height - 1; j++) { if (bmp.GetPixel(i, j).R == 255) { //除去しないパターン if (( 略 )) { //セーフ } else if ((略)){ //セーフ } //除去するパターン else if ((bmp.GetPixel(i + 1, j).R != 255) || (bmp.GetPixel(i, j - 1).R != 255)) { //黒にする bmp.SetPixel(i, j, Color.FromArgb(0, 0, 0)); Flag++; } } } } // MessageBox.Show(Flag.ToString()); //終了 if (Flag == 0) return bmp; Flag = 0; /*パターン2も同じようにする*/ という感じでプログラムを組んでいます。 画像は失敗例です。アドバイスをお願いします

    • 締切済み
    • CGI
  • Bitmapデータ型の画像幅の拡大

    現在Visual studio 2005のフォームアプリケーションでプログラミグを行っている者です。以下のプログラムの中に画像の幅であるw,hという変数があるのですが、私の作ろうとしている画像処理の関係上、この画像データの幅を倍にしたいです(例:3*w,3*h)。しかし、変数宣言(例:int 3*w)やfor文の中で倍にしようとしても、ビルドはできるものの"アプリケーションのコンポーネントで、ハンドルされていない例外が発生しました。・・・パラメータは正の値で、高さより小さい値指定しなければなりません。"とでて、実行できません。おそらく倍にしてあげたとこで、倍になった部分の画像データがわからないためこういったエラーが出てしまうのだと考えています。どうにかして、BITMAPデータ型で読み込んだ画像の幅を倍の数値を得たいのですが、エラーのでないようにするためにはどのようにしてあげればいいのでしょうか?わかる方がいたらよろしくお願いします。 プログラムは以下のとおりです。 #pragma once // 省略 // } #pragma endregion private:Bitmap^ pic; private:array< Bitmap^>^ bmp; // 原画像格納 // private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) { bmp[0] = gcnew Bitmap("画像ファイル1",true); pictureBox1->Image = bmp[0]; pic = gcnew Bitmap("画像ファイル2",true); } private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) { int x,y,a,b; /* x,y: 画像の座標 a,b: 複合画像の座標 */ int w = pic->Width; //ここでpic->Width*3としてもエラー /* 複合画像の横幅 */ int h = pic->Height; /* 複合画像の縦幅 */ x = 0; y = 0; a = 0; b = 0; for(y = 0; y < h; y++){ //ここで3*hとしてもエラー for(x = 0; x < w; x+=3){ pic->SetPixel( x, y, bmp[1]->GetPixel( x, y ) ); } } pictureBox2->Image = pic; } }; }

  • 線形補間法プログラム(C++)

    C++言語で線形補間法のプログラムを組んで実行しているのですが、どしてもうまくいきません。ただ2倍の画像を作っているだけなのですが・・・。 以下プログラムを載せます、おおよその場所はわかるのですがどうすれば通るのかわかりません。どう直したらよいのか分かる方がいましたらご教授お願いします。 ※bmp[0]:現画像 pic:bmp[0]の縦横2倍の画像 // 線形補間法 // int zx = 2; int zy = 2; int i,j,m,n; float x,y,p,q; int xs = bmp[0]->Width/2; int ys = bmp[0]->Height/2; int d; for(i = -ys; i < ys; i++){ for(j = -xs; j < xs; j++){ y = i/zy; x = j/zx; if(y > 0){ m = (int)y; }else{ m = (int)(y-1);} if(x > 0){ n = (int)x; }else{ n = (int)(x-1);} q = y - m; p = x - n; if(q == 1){q = 0; m = m + 1;} if(p == 1){p = 0; n = n + 1;} if((m >= -ys)&&(m < ys)&&(n >= -xs)&&(n < xs)){ d = (int)((1.0 - q) * (1.0 - p) * (bmp[0]->GetPixel( m + ys, n + xs)) //おそらくこの辺に問題があるかと思われます。 + p * (bmp[0]->GetPixel( m +ys, n + xs)) + q * (1.0 - p) * (bmp[0]->GetPixel(m + 1 + ys, n + xs)) + p * (bmp[0]->GetPixel(m + 1 + ys, n + 1 + xs))); }else{ d = 0; } if(d < 0){d = 0;} if(d > 255){d = 255;} pic->SetPixel(i + ys, j + xs) = d; } } pictureBox2->Image = pic; }

  • C#でBitmapの画像を比較

    C#でBitmapの画像を比較するときに、 bmp.GetPixel(W, H); でひとつひとつ比較していけば出来るのですが、 全く同じBitmapかどうかの比較をするのに、 Bitmap情報の数値化などで、 簡単な方法はあるのでしょうか? 画像比較速度を上げたいので。 よろしくお願い致します。

  • pictureBoxの画像の座標の色の出し方。

    VC++で、pictureBoxで表示した画像を適当な場所をクリックするとその座標とRGBの色あいが表示するプログラムなんですが、エラーはしなかったんですが、デバックして画像表示して適当にクリックしてもなにも表示されませんでした。 プログラムに間違えでもあるのかみてください。 private: System::Void pictureBox1_MouseDown(System::Object^sender, System::Windows::Forms::MouseEventArgs^ e) { String^fname = openFileDialog1->FileName; Bitmap^fun = gcnew Bitmap(fname); Point^ p = PointToClient( Point(e->X ,e->Y)); Color^col = fun->GetPixel(p->X,p->Y); label1->Text = String::Format("..{0}", fun->GetPixel(p->X,p->Y)); }

  • C++でのtxtファイル読み込みについて

    こんにちは。 C++でのtxtファイル読み込みについて質問させていただきます。 下記のようなコードを使ってtxtファイルを読み込もうとしています。 private: System::Void toolStripButton2_Click(System::Object^ sender, System::EventArgs^ e) { array<int>^ x=gcnew array<int>(103*300); array<int>^ y=gcnew array<int>(103*300); int num=int::Parse(numericUpDown4->Text); String^ fileName="outputx"+ num.ToString() +".txt"; String^ string1; StreamReader^ sreader1; StreamReader^ din = File::OpenText(fileName); array<String^>^ sub_string; //指定したファイル名でStreamReaderを設定する try{ sreader1=gcnew StreamReader(fileName); }catch(Exception^ ex){ MessageBox::Show("!"); return; } //x[i]の読み込み String^ str; int count = 0; while ((str = din->ReadLine()) != nullptr) { string1=sreader1->ReadLine(); //StreamReaderに1行読み込む sub_string=string1->Split(' '); //コンマで分割する x[count]=Convert::ToInt32(sub_string[1]); y[count]=Convert::ToInt32(sub_string[2]); count++; } Bitmap^ bmap_dst=gcnew Bitmap(104,301); for(int j=0;j<301;j++) for(int i=0;i<104;i++){ bmap_dst->SetPixel(i,j,Color::FromArgb(255,255,255));} for(int k=0;k<count;k++){ bmap_dst->SetPixel(x[k],y[k],Color::FromArgb(0,0,0));} pictureBox1->Image = bmap_dst; pictureBox2->Image = bmap_dst; //y座標 fileName="outputy"+ num.ToString() +".txt"; String^ string2; StreamReader^ sreader2; din = File::OpenText(fileName); array<String^>^ sub_string2; //指定したファイル名でStreamReaderを設定する try{ sreader2=gcnew StreamReader(fileName); }catch(Exception^ ex){ MessageBox::Show("!"); return; } //x[i]の読み込み String^ str2; count = 0; while ((str2 = din->ReadLine()) != nullptr) { string2=sreader2->ReadLine(); //StreamReaderに1行読み込む sub_string2=string2->Split(' '); //コンマで分割する x[count]=Convert::ToInt32(sub_string2[1]); y[count]=Convert::ToInt32(sub_string2[2]); count++; } Bitmap^ bmap_dst2=gcnew Bitmap(104,301); for(int j=0;j<301;j++) for(int i=0;i<104;i++){ bmap_dst2->SetPixel(i,j,Color::FromArgb(255,255,255));} for(int k=0;k<count;k++){ bmap_dst2->SetPixel(x[k],y[k],Color::FromArgb(0,0,0));} pictureBox3->Image = bmap_dst2; pictureBox4->Image = bmap_dst2; } また、読み込むtxtファイルは下記のようなものです。(長いので途中部分のみ)      1    287      1    288      2    107      2    108      2    109      2    110 これをビルドすると”入力文字列の形式が正しくありません”と出てしまいます。 また、下記のようなtxtファイルだと問題なく読み込むことができます。 9 164 9 165 9 166 10 151 10 152 10 153 10 154 プログラミングのどこがいけないのでしょうか? 説明不足かと思いますが、ご回答よろしくおねがいします。

  • 簡単法知ってる人教えてください。

    ボタンを押して画像を読み込み、その画像をカウントするプログラムを考えたのですが、画像の絶対パスを取得するために毎回変更する部分ができてしまいました;; 誰か、どんな画像でも読み込める工夫を知ってる人がいたら教えてください。プログラムは↓ Function CountNumColor(ByRef DotWW As Long, ByRef DotHH As Long, ByRef CHECK_C As Long) As Integer Dim Form1 As Object Dim NumEQ As Double Dim NumNot As Long Dim x, y As Long Dim ChkColor As Color = Color.FromArgb(0) Dim myBitmap As New Bitmap("E:\2005\画像処理システム\無題.bmp") NumEQ = 0 NumNot = 0 System.Windows.Forms.Application.DoEvents() For x = 0 To DotHH - 1 For y = 0 To DotWW - 1 System.Windows.Forms.Application.DoEvents() ChkColor = myBitmap.GetPixel(x, y) If ChkColor.R = 0 And ChkColor.G = 0 And ChkColor.B = 0 Then NumEQ = NumEQ + 1 Else NumNot = NumNot + 1 Debug.Write("x,y,Val(Bitmap.GetPixel(x, y)") End If Next y Next x CountNumColor = NumEQ End Function このプログラムの”E:\2005\画像処理システム\無題.bmp”の部分を工夫してどんな画像でも読み込むことができることができるようにできないでしょうか? わかる人の知恵を貸してください><

  • 画素へのアクセスについて困っています。

    現在VC++2005でプログラムを組んでいますが、画素に対するアクセスをしたいですが、getpixel()以外の方法がありますか? 自分がやっているのは以下のようになります。 Color color = bmp->Getpixel(x,y); r = color.R, g = color.G, b = color.B; 下のようなアクセスを行いたいですが、フォームアプリケーションではどうすればよいでしょうか。 B = Bmpimage[x*3+y*bmpL]; G = Bmpimage[x*3+y*bmpL+1]; R = Bmpimage[x*3+y*bmpL+2]; ご教授よろしくお願いします。

専門家に質問してみよう