Draw over a bitmap loaded in a picturebox - c#

I need to draw over a bitmap loaded in a PictureBox. I've been looking for a way on this site but the answers don't work because the resulting image is in a wrong location.
private void pbImage_MouseClick(object sender, MouseEventArgs e)
{
currentImage = pbImage.Image;
Bitmap imageAux = new Bitmap(currentImage.Width, currentImage.Height);
using (Graphics g = Graphics.FromImage(imageAux))
{
Brush brush = new SolidBrush(Color.Red);
Pen pen = new Pen(Color.Black, 10);
g.DrawImage(currentImage, pbImage.Location);
g.Flush();
if (e.Button == MouseButtons.Left)
{
Control control = (Control)sender;
punto = ((Control)sender).PointToScreen(new Point(e.X, e.Y)); ;
g.DrawRectangle(pen, new Rectangle(punto.X, punto.Y, 50, 50));
g.FillRectangle(brush, new Rectangle(punto.X, punto.Y, 50, 50));
g.Flush();
g.Dispose();
pbImage.Invalidate();
}
}
pbImage.Refresh();
currentImage.Save("C:\\prueba3.bmp");
imageAux.Save("C:\\prueba4.bmp");
pbImage.Image = (Image)imageAux.Clone();
}

You should create additional Bitmaps to draw.
Load the original in a Bitmap.
Create a bitmap to assign to the picturebox. (backpage)
Create/Generate a grayscale version of the original bitmap.
When it needs to draw:
Clear the picturebox bitmap
Draw the grayscale onto
Draw the 50, 50 rect of the original on the selection location in the picturebox bitmap
Refresh het picturebox
Here's an example, Add a picturebox to the Form and replace the filename with your image filename.
public partial class Form1 : Form
{
private Bitmap _originalBitmap;
private Bitmap _grayScaleBitmap;
private Bitmap _pictureBoxBitmap;
//private Brush brush = new SolidBrush(Color.Red);
private Pen pen = new Pen(Color.Black, 1);
private Point? _inspectRectStart;
public Form1()
{
InitializeComponent();
_originalBitmap = (Bitmap)Bitmap.FromFile("lin-png-256x256-Rafael_256x256_png-256x256.png");
_grayScaleBitmap = MakeGrayscale3(_originalBitmap);
_pictureBoxBitmap = new Bitmap(_originalBitmap.Width, _originalBitmap.Height);
DrawImage();
pictureBox1.Image = _pictureBoxBitmap;
}
private static Bitmap MakeGrayscale3(Bitmap original)
{
//create a blank bitmap the same size as original
Bitmap newBitmap = new Bitmap(original.Width, original.Height);
//get a graphics object from the new image
Graphics g = Graphics.FromImage(newBitmap);
//create the grayscale ColorMatrix
ColorMatrix colorMatrix = new ColorMatrix(
new float[][]
{
new float[] {.3f, .3f, .3f, 0, 0},
new float[] {.59f, .59f, .59f, 0, 0},
new float[] {.11f, .11f, .11f, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {0, 0, 0, 0, 1}
});
//create some image attributes
ImageAttributes attributes = new ImageAttributes();
//set the color matrix attribute
attributes.SetColorMatrix(colorMatrix);
//draw the original image on the new image
//using the grayscale color matrix
g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height),
0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes);
//dispose the Graphics object
g.Dispose();
return newBitmap;
}
private void DrawImage()
{
using (Graphics g = Graphics.FromImage(_pictureBoxBitmap))
{
g.Clear(Color.White); // if the bitmap has transparent parts
// draw the grayscale image.
g.DrawImage(_grayScaleBitmap, new Rectangle(0, 0, _originalBitmap.Width, _originalBitmap.Height), 0, 0, _originalBitmap.Width, _originalBitmap.Height, GraphicsUnit.Pixel);
// if there is a selection, draw it.
if (_inspectRectStart.HasValue)
{
var rect = new Rectangle(_inspectRectStart.Value, new Size(50, 50));
// draw the original bitmap in a rectangle.
g.DrawImage(_originalBitmap, _inspectRectStart.Value.X, _inspectRectStart.Value.Y, rect, GraphicsUnit.Pixel);
g.DrawRectangle(pen, rect);
}
}
pictureBox1.Refresh();
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
// move the rectangle position
_inspectRectStart = e.Location;
// redraw image.
DrawImage();
}
}

