pictureBox1.Image is null even after drawing on a PictureBox - c#

I am drawing on a PictureBox control a grid with a small image on it.
When pressing a Button, I need to update the small image position on the grid, drawing it again on a different position.
I am drawing first time with:
Bitmap ime = new Bitmap(Properties.Resources.ime);
Image imge= ime;
Graphics g = e.Graphics;
using (Pen pen = new Pen(Color.Black, 2))
{
int rows = matrix.GetUpperBound(0) + 1 - matrix.GetLowerBound(0); // = 3, this value is not used
int columns = matrix.GetUpperBound(1) + 1 - matrix.GetLowerBound(1); // = 4
for (int index = 0; index < matrix.Length; index++)
{
int i = index / columns;
int j = index % columns;
if (matrix[i, j] == 0)
{
Rectangle rect = new Rectangle(new Point(5 + step * j, 5 + step * i), new Size(width, height));
g.DrawRectangle(pen, rect);
g.FillRectangle(Brushes.Black, rect);
}
}
Rectangle rect1 = new Rectangle(new Point(5 + step * 10, 5 + step * 10), new Size(width, height));
g.DrawImage(imge, rect1);
}
and the second time, when updating the PictureBox, I am using:
using (var g = Graphics.FromImage(matrixPictureBox.Image))
but I am getting the error saying that matrixPictureBox.Image is null
Does anybody know the problem?

Related

