I can not understand how correctly in the MouseDoubleClick event to take a Bitmap drawn image and MouseDoubleClick get pixelated and change color. Please tell me a link to the GitHub project . The difficulty lies in the fact that I cannot change the color of each pixel (that is, when I double-click nothing happens), and when I try to work directly with the Bitmap image, an exception appears (I add a line to the beginning of the event: bmap = new Bitmap(panel.Image); ): System.NullReferenceException: 'Object reference not set to an instance of an object.'

Thank you in advance))

 using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; namespace NNHopfild { public partial class NNHT : Form { Point CurrentPoint; Graphics g; Bitmap bmap; public NNHT() { InitializeComponent(); bmap = new Bitmap(panel.Width, panel.Height); panel.MouseDown += panel_MouseDown; panel.Paint += panel_Paint; g = panel.CreateGraphics(); } private void exit_Click(object sender, EventArgs e) { Application.Exit(); } private void panel_MouseMove(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { using (Graphics g = Graphics.FromImage(bmap)) { g.FillEllipse(Brushes.Black, eX, eY, 10, 10); } panel.Invalidate(); } } private void panel_MouseDown(object sender, MouseEventArgs e) { CurrentPoint = e.Location; } private void panel_Paint(object sender, PaintEventArgs e) { e.Graphics.DrawImage(bmap, Point.Empty); } private void panel_MouseDoubleClick(object sender, MouseEventArgs e) { int height = panel.Height; int width = panel.Width; int[,] mat = new int[height, width]; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { Color col; col = bmap.GetPixel(i, j); if (col == Color.White) { mat[i, j] = -1; bmap.SetPixel(i, j, Color.Blue); } if (col == Color.Black) { mat[i, j] = 1; bmap.SetPixel(i, j, Color.Red); } } } } } } 
  • so what does not work? Error pops up or what's the problem? - tym32167
  • Well, at first glance, it is worth going over the pixels from the 0 index; I support the question - what is wrong? - Alias
  • @Alias ​​I corrected the question and tried to start your variant with 0, the problem is urgent - Alexandr Zemlyak
  • @ tym32167 supplemented the question - Alexandr Zemlyak
  • Bitmap.SetPixel(,,) way, I don’t think that you are critical, but the regular Bitmap.SetPixel(,,) method is slow, look in the direction of Bitmap.LockBits() and FastBitmap . - Alias

2 answers 2

Just as an example:

I made a form where a square is drawn by double-clicking on the picturebox.

 class MyForm : System.Windows.Forms.Form { public MyForm() { var box = new PictureBox(); var image = new Bitmap(500, 500); for (var i = 0; i < 500; i++) for (var j = 0; j < 500; j++) { image.SetPixel(i, j, Color.Green); } box.Image = image; box.Width = 500; box.Height = 500; this.Width = 500; this.Height = 500; this.FormBorderStyle = FormBorderStyle.FixedToolWindow; box.MouseDoubleClick += (sender, args) => { for (var i = -10; i < 10; i++) { for (var j = -10; j < 10; j++) { var x = args.Location.X + i; var y = args.Location.Y + j; if (x >= 0 && y >= 0 && x < 500 && y < 500) image.SetPixel(x, y, Color.Red); } } box.Refresh(); }; this.Controls.Add(box); } } 

Happened

Result

  • thank you) but this is a bit wrong. The fact is that I implemented drawing with the mouse cursor on the left mouse button held down, but after that I would like to convert the image into a Bitmap and cycle through it and change the pixel color relative to the condition - Alexandr Zemlyak
  • @AlexandrZemlyak did not understand. I wrote to you how to change the image pixel by pixel. And I change bitmap in the handler. And in the cycle. This is exactly what you just wrote to me. - tym32167

on the second look :) let's compare with an example from tym32167:

  • you create an image bmap = new Bitmap(panel.Width, panel.Height); the size of the panel, but do not assign it acc. control panel.Image = bmap; - hence the mentioned exception, because panel.Image you apparently still NULL .
  • after redrawing there is no call to the Control.Refresh() method to force redraw the entire control; It is possible to more economically redraw: for each changed region of Control.Invalidate(Region) , then a single Control.Update() update only these regions.
  • you have at some point for some reason there are two g = panel.CreateGraphics(); objects of the same name: 1st belongs to the class of the form g = panel.CreateGraphics(); and is associated with the control (so it will try to draw in an empty panel.Image ), and the 2nd is re-created to draw ellipses using (Graphics g = Graphics.FromImage(bmap)){ } in a bitmap not assigned to the control.