I think, thats because g.DrawImage(currentImage, pbImage.Location); will draw the image relative on the imageAux with the actual location of the pbImage in relation to it's parent. try new Point(); instead.

Related

Why when cropping image i'm getting black image of the cropped image?

In form1 constructor
public Form1()
{
InitializeComponent();
BackColor = Color.LightGreen;
TransparencyKey = Color.LightGreen;
this.TopMost = true;
this.Location = new Point(0, 0);
timer1.Enabled = true;
}
Then:
private void Cap()
{
countImages++;
ScreenCapture sc = new ScreenCapture();
Image img = sc.CaptureScreen();
Bitmap bmp = new Bitmap(img);
Bitmap source = new Bitmap(this.Width, this.Height);
Rectangle section = new Rectangle(new Point(source.Width, source.Height), source.Size);
Bitmap CroppedImage = CropImage(source, section);
CroppedImage.Save("c:\\temp\\screens\\" + countImages + ".gif", ImageFormat.Gif);
source.Dispose();
}
And
public Bitmap CropImage(Bitmap source, Rectangle section)
{
// An empty bitmap which will hold the cropped image
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;
}
The Bitmaps i save to the hard disk:
CroppedImage.Save("c:\\temp\\screens\\" + countImages + ".gif", ImageFormat.Gif);
They are all black.
I want to crop this part from the image and save it to the hard disk.
Example of screenshot and what i want to crop from it:
I marked with a red circle the transparent form1 and this is what i want to crop the part of the form1 and save this as cropped image the form1 part:
I tried this first:
private void CaptureDesktop()
{
countImages++;
ScreenCapture sc = new ScreenCapture();
Image img = sc.CaptureScreen();
Bitmap bmp = new Bitmap(img);
Bitmap source = new Bitmap(this.Width, this.Height);
Rectangle section = new Rectangle(new Point(source.Width, source.Height), source.Size);
Bitmap CroppedImage = CropImage(bmp, section);
CroppedImage.Save("c:\\temp\\desktopscreens\\" + countImages + ".gif", ImageFormat.Gif);
}
But i'm getting this cropped image as result: Strange picture in picture ?
Then i tried this code:
using (Bitmap bmpScreenCapture = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height))
{
using (Graphics g = Graphics.FromImage(bmpScreenCapture))
{
g.CopyFromScreen(this.Location.X,
this.Location.Y,
0, 0,
this.Size,
CopyPixelOperation.SourceCopy);
}
Rectangle section = new Rectangle(new Point(this.Location.X, this.Location.Y), new Size(this.Width, this.Height));
Bitmap CroppedImage = CropImage(bmpScreenCapture, section);
CroppedImage.Save("c:\\temp\\desktopscreens\\1.bmp", ImageFormat.Bmp);
}
But the result is:
Not what i wanted. I want only to crop the form1 part from the whole image.
You do Bitmap source = new Bitmap(this.Width, this.Height); this creates a black image.
Then you proceed to crop it. That's still a black image.
Then you proceed to save it. That's still a black image.
Perhaps you meant to crop Bitmap bmp or Image img, not Bitmap source. I don't know what Bitmap source is meant to be.
Try this (some code from Capture the screen shot using .NET)
private void Cap()
{
using (Bitmap bmpScreenCapture = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height))
{
using (Graphics g = Graphics.FromImage(bmpScreenCapture))
{
g.CopyFromScreen(this.Location.X,
this.Location.Y,
0, 0,
this.Size,
CopyPixelOperation.SourceCopy);
}
Rectangle section = new Rectangle(new Point(this.Location.X, this.Location.Y), new Size(this.Width, this.Height));
Bitmap CroppedImage = CropImage(bmpScreenCapture, section);
CroppedImage.Save("c:\\temp\\screens\1.bmp", ImageFormat.Bmp);
}
}
public Bitmap CropImage(Bitmap source, Rectangle section)
{
// An empty bitmap which will hold the cropped image
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;
}

