C# Graphics.FillRectangle not working at all - c#

The code below won't work no matter how many times I press the button, it's really annoying me
private void button2_Click(object sender, EventArgs e)
{
Bitmap screen = new Bitmap(600, 800);
Graphics gfx = Graphics.FromImage(screen);
SolidBrush brush = new SolidBrush(Color.FromArgb(255, 255, 0));
gfx.FillRectangle(brush, 0, 0, 600, 800);
gfx.Dispose();
brush.Dispose();
screen.Dispose();
}

You didn't ever draw your bitmap to the screen. You could do this like that:
private void button2_Click(object sender, EventArgs e)
{
Bitmap screen = new Bitmap(600, 800);
Graphics gfx = Graphics.FromImage(screen);
SolidBrush brush = new SolidBrush(Color.FromArgb(255, 255, 0));
gfx.FillRectangle(brush, 0, 0, 600, 800);
CreateGraphics().DrawImage(screen, 0, 0);
gfx.Dispose();
brush.Dispose();
screen.Dispose();
}
However you shouldn't use that, as it prevents optimal DoubleBuffering to work and as the changes are erased whenever the paint event is fired, and therefore isn't good practice.
Instead you should handle the Paint event (To do this, go to the designer (press F7 in the code behind), select your form, open the properties window (Press F4), select the events tab (click onto the lightning bolt) and double click into the field right to Paint):
private void Form1_Paint(object sender, PaintEventArgs e)
{
Bitmap screen = new Bitmap(600, 800);
Graphics gfx = Graphics.FromImage(screen);
SolidBrush brush = new SolidBrush(Color.FromArgb(255, 255, 0));
gfx.FillRectangle(brush, 0, 0, 600, 800);
e.Graphics.DrawImage(screen, 0, 0);
gfx.Dispose();
brush.Dispose();
screen.Dispose();
}
However it's not recommendable to use a bitmap in that case, as you don't have much being displayed - instead you should directly draw to the graphics of the form:
private void Form1_Paint(object sender, PaintEventArgs e)
{
using (var gfx = e.Graphics)
using (var brush = new SolidBrush(Color.FromArgb(255, 255, 0)))
gfx.FillRectangle(brush, 0, 0, 600, 800);
}
You could notice that I used using, which is good practice, as it automatically disposes the objects.
Now all you have to do (you have to do this for both solutions including the handling of the paint event) is to call Invalidate() in your button click event handling and set a property that tells the paint method that it is being called because a button got pressed:
private void Form1_Paint(object sender, PaintEventArgs e)
{
if (!_button2Pressed)
return;
using (var gfx = e.Graphics)
using (var brush = new SolidBrush(Color.FromArgb(255, 255, 0)))
gfx.FillRectangle(brush, 0, 0, 600, 800);
_button2Pressed = false;
}
private void button2_Click(object sender, EventArgs e)
{
_button2Pressed = true;
Invalidate();
}
private bool _button2Pressed;
This should do it.

Related

C# Drawing on panel in TLP

private void panel1_Paint(object sender, PaintEventArgs e)
{
Graphics graphicObj;
graphicObj = this.CreateGraphics();
Pen myPen = new Pen(System.Drawing.Color.Black, 2);
graphicObj.DrawEllipse(myPen, 200, 200, 200, 200);
}
This work on form. But for auto resizing items such as buttons, label I have to use TablePanelLayout, and drawing on it only works with adding to construtor in form
panel1.Paint+=new PaintEventHandler(panel1_draw);
and then by drawing with this method
private void panel1_Paint(object sender, PaintEventArgs e)
{
var g = e.Graphics;
Pen myp = new Pen(System.Drawing.Color.Red, 4);
Font fy = new Font("Helvetica", 10, FontStyle.Bold);
Brush br = new SolidBrush(System.Drawing.Color.Red);
g.DrawString(textBox1.Text, fy, br, 0,0);
}
Question is Why/what topic should I master to know it.

How to set the background image of a form dynamically on load?