How to make painted structures clean in Graphics(C#)

I used some basic code to draw lines on an bitmap, but I cannot think of any reason
why the surroundings of these lines are not deep black. If there is any solution I would be really interested in it. Thank you!
This is my code:
Bitmap bm = new Bitmap(3200, 1600, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
double step = werte.Count / 3200;
Pen whitePen = new Pen(Color.White, 3);
var graphics = Graphics.FromImage(bm);
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
graphics.FillRectangle(new SolidBrush(Color.Black), 0, 0, 3200, 1600);
int lastangezeigtH = (int)(1600 - ((werte[(int)(0 * step)] - min) * 1600 / deltaMinMax));
for (int i = 1; i < 3200; i++)
{
double h = (werte[(int)(i * step)] - min) * 1600 / deltaMinMax;
int angezeigtH = (int)(1600 - h);
//bm.SetPixel(i, angezeigtH, Color.White);
graphics.DrawLine(whitePen,i - 1, lastangezeigtH, i, angezeigtH);
lastangezeigtH = angezeigtH;
}

How to center this image

I have an image that looks like this. I have the pointy image which looks good and then I have to draw the green image on top of the pointy image. The idea is to draw the green image in the center of the pointy image. I am having some problems with that.
var shipImageOffset = new PointF(0, 0);
using (var bmp = new Bitmap(_shipImage))
using (var image = ImageUtilities.RotateImage(
bmp,
(float)ShipHeading,
new PointF(this.Width / 2, this.Height / 2),
shipImageOffset,
this.Width,
this.Height))
{
e.Graphics.DrawImage(image, new PointF(0,0));
}
//paint the green pointer image
if (_windImageRepo.TryGetValue(needleSpeed, out var windImage))
{
//need to figure out the origin point - the origin point is the center of the long rectangle
//at the bottom
var center = new PointF(windImage.HorizontalResolution, windImage.VerticalResolution);
using (var bmp = new Bitmap(windImage))
{
for (int x = 0; x < bmp.Width; x++)
{
for (int y = 0; y < bmp.Height; y++)
{
var color = bmp.GetPixel(x, y);
if (color != Color.FromArgb(0))
{
bmp.SetPixel(x, y, System.Drawing.Color.LimeGreen);
}
}
}
var windImageOffset = new PointF(0,0);
using (var image = ImageUtilities.RotateImage(
bmp,
(float)WindHeading,
new PointF(this.Width / 2, this.Height / 2),
windImageOffset,
this.Width,
this.Height))
{
//This is your image from the pictureBox1
Bitmap img = new Bitmap(_shipImage);
// I am targeting the middle of the image, Your case would be the binarized image
Point index = new Point(img.Size.Width / 2, img.Size.Height / 2);
e.Graphics.DrawImage(image,Center(_shipImage));
}
}
}
base.OnPaint(e);
}
The objective is to get the green pointer in the middle of other image. Not having luck on that.

Can rectangle be split in rows and columns?

private void panel1_Paint(object sender, PaintEventArgs e)
{
Pen mypen = default(Pen);
mypen = new Pen(System.Drawing.Color.Red, 3);
mypen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
//For Dash Line in Rectangle
Pen mypen1 = default(Pen);
mypen1 = new Pen(System.Drawing.Color.Blue, 1);
mypen1.DashStyle![enter image description here][2] = System.Drawing.Drawing2D.DashStyle.Dash;
//Pen mypen2 =default(Pen);
//mypen2 = new Pen(System.Drawing.Color.Yellow, 3);
//mypen2.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
//Pen mypen3 = default(Pen);
//mypen3 = new Pen(System.Drawing.Color.Violet, 1);
//mypen3.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
L1 = Rect1LT.X + 5;
T1 = Rect1LT.Y + 5;
W1 = Rect1RB.X - Rect1LT.X;
H1 = Rect1RB.Y - Rect1LT.Y;
e.Graphics.DrawRectangle(mypen, new System.Drawing.Rectangle(L1, T1, W1, H1));
e.Graphics.DrawRectangle(mypen1, new System.Drawing.Rectangle(L1, T1, W1, H1));
e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1LT.X, Rect1LT.Y, 10, 10));
e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1RT.X, Rect1RT.Y, 10, 10));
e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1LB.X, Rect1LB.Y, 10, 10));
e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1RB.X, Rect1RB.Y, 10, 10));
e.Graphics.FillRectangle(Brushes.Blue, Rect1LT);
e.Graphics.FillRectangle(Brushes.Blue, Rect1RT);
e.Graphics.FillRectangle(Brushes.Blue, Rect1LB);
e.Graphics.FillRectangle(Brushes.Blue, Rect1RB);
e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1T.X, Rect1T.Y, 10, 10));
e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1R.X, Rect1R.Y, 10, 10));
e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1B.X, Rect1B.Y, 10, 10));
e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1L.X, Rect1L.Y, 10, 10));
e.Graphics.FillRectangle(Brushes.Blue, Rect1T);
e.Graphics.FillRectangle(Brushes.Blue, Rect1R);
e.Graphics.FillRectangle(Brushes.Blue, Rect1B);
e.Graphics.FillRectangle(Brushes.Blue, Rect1L);
DataGridView dg1 = new DataGridView();
//while (!exit)
//{
// var time = GetTime();
// Update(time);
// Render(time);
//}
}
I want to Divide Rectangle in Rows and Columns and Size of Rows and Column can be changeable at runtime? and No of Rows and Columns also can be changeable? I don't want to split whole rectangle I just want to divide them in rectangle.
Here is a simplfied example:
int cols = 7; int rows = 11;
private void panel1_Paint(object sender, PaintEventArgs e)
{
Rectangle Rect = // your Rectangle!
Rectangle pRect = Rect; // panel2.ClientRectangle;
float width = 1f * pRect.Width / cols;
float height = 1f * pRect.Height / rows;
using (Pen pen = new Pen(System.Drawing.Color.Blue, 1))
{
pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
for (int c = 0; c < cols; c++)
for (int r = 0; r < rows; r++)
{
RectangleF rect = new RectangleF(pRect.X + c * width, pRect.Y + r * height,
width, height);
e.Graphics.FillRectangle(Brushes.Coral, rect);
// e.Graphics.DrawRectangle(pen, rect.X, rect.Y, rect.Width, rect.Height);
}
for (int c = 0; c < cols; c++) e.Graphics.DrawLine(pen,
pRect.X + c * width, pRect.Y, pRect.X + c * width, pRect.Y + pRect.Height);
for (int r = 0; r < rows; r++) e.Graphics.DrawLine(pen,
pRect.X, pRect.Y + r * height, pRect.X + pRect.Width, pRect.Y + r * height);
e.Graphics.DrawRectangle(Pens.Red,
pRect.X, pRect.Y, pRect.Width - 1, pRect.Height - 1);
}
}
Note a few changes:
The border color and the fill color must not be the same.
The fill must come first or it will overwrite the border
I work with floats to fill the panel completely; if the cols and rows don't divide into the panel/rectangle size evenly, the recangles will not all have the same sizes ..
At first I have ignored your DashStyle. If you want to have a DashStyle you must completely change your plan! The reason is that if you draw Rectangles in a grid you..
..either have them overlapping and then the dashes will get in each others way. There is a DashOffset parameter but I don't think it can be twisted to make it work over any grid.
..or you need to draw the rectangles inside the grid cells but then they will be twice a thick and the patterns still will disturb each other.
Instead you simply draw only a few lines as shown!
Here is my example with Dashes:

Color on screen area search

I'm trying to find patches of a certain color on the screen.
I am able to find all the pixels on the screen and test the RGB and add the points into an array, but i don't want all the pixels just 1 point for each patch of the color.
Here is my code:
public static Point[] PixelSearch(Rectangle rect, Color Pixel_Color, int Shade_Variation)
{
ArrayList points = new ArrayList();
Bitmap RegionIn_Bitmap = new Bitmap(rect.Width, rect.Height, PixelFormat.Format24bppRgb);
using (Graphics GFX = Graphics.FromImage(RegionIn_Bitmap))
{
GFX.CopyFromScreen(rect.X, rect.Y, 0, 0, rect.Size, CopyPixelOperation.SourceCopy);
}
BitmapData RegionIn_BitmapData = RegionIn_Bitmap.LockBits(new Rectangle(0, 0, RegionIn_Bitmap.Width, RegionIn_Bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int[] Formatted_Color = new int[3] { Pixel_Color.B, Pixel_Color.G, Pixel_Color.R }; //bgr
unsafe
{
for (int y = 0; y < RegionIn_BitmapData.Height; y++)
{
byte* row = (byte*)RegionIn_BitmapData.Scan0 + (y * RegionIn_BitmapData.Stride);
for (int x = 0; x < RegionIn_BitmapData.Width; x++)
if (row[x * 3] >= (Formatted_Color[0] - Shade_Variation) & row[x * 3] <= (Formatted_Color[0] + Shade_Variation)) //blue
if (row[(x * 3) + 1] >= (Formatted_Color[1] - Shade_Variation) & row[(x * 3) + 1] <= (Formatted_Color[1] + Shade_Variation)) //green
if (row[(x * 3) + 2] >= (Formatted_Color[2] - Shade_Variation) & row[(x * 3) + 2] <= (Formatted_Color[2] + Shade_Variation)) //red
points.Add(new Point(x + rect.X, y + rect.Y));
}
}
RegionIn_Bitmap.Dispose();
return (Point[])points.ToArray(typeof(Point));
}
I call the method like this:
points = PixelSearch(Screen.PrimaryScreen.Bounds, Color.FromArgb(255, 0, 0), 15);
I sometimes get thousands of results from this and would only like a few. any ideas how i can do this?

Image in rowheadercell for dynamic gridview

I am hoping someone can help. In my software I have dynamic Data Grid Views, which all share the common grd name when being made. Each placed into dynamic tabs. All works fine, but I wanted to add an image to the Grid Row Header. There are examples on here for non dynamic grid views, but not for dynamic, so I adapted and used the following code:
private void grd_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
if (e.InheritedRowStyle.BackColor == Color.Gold)
{
Bitmap myBitmap = new Bitmap(imageList1.Images[0]);
Icon myIcon = Icon.FromHandle(myBitmap.GetHicon());
Graphics graphics = e.Graphics;
//Set Image dimension - Users choice
int iconHeight = 16;
int iconWidth = 32;
//Set x/y position - As the center of the RowHeaderCell
int xPosition = ((e.RowBounds.Height * 2) - iconWidth) / 2;
int yPosition = ((e.RowBounds.Y + (e.RowIndex * e.RowBounds.Height) - iconHeight) / 2)+ e.RowBounds.Height + 1;
Rectangle rectangle = new Rectangle(xPosition, yPosition, iconWidth, iconHeight);
graphics.DrawIcon(myIcon, rectangle);
}
else if (e.InheritedRowStyle.BackColor == Color.PowderBlue)
{
Bitmap myBitmap = new Bitmap(imageList1.Images[1]);
Icon myIcon = Icon.FromHandle(myBitmap.GetHicon());
Graphics graphics = e.Graphics;
//Set Image dimension - Users choice
int iconHeight = 16;
int iconWidth = 16;
//Set x/y position - As the center of the RowHeaderCell
int xPosition = ((e.RowBounds.Height * 2) - iconWidth) / 2;
int yPosition = ((e.RowBounds.Y + (e.RowIndex * e.RowBounds.Height) - iconHeight) / 2) + e.RowBounds.Height + 1;
Rectangle rectangle = new Rectangle(xPosition, yPosition, iconWidth, iconHeight);
graphics.DrawIcon(myIcon, rectangle);
}
else if (e.InheritedRowStyle.BackColor == Color.YellowGreen)
{
//Convert the image to icon, inorder to load it in the row header column
Bitmap myBitmap = new Bitmap(imageList1.Images[2]);
Icon myIcon = Icon.FromHandle(myBitmap.GetHicon());
Graphics graphics = e.Graphics;
//Set Image dimension - Users choice
int iconHeight = 16;
int iconWidth = 16;
//Set x/y position - As the center of the RowHeaderCell
int xPosition = ((e.RowBounds.Height *2) - iconWidth) / 2;
int yPosition = ((e.RowBounds.Y + (e.RowIndex * e.RowBounds.Height) - iconHeight) / 2) + e.RowBounds.Height + 1;
Rectangle rectangle = new Rectangle(xPosition, yPosition, iconWidth, iconHeight);
graphics.DrawIcon(myIcon, rectangle);
}
else if (e.InheritedRowStyle.BackColor == Color.White)
{
//Convert the image to icon, inorder to load it in the row header column
Bitmap myBitmap = new Bitmap(imageList1.Images[3]);
Icon myIcon = Icon.FromHandle(myBitmap.GetHicon());
Graphics graphics = e.Graphics;
//Set Image dimension - Users choice
int iconHeight = 16;
int iconWidth = 16;
//Set x/y position - As the center of the RowHeaderCell
int xPosition = ((e.RowBounds.Height * 2) - iconHeight) / 2;
int yPosition = ((e.RowBounds.Y + (e.RowIndex * e.RowBounds.Height) - iconHeight) / 2) + e.RowBounds.Height + 1;
Rectangle rectangle = new Rectangle(xPosition, yPosition, iconWidth, iconHeight);
graphics.DrawIcon(myIcon, rectangle);
}
}
And I am calling this code from a place in the code after the searching is completed and the data sent to the grid using:
grd.RowPostPaint += new System.Windows.Forms.DataGridViewRowPostPaintEventHandler(this.grd_RowPostPaint);
There is a problem however when the software runs maximized the images display ok, when it runs at any size other than the only time they display is on mouseover (not coded that way it just happends that way) and when I scroll they disappear at the bottom of the grid ... any ideas what I am doing wrong (I am not a coder with much experience ... please be kind).

Categories