How can I draw a known rectangle size on a new bitmap?

I have this code:
Bitmap newbmp = new Bitmap(512, 512);
foreach (Point s in CommonList)
{
w.WriteLine("The following points are the same" + s);
newbmp.SetPixel(s.X, s.Y, Color.Red);
}
w.Close();
newbmp.Save(#"c:\newbmp\newbmp.bmp", ImageFormat.Bmp);
newbmp.Dispose();
The code is not in a paint event.
Then I have a paint event of a pictureBox1:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (cloudPoints != null)
{
if (DrawIt)
{
e.Graphics.DrawRectangle(pen, rect);
pointsAffected = cloudPoints.Where(pt => rect.Contains(pt));
CloudEnteringAlert.pointtocolorinrectangle = pointsAffected.ToList();
Bitmap bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height, PixelFormat.Format32bppArgb);
CloudEnteringAlert.Paint(e.Graphics, 1, 200, bmp);
}
}
}
In the paint event I'm drawing a rectangle. The variable rect.
I want to draw the rectangle rect on the newbmp. After saving the newbmp to draw this rect on him.
How can I draw the rect on the newbmp ?
You should create a Graphics object from the bitmap to work on it:
..
Bitmap newbmp = new Bitmap(512, 512);
foreach (Point s in CommonList)
{
Console.WriteLine("The following points are the same" + s);
newbmp.SetPixel(s.X, s.Y, Color.Red);
}
using (Graphics G = Graphics.FromImage(newbmp))
{
G.DrawRectangle(Pens.Red, yourRectangle);
..
}
newbmp.Save(#"c:\newbmp\newbmp.bmp", ImageFormat.Bmp);
newbmp.Dispose();
For other Pen properties like Width or LineJoin use this format:
using (Graphics G = Graphics.FromImage(newbmp))
using (Pen pen = new Pen(Color.Red, 8f) )
{
// rounded corners please!
pen.LineJoin = System.Drawing.Drawing2D.LineJoin.Round;
G.DrawRectangle(pen, yourRectangle);
//..
}

Adding Height to Image for Subtitle

i want to add an additonal height to an Image to give it a subtitle.
I do not want to "compres" or resize my original image.
I want to keep it's size and add +40 px to its height on bottom and add a text like this example
The red part is the original image.
The blue part is my addition.
I tried this code but my text appears "outside" the image i think.
Image image = Image.FromFile("D:\\my_sample_image.jpg");
// Create graphics from image
Graphics graphics = Graphics.FromImage(image);
// Create font
Font font = new Font("Times New Roman", 42.0f);
// Create text position
PointF point = new PointF(150, image.Height+40);
// Draw text
graphics.DrawString("Watermark", font, Brushes.Red, point);
// Save image
image.Save("D:\\my_sample_output.jpg");
MessageBox.Show("FINISHED");
// Open generated image file in default image viewer installed in Windows
Process.Start("D:\\my_sample_output.jpg");
Make a new Bitmap, create a Graphics out of it, then draw the old image with room for text at the bottom.
Bitmap image = new Bitmap("path/resource");
Bitmap newImage = new Bitmap(image.Width, image.Height + 40);
using (Graphics g = Graphics.FromImage(newImage))
{
// Draw base image
Rectangle rect = new Rectangle(0, 0, image.Width, image.Height);
g.DrawImageUnscaledAndClipped(image, rect);
//Fill undrawn area
g.FillRectangle(new SolidBrush(Color.Black), 0, image.Height, newImage.Width, 40);
// Create font
Font font = new Font("Times New Roman", 22.0f);
// Create text position (play with positioning)
PointF point = new PointF(0, image.Height);
// Draw text
g.DrawString("Watermark", font, Brushes.Red, point);
}
public Image addSubtitleToImage(string path, int height, string title)
{
Bitmap image = new Bitmap(path);
Bitmap newImage = new Bitmap(image.Width, image.Height + height);
using (Graphics g = Graphics.FromImage(newImage))
{
g.FillRectangle(new SolidBrush(Color.Black), new Rectangle(0, 0, newImage.Width, newImage.Height));
g.DrawImage(image, new Rectangle(0, 0, image.Width, image.Height));
Font font = new Font("Tahoma", 30.0f);
g.DrawString(title, font, Brushes.White, new PointF(image.Width/2 , image.Height+));
}
return newImage;
}

Drawing a point in an image in C#

I have an image with the dimensions of 100x50 and I want to draw a dot in the center - i.e. at 50x25. How would I do this?
you could use the setPixle() function.
Graphics g = pictureBox1.CreateGraphics();
g.DrawEllipse(Pens.Black, new Rectangle(50, 25, 1, 1));
look here for saving the picture
it does not draw on form load so you should add your code in form paintevent :
private void Form1_Paint(object sender, PaintEventArgs e)
{
Application.DoEvents();
Graphics g = pictureBox1.CreateGraphics();
g.DrawEllipse(Pens.DarkBlue, new Rectangle(120, 90, 1, 1));
}
Image img = pictureBox1.Image;
Graphics g = Graphics.FromImage(img);
g.DrawEllipse(Pens.DarkBlue, new Rectangle(50, 25, 1, 1));
g.DrawImage(img, new Point(0, 0));
img.Save("d:\\img.Jpeg", System.Drawing.Imaging.ImageFormat.Jpeg);
try this for other question :
Rectangle bounds = new Rectangle(10, 20, 50, 60);
Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height);
Graphics g = Graphics.FromImage(bitmap);
g.CopyFromScreen(Point.Empty,Point.Empty, bounds.Size);
bitmap.Save("d:\\img.Jpeg", System.Drawing.Imaging.ImageFormat.Jpeg);
this code will capture screen with bound of bounds rectangle.