Just create a new windows form application in C# and try this code it does not work as desired:
private void Form1_Load(object sender, EventArgs e)
{
Bitmap rBitmap = new Bitmap(600, 500);
Graphics graphics = Graphics.FromImage(rBitmap);
LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, 600, 500), Color.DeepSkyBlue, Color.Green, LinearGradientMode.Vertical);
brush.SetSigmaBellShape(0.0f, 1f);
graphics.FillRectangle(brush, new Rectangle(0, 0, 600, 500));
Form1.ActiveForm.BackgroundImage = rBitmap;
}
The form loads with defaults. If you add a button to the form and add the same code, it works as desired setting the background image of the form. So how do you accomplish this dynamically in the Form1_Load event so an image is displayed when the program is opened?
Form isn't active during the load event:
Try:
this.BackgroundImage = rBitmap;
And dispose of your objects when you are done:
Bitmap rBitmap = new Bitmap(600, 500);
using (Graphics g = Graphics.FromImage(rBitmap)) {
using (var br = new LinearGradientBrush(new Rectangle(0, 0, 600, 500),
Color.DeepSkyBlue, Color.Green, LinearGradientMode.Vertical)) {
br.SetSigmaBellShape(0.0f, 1f);
g.FillRectangle(br, new Rectangle(0, 0, 600, 500));
}
}
this.BackgroundImage = rBitmap;

Compare two images with PictureBox controls

I'm trying to achieve an effect similar to this site. I am basically trying to implement a way to "compare" two similar images (with different colors, etc). I managed to do this in a not so brilliant way using two PictureBox controls (Winforms) one next to the other, and changing their Size and Location attributes on a MouseMove event.
The result works, but it flickers a lot and it's not really the best way to do it.
Is there a better way to do this, maybe with a WPF or by changing the code in any way? Here it is:
private void pbImg1_MouseMove(object sender, MouseEventArgs e)
{
pbImg2.Image = CropImage(array[1], new Rectangle(pbImg1.Size.Width, 0, totalSize.Width - pbImg1.Size.Width, 240));
pbImg1.Size = new Size(e.X, pbImg1.Height);
pbImg2.Location = new Point(pbImg1.Size.Width + pbImg1.Location.X, pbImg2.Location.Y);
pbImg2.Size = new Size(totalSize.Width - pbImg1.Size.Width, 240);
lpbImg1Size.Text = pbImg1.Size.ToString();
lpbImg2Size.Text = pbImg2.Size.ToString();
lpbImg1Location.Text = pbImg1.Location.ToString();
lpbImg2Location.Text = pbImg2.Location.ToString();
}
private void pbImg2_MouseMove(object sender, MouseEventArgs e)
{
pbImg1.Image = CropImage(array[0], new Rectangle(0, 0, totalSize.Width - pbImg2.Size.Width, 240));
pbImg1.Size = new Size(pbImg1.Width + e.X, 240);
lpbImg1Size.Text = pbImg1.Size.ToString();
lpbImg2Size.Text = pbImg2.Size.ToString();
lpbImg1Location.Text = pbImg1.Location.ToString();
lpbImg2Location.Text = pbImg2.Location.ToString();
}
public Bitmap CropImage(Bitmap source, Rectangle section)
{
// An empty bitmap which will hold the cropped image
//TRY CATCH
Bitmap bmp = new Bitmap(section.Width, section.Height);
Graphics g = Graphics.FromImage(bmp);
// Draw the given area (section) of the source image
// at location 0,0 on the empty bitmap (bmp)
g.DrawImage(source, 0, 0, section, GraphicsUnit.Pixel);
return bmp;
}
And here you can see the behavior of the program:
https://gfycat.com/VillainousReadyAmazonparrot
You need two images imageLeft, imageRight with the same size as the picturebox:
private int pos = 0; //x coordinate of mouse in picturebox
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if(pos == 0)
{
e.Graphics.DrawImage(Properties.Resources.imageRight, new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height));
}
else
{
e.Graphics.DrawImage(Properties.Resources.imageLeft, new Rectangle(0, 0, pos, pictureBox1.Height),
new Rectangle(0, 0, pos, pictureBox1.Height), GraphicsUnit.Pixel);
e.Graphics.DrawImage(Properties.Resources.imageRight, new Rectangle(pos, 0, pictureBox1.Width - pos, pictureBox1.Height),
new Rectangle(pos, 0, pictureBox1.Width - pos, pictureBox1.Height), GraphicsUnit.Pixel);
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
pos = e.X;
pictureBox1.Invalidate();
}

placing the shape in front of the image in c#