How can I draw a small image over an image using Graphics library C# ?

When I try to draw an image over another one using Graphics library C# it scale the small one and cover the first one:
public Form1()
{
//InitializeComponent();
read_file();
InitializeComponent1();
SetStyle(ControlStyles.Opaque, true);
// theImage = new Bitmap("F:/4th year/1st Term/sensor network/proj/reconstructscene/reconstructscene/images/tryImage.jpg");
theImage2 = new Bitmap("F:/4th year/1st Term/sensor network/proj/reconstructscene/reconstructscene/images/1.jpg");
// theImage = new Bitmap(newImage);
theImage = new Bitmap("F:/4th year/1st Term/sensor network/proj/reconstructscene/reconstructscene/images/tryImage.jpg");
}
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
//e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
//e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
//e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.DrawImage(theImage, ClientRectangle);
// Create pen.
g.FillRectangle(new SolidBrush(Color.Red), 50, 50, 50, 50);
RectangleF recto = new System.Drawing.RectangleF(50, 50, 50, 50);
Pen blackPen = new Pen(Color.Black,1);
g.DrawRectangle(blackPen, 50, 50, 50, 50);
g.DrawImage(theImage2, ClientRectangle); //this will cover the 1st one
}
Have this instead:
g.DrawImage(theImage2, 0, 0, theImage2.Width, theImage2.Height);
This should draw the image in the "proper" place without stretching it.
look at draw on image
insteed DrawString you should use DrawImage

Categories

Resources