i have one picture showing of the human body and i want to use shapes to locate the injuries of the patient. all the shapes will shows off when the user click button. right now im testing with only one shape.
here is my code.
private void button7_Click_4(object sender, EventArgs e)
{
Graphics g = this.CreateGraphics();
g.Clear(this.BackColor);
Image img = Image.FromFile("C:\\Users\\HDAdmin\\Pictures\\humanbody\\effect2.png");
g.DrawImage(img, 0, 0, img.Height, img.Width);
g.Dispose();
}
right now, the shape appear at the back of the image. so how i want to make the shape appear in front of the picture?
Couple of issues.
1) Painting should happen in a paint event. Do not use CreateGraphics since that will only be a temporary drawing.
2) Your DrawImage width and height arguments are reversed.
3) It doesn't look like you are painting the PictureBox control that you have on the form:
private Image img;
public Form1() {
InitializeComponent();
button1.Click += button1_Click;
pictureBox1.Paint += pictureBox1_Paint;
}
void button1_Click(object sender, EventArgs e) {
img = = Image.FromFile("C:\\Users\\HDAdmin\\Pictures\\humanbody\\effect2.png");
pictureBox1.Invalidate();
}
void pictureBox1_Paint(object sender, PaintEventArgs e) {
e.Graphics.Clear(pictureBox1.BackColor);
if (img != null) {
e.Graphics.DrawImage(img, 0, 0, img.Width, img.Height);
//Draw test shape:
e.Graphics.DrawRectangle(Pens.Red, new Rectangle(10, 10, 20, 60));
}
}
I think you should first get graphics of human image and then draw shape image on it. Some thing like that :
Image img = Image.FromFile("C:\\Users\\HDAdmin\\Pictures\\humanbody\\effect2.png");
Graphics g = Graphics.FromImage ( img );
g.DrawImage(ShapeImage, 0, 0, 30, 30); // you can set your required x,y,width,height

How to Save the drawing (contents) from a panel into any format on a physical storage with C#? (WinForms)

Can someone tell me what i don't make as it should, why i cannot save the drawing to a physical storage?
private void panel1_Paint(object sender, PaintEventArgs e)
{
Pen p = new Pen(Color.Red, 3);
Bitmap bmp = new Bitmap(700, 900);
Graphics gr = this.CreateGraphics();
gr.DrawLine(p, new Point(30, 30), new Point(80, 120));
gr.DrawEllipse(p, 30, 30, 80, 120);
//when i do this way it saves only a black rectangle, without other drawn content
bmp.Save(#"C:\testBMP.jpeg", ImageFormat.Jpeg);
// If i use the following 2 commented lines it saves only a empty rectangle.
//Rectangle rec = new Rectangle(0, 0, 700, 900);
// panel1.DrawToBitmap(bmp, rec);
}
Thank you for advice!
You have two problems here.
Drawing your panel's contents. This should be done inside its Paint event handler, like this:
private void panel1_Paint(object sender, PaintEventArgs e)
{
using (Pen p = new Pen(Color.Red, 3))
{
// get the panel's Graphics instance
Graphics gr = e.Graphics;
// draw to panel
gr.DrawLine(p, new Point(30, 30), new Point(80, 120));
gr.DrawEllipse(p, 30, 30, 80, 120);
}
}
Saving your panel's contents as an image. This part should be done somewhere else (for example, when you click on a "Save" button):
private void saveButton_Click(object sender, EventArgs e)
{
int width = panel1.Size.Width;
int height = panel1.Size.Height;
using (Bitmap bmp = new Bitmap(width, height))
{
panel1.DrawToBitmap(bmp, new Rectangle(0, 0, width, height));
bmp.Save(#"C:\testBMP.jpeg", ImageFormat.Jpeg);
}
}
The instance gr has nothing to do with your bitmap (bmp). So you're creating graphics that are associated with the form or control, and have a separate bitmap. When you save the bitmap, you haven't drawn anything in it.
You need to get a Graphics object from the Image, not from your form. I have not tested this, but it should work.
private void panel1_Paint(object sender, PaintEventArgs e)
{
using (Pen p = new Pen(Color.Red, 3))
using (Bitmap bmp = new Bitmap(700, 900))
using (Graphics gr = Graphics.FromImage(bmp))
{
gr.DrawLine(p, new Point(30, 30), new Point(80, 120));
gr.DrawEllipse(p, 30, 30, 80, 120);
bmp.Save(#"C:\testBMP.jpeg", ImageFormat.Jpeg);
}
}

Categories

Resources