private Bitmap CropImage()
{
Bitmap pic = pictureBoxSnap.Image as Bitmap;
Bitmap cropped = new Bitmap(rect.Width, rect.Height);
using (Graphics g = Graphics.FromImage(cropped))
{
g.DrawImage(pic, new Rectangle(0, 0, rect.Width, rect.Height),
rect, GraphicsUnit.Pixel);
}
pic.Save(#"c:\temp\testingitimage.jpg");
cropped.Save(#"c:\temp\testingitimage1.bmp");
return cropped;
}
I added this two lines of Save to test what i get. The first one pic i see the correct image that is in the pictureBox.
But the second one cropped is all white and empty.
And i call this method from the pictureBox paint event:
private void pictureBoxSnap_Paint(object sender, PaintEventArgs e)
{
if (pictureBoxSnap.Image != null)
{
{
if (ClearGraphics == false)
{
if (cropRect == false)
{
if (rectangles[listBoxSnap.SelectedIndex] != Rectangle.Empty)
{
e.Graphics.DrawRectangle(Pens.Firebrick, rectangles[listBoxSnap.SelectedIndex]);
}
}
else
{
if (rect.Width > 10 && rect.Height > 10)
{
e.Graphics.DrawRectangle(Pens.Gray, rect);
pictureBoxSnap.Image = CropImage();
Image img = CropImage();
img.Save(#"c:\temp\testimageing.jpg");
}
}
}
}
}
}
I used a breakpoint on the: e.Graphics.DrawRectangle(Pens.Gray, rect); and rect is not empty ( rect is Rectangle i draw on the pictureBox then when i click on a button it's making validate for the pictureBox).
I also did a save here too and testimageing i see it black on the hard disk but when i edit it with Paint i see it's white empty.
For exmaple when i draw a rectangle on the pictureBox then i use a breakpoint in the CropImage method i see that the variable rect is for example: X = 136 Y = 149 Width = 131 Height = 106
Also in the paint event this rect variable have the same values.
And the pictureBox size is: 640x480
And the pictureBox property SizeMode is set to: zoom
Wo why i get empty white image ? And not the cropped rectangle with the part of the image inside ?
EDIT:
This is the code im using now:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using DannyGeneral;
using System.Diagnostics;
namespace MinimizeCapture
{
public partial class Form1 : Form
{
Boolean bHaveMouse;
Point ptOriginal = new Point();
Point ptLast = new Point();
bool cropRect;
Bitmap cloneBitmap;
Rectangle recttest;
private Rectangle Rect;
private Rectangle[] rectangles;
private Rectangle RectClone;
private bool btn = false;
private Point RectStartPoint = Point.Empty;
private Point RectEndPoint = Point.Empty;
private Brush selectionBrush = new SolidBrush(Color.Red);
private Pen pen;
private string selectedIndex;
private List<string> drawnItems = new List<string>();
private bool ClearGraphics;
public Form1()
{
InitializeComponent();
cropRect = false;
var windows = OpenWindowGetter.FindWindowsWithText();
ClearGraphics = false;
this.DoubleBuffered = true;
btn = false;
pen = new Pen(selectionBrush);
buttonSnap.Enabled = false;
backgroundWorker1.RunWorkerAsync();
}
private void buttonSnap_Click(object sender, EventArgs e)
{
ClearGraphics = true;
this.listBoxSnap.Items.Clear();
this.pictureBoxSnap.Image = null;
backgroundWorker1.RunWorkerAsync();
}
private void listBoxSnap_SelectedIndexChanged(object sender, EventArgs e)
{
WindowSnap snap = this.listBoxSnap.SelectedItem as WindowSnap;
selectedIndex = this.listBoxSnap.SelectedIndex.ToString();
this.pictureBoxSnap.Image = snap.Image;
for (int i = 0; i < rectangles.Length; i++)
{
if (rectangles[i] != RectClone)
{
ClearGraphics = false;
}
else
{
ClearGraphics = true;
}
}
}
private void checkBoxForceMDI_CheckedChanged(object sender, EventArgs e)
{
WindowSnap.ForceMDICapturing = (sender as CheckBox).Checked;
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
listBoxSnap.Invoke(new MethodInvoker(delegate { this.listBoxSnap.Items.Add("Minimized Windows"); }));
listBoxSnap.Invoke(new MethodInvoker(delegate { this.listBoxSnap.Items.AddRange(WindowSnap.GetAllWindows(true,true).ToArray()); }));
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
rectangles = new Rectangle[listBoxSnap.Items.Count];
buttonSnap.Enabled = true;
}
private void pictureBoxSnap_Paint(object sender, PaintEventArgs e)
{
if (pictureBoxSnap.Image != null)
{
{
if (ClearGraphics == false)
{
if (rectangles[listBoxSnap.SelectedIndex] != Rectangle.Empty)
{
e.Graphics.DrawRectangle(Pens.Firebrick, rectangles[listBoxSnap.SelectedIndex]);
}
}
if (cropRect == true)
{
if (recttest.Width > 10 && recttest.Height > 10)
{
//e.Graphics.DrawRectangle(Pens.Gray, recttest);
e.Graphics.Clear(Color.White);
/*pictureBoxSnap.Image = CropImage();
Image img = CropImage();
img.Save(#"c:\temp\testimageing.jpg");*/
}
}
}
}
}
private void pictureBoxSnap_MouseMove(object sender, MouseEventArgs e)
{
if (btn == true)
{
ClearGraphics = false;
RectEndPoint = e.Location;
int currentindex = listBoxSnap.SelectedIndex;
rectangles[currentindex] = RectClone;
Rect = getRect(RectStartPoint, RectEndPoint);
RectClone = Rect;
pictureBoxSnap.Invalidate();
}
Point ptCurrent = new Point(e.X, e.Y);
// If we "have the mouse", then we draw our lines.
if (bHaveMouse)
{
// If we have drawn previously, draw again in
// that spot to remove the lines.
if (ptLast.X != -1)
{
MyDrawReversibleRectangle(ptOriginal, ptLast);
}
// Update last point.
ptLast = ptCurrent;
// Draw new lines.
MyDrawReversibleRectangle(ptOriginal, ptCurrent);
}
}
private void pictureBoxSnap_MouseDown(object sender, MouseEventArgs e)
{
RectStartPoint = e.Location;
btn = true;
Rect = Rectangle.Empty;
RectClone = Rectangle.Empty;
bHaveMouse = true;
// Store the "starting point" for this rubber-band rectangle.
ptOriginal.X = e.X;
ptOriginal.Y = e.Y;
// Special value lets us know that no previous
// rectangle needs to be erased.
ptLast.X = -1;
ptLast.Y = -1;
}
private void pictureBoxSnap_MouseUp(object sender, MouseEventArgs e)
{
recttest = rectangles[listBoxSnap.SelectedIndex];
ClearGraphics = false;
btn = false;
RectEndPoint = e.Location;
pictureBoxSnap.Invalidate();
int currentindex = listBoxSnap.SelectedIndex;
rectangles[currentindex] = RectClone;
// Set internal flag to know we no longer "have the mouse".
bHaveMouse = false;
// If we have drawn previously, draw again in that spot
// to remove the lines.
if (ptLast.X != -1)
{
Point ptCurrent = new Point(e.X, e.Y);
MyDrawReversibleRectangle(ptOriginal, ptLast);
}
// Set flags to know that there is no "previous" line to reverse.
ptLast.X = -1;
ptLast.Y = -1;
ptOriginal.X = -1;
ptOriginal.Y = -1;
pictureBoxSnap.Invalidate();
}
Rectangle getRect(Point p1, Point p2)
{
Point p = new Point(Math.Min(p1.X, p2.X), Math.Min(p1.Y, p2.Y));
Size s = new Size(Math.Abs(p1.X - p2.X), Math.Abs(p1.Y - p2.Y));
return new Rectangle(p, s);
}
private void ConfirmRectangle_Click(object sender, EventArgs e)
{
ConfirmRectangle.ForeColor = Color.Red;
ConfirmRectangle.Enabled = false;
StreamWriter w = new StreamWriter(#"c:\temp\Settings.txt", true);
w.WriteLine("Rectangle Location: " + RectClone.Location + " Rectangle Size: " + RectClone.Size + " Selected Index: " + selectedIndex);
textBoxIndex.Text = selectedIndex.ToString();
w.Close();
cropRect = false;
//pictureBoxSnap.Invalidate();
Image img = CropImage();
img.Save(#"c:\temp\testimageing.jpg");
pictureBoxSnap.Image = img;
}
// Convert and normalize the points and draw the reversible frame.
private void MyDrawReversibleRectangle(Point p1, Point p2)
{
Rectangle rc = new Rectangle();
// Convert the points to screen coordinates.
p1 = pictureBoxSnap.PointToScreen(p1);
p2 = pictureBoxSnap.PointToScreen(p2);
// Normalize the rectangle.
if (p1.X < p2.X)
{
rc.X = p1.X;
rc.Width = p2.X - p1.X;
}
else
{
rc.X = p2.X;
rc.Width = p1.X - p2.X;
}
if (p1.Y < p2.Y)
{
rc.Y = p1.Y;
rc.Height = p2.Y - p1.Y;
}
else
{
rc.Y = p2.Y;
rc.Height = p1.Y - p2.Y;
}
// Draw the reversible frame.
rect = new Rectangle(pictureBoxSnap.PointToClient(rc.Location), rc.Size);
ControlPaint.DrawReversibleFrame(rc, Color.Gray, FrameStyle.Dashed);
}
Rectangle rect = Rectangle.Empty;
private Bitmap CropImage()
{
//rect = recttest;
Bitmap pic = pictureBoxSnap.Image as Bitmap;
Bitmap cropped = new Bitmap(rect.Width, rect.Height);
using (Graphics g = Graphics.FromImage(cropped))
{
g.DrawImage(pic, new Rectangle(0, 0, rect.Width, rect.Height),
rect, GraphicsUnit.Pixel);
}
pic.Save(#"c:\temp\testingitimage.jpg");
cropped.Save(#"c:\temp\testingitimage1.bmp");
return cropped;
}
}
}
Moved the CropImage call method from the paint and added it to the button click here:
private void ConfirmRectangle_Click(object sender, EventArgs e)
{
ConfirmRectangle.ForeColor = Color.Red;
ConfirmRectangle.Enabled = false;
StreamWriter w = new StreamWriter(#"c:\temp\Settings.txt", true);
w.WriteLine("Rectangle Location: " + RectClone.Location + " Rectangle Size: " + RectClone.Size + " Selected Index: " + selectedIndex);
textBoxIndex.Text = selectedIndex.ToString();
w.Close();
cropRect = false;
//pictureBoxSnap.Invalidate();
Image img = CropImage();
img.Save(#"c:\temp\testimageing.jpg");
pictureBoxSnap.Image = img;
}
This lines:
Image img = CropImage();
img.Save(#"c:\temp\testimageing.jpg");
pictureBoxSnap.Image = img;
But what i get in the pictureBox is this:
Not sure why. The rectangle is in the position i drawed it's ok but instead showing the part of the original image cut in the rectangle it's doing like zoom in.
You are cropping multiple times.
pictureBoxSnap.Image = CropImage(); // First Time
Image img = CropImage(); // Second Time
img.Save(#"c:\temp\testimageing.jpg");
You just need to crop once. Here you are using same picturebox for source and for cropped image. first time when you crop then image. the cropped image will be set correctly to the picturebox. but, second time application will try to crop that image again.
You should do like this
Image img = CropImage();
img.Save(#"c:\temp\testimageing.jpg");
pictureBoxSnap.Image = img;
private Bitmap CropImage(){
Bitmap pic = pictureBoxSnap.Image as Bitmap;
Bitmap cropped = new Bitmap(rect.Width, rect.Height);
using (Graphics g = Graphics.FromImage(cropped)){
g.DrawImage(pic, new Rectangle(0, 0, rect.Width, rect.Height),
rect, GraphicsUnit.Pixel);
}
using (Graphics g = Graphics.FromImage(pic)){
g.DrawImage(cropped , 136, 149, rect.Width, rect.Height);
//Draw the rectangle
}
//pic.Save(#"c:\temp\testingitimage.jpg");
//cropped.Save(#"c:\temp\testingitimage1.bmp");
return pic;
}
valter
Related
I'm using WinForms. In my form i have a picturebox that contains an image. I provided my code which highlights images by right-clicking and dragging the mouse.
How do I print the image and what i highlighted in the picturebox?
private Random _rnd = new Random();
private Point _pt;
private Point _pt2;
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
//set the upper left point of our selection rectangle
if (e.Button == MouseButtons.Left)
_pt = e.Location;
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
//display the selected part when mouse button gets released
if (e.Button == MouseButtons.Left)
{
GenerateBmp();
}
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
//if we have a valid rectangle, draw it
if (_pt.X - _pt2.X != 0 && _pt.Y - _pt2.Y != 0)
{
//fill
using (SolidBrush sb = new SolidBrush(Color.FromArgb(95, 255, 255, 0)))
e.Graphics.FillRectangle(sb, new Rectangle(_pt.X, _pt.Y, _pt2.X - _pt.X, _pt2.Y - _pt.Y));
//draw
e.Graphics.DrawRectangle(Pens.Blue, new Rectangle(_pt.X, _pt.Y, _pt2.X - _pt.X, _pt2.Y - _pt.Y));
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
//set the bottom right one
if (e.Button == MouseButtons.Left)
{
_pt2 = e.Location;
this.pictureBox1.Invalidate();
}
}
private void GenerateBmp()
{
//check, if we have a valid rectangle
if (_pt2.X - _pt.X > 0 && _pt2.Y - _pt.Y > 0)
{
//create that rectangle
Rectangle r = new Rectangle(_pt.X, _pt.Y, _pt2.X - _pt.X, _pt2.Y - _pt.Y);
//create a new Bitmap with the size of the selection-rectangle
Bitmap bmp = new Bitmap(r.Width, r.Height);
//draw the selectex part of the original image
using (Graphics g = Graphics.FromImage(bmp))
g.DrawImage(this.pictureBox1.Image, new Rectangle(0, 0, r.Width, r.Height), r, GraphicsUnit.Pixel);
}
}
private Bitmap SetUpPictures(PictureBox pb)
{
//create a bitmap to display
Bitmap bmp1 = new Bitmap(pb.ClientSize.Width, pb.ClientSize.Height);
//get the graphics-context
using (Graphics g = Graphics.FromImage(bmp1))
{
//get a random, opaque, color
Color c = Color.FromArgb(255, _rnd.Next(256), _rnd.Next(256), _rnd.Next(256));
g.Clear(c);
//better smoothinmode for round shapes
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
//draw ten shapes to the bitmap
for (int i = 0; i < 10; i++)
{
//loaction and size rectangle
Rectangle r = new Rectangle(_rnd.Next(pb.ClientSize.Width / 2), _rnd.Next(pb.ClientSize.Height / 2),
_rnd.Next(pb.ClientSize.Width / 2), _rnd.Next(pb.ClientSize.Height / 2));
//random color
Color c2 = Color.FromArgb(_rnd.Next(256), _rnd.Next(256), _rnd.Next(256), _rnd.Next(256));
//one color brush
using (SolidBrush sb = new SolidBrush(c2))
{
//check, if i is odd or even and decide on that to draw rectangles or ellipses
if ((i & 0x01) == 1)
g.FillEllipse(sb, r);
else
g.FillRectangle(sb, r);
}
}
}
//return our artwork
return bmp1;
}
private void Btn_Print_Click(object sender, EventArgs e)
{
System.Drawing.Printing.PrintDocument myPrintDocument1 = new System.Drawing.Printing.PrintDocument();
PrintDialog myPrinDialog1 = new PrintDialog();
myPrintDocument1.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(DVPrintDocument_PrintPage);
myPrinDialog1.Document = myPrintDocument1;
if (myPrinDialog1.ShowDialog() == DialogResult.OK)
{
myPrintDocument1.Print();
}
}
private void DVPrintDocument_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
e.Graphics.DrawImage(pictureBox1.Image, 25, 25, 800, 1050);
var rc = new RectangleF(0, 0, pictureBox1.Image.Width / 100f, pictureBox1.Image.Height / 100f);
e.Graphics.DrawImage(pictureBox1.Image, rc);
}
You can draw the content of picturebox simply using DrawToBitmap method:
For example:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawRectangle(Pens.Red, new Rectangle(10, 10, 100, 100));
}
private void button1_Click(object sender, EventArgs e)
{
this.printDocument1.Print();
}
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
var bmp=new Bitmap(this.pictureBox1.Width, this.pictureBox1.Height);
this.pictureBox1.DrawToBitmap(bmp,this.pictureBox1.ClientRectangle);
e.Graphics.DrawImageUnscaled(bmp, 0, 0);
}
And here is the printed result:
I am creating a program that can track multiple objects and get their centroid eventually I would use these centroids to connect to the nearest centroid of another object. But my problem is, my program tracks only one significant object on the video and it doesn't seem to display the centroid of this object. anyone can help me?
namespace Video_Processing_fixed_
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Bitmap video;
Graphics g;
bool OnOff;
int mode;
int thoigiandemnguoc = 5;
private FilterInfoCollection CaptureDevice;
private VideoCaptureDevice FinalFrame;
private void Form1_Load(object sender, EventArgs e)
{
CaptureDevice = new FilterInfoCollection(FilterCategory.VideoInputDevice);
foreach (FilterInfo Device in CaptureDevice)
{
comboBox1.Items.Add(Device.Name);
}
comboBox1.SelectedIndex = 0;
FinalFrame = new VideoCaptureDevice();
}
private void button1_Click(object sender, EventArgs e)
{
FinalFrame = new VideoCaptureDevice(CaptureDevice[comboBox1.SelectedIndex].MonikerString);
FinalFrame.NewFrame+=new NewFrameEventHandler(FinalFrame_NewFrame);
FinalFrame.Start();
}
void FinalFrame_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
video = (Bitmap)eventArgs.Frame.Clone();
Bitmap video2 = (Bitmap)eventArgs.Frame.Clone();
g = Graphics.FromImage(video2);
g.DrawString("Test", new Font("Arial", 20), new SolidBrush(Color.White), new PointF(2, 2));
g.Dispose();
if (mode == 1)
{
// create filter
EuclideanColorFiltering filter = new EuclideanColorFiltering();
// set center colol and radius
filter.CenterColor = Color.FromArgb(215, 30, 30);
filter.Radius = 100;
// apply the filter
filter.ApplyInPlace(video2);
BlobCounter blobcounter = new BlobCounter();
blobcounter.MinWidth = 5;
blobcounter.MinHeight = 5;
blobcounter.FilterBlobs = true;
blobcounter.ObjectsOrder = ObjectsOrder.Area;
blobcounter.ProcessImage(video2);
Blob[] blobs = blobcounter.GetObjectsInformation();
AForge.Point Center = new AForge.Point();
if (blobs.Length > 0)
{
Center.X = blobs.Average(c => c.CenterOfGravity.X);
Center.Y = blobs.Average(c => c.CenterOfGravity.Y);
}
Rectangle[] rects = blobcounter.GetObjectsRectangles();
foreach(Rectangle recs in rects)
if (rects.Length > 0)
{
foreach (Rectangle objectRect in rects)
{
Graphics graphic = Graphics.FromImage(video2);
using (Pen pen = new Pen(Color.FromArgb(160, 255, 160), 5))
{
graphic.DrawRectangle(pen, objectRect);
}
graphic.Dispose();
}
}
( Pen pen = new Pen(Color.White,3))
pictureBox2.Image = video2;
pictureBox1.Image = video;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (FinalFrame.IsRunning==true)
{
FinalFrame.SignalToStop();
FinalFrame.WaitForStop();
}
}
private void button2_Click(object sender, EventArgs e)
{
pictureBox2.Image = (Bitmap)pictureBox1.Image.Clone();
}
private void ButObjTrack_Click(object sender, EventArgs e)
{
mode = 1;
}
private void StopButt_Click(object sender, EventArgs e)
{
FinalFrame.SignalToStop();
}
}
}
You do not display the average center value. Change these lines:
Rectangle[] rects = blobcounter.GetObjectsRectangles();
foreach(Rectangle recs in rects)
if (rects.Length > 0)
{
foreach (Rectangle objectRect in rects)
{
Graphics graphic = Graphics.FromImage(video2);
using (Pen pen = new Pen(Color.FromArgb(160, 255, 160), 5))
{
graphic.DrawRectangle(pen, objectRect);
}
graphic.Dispose();
}
}
To these:
Rectangle[] rects = blobcounter.GetObjectsRectangles();
foreach (Rectangle recs in rects)
{
if (rects.Length > 0)
{
Graphics graphic = Graphics.FromImage(video2);
foreach (Rectangle objectRect in rects)
{
graphic.DrawRectangle(Pens.LightGreen, objectRect);
}
graphic.DrawRectangle(Pens.Red, Center.X - 4, Center.Y - 4, 8, 8);
graphic.Dispose();
}
}
I am attempting to save an image as modified by graphics tools such as pens and shapes that can be drawn onto the image. I have done this using a panel with background image and trying to set up a bit map that will save changes within this panel:
private void saveToolStripButton_Click(object sender, EventArgs e)
{
//sets panel1 contents as bit map to be saved at set locations
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:\Users\Me\Pics\testBitmap.jpeg", ImageFormat.Jpeg);
}
MessageBox.Show("Your image has been saved");
}
Once the save button is clicked, the image saves ok but the changes made with the graphics tools do not show up. Can anyone suggest a solution?
Here is some code regarding the graphics tool i've set up for use within the panel:
{
InitializeComponent();
//Create graphics object in panel1
g = panel1.CreateGraphics();
}
private void btnExit2_Click(object sender, EventArgs e)
{
this.Close();
}
Graphics g;
//set a drawing boolean
bool draw = false;
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
draw = true;
if (drawSq)
{
SolidBrush brush = new SolidBrush(Color.FromArgb(128, 255, 0, 0));
if (toolStripTextBox1.Text != "")
{
g.FillRectangle(brush, e.X, e.Y, Convert.ToInt32(toolStripTextBox1.Text), Convert.ToInt32(toolStripTextBox1.Text));
}
else if (toolStripTextBox1.Text == "")
{
MessageBox.Show("Please enter a shape size");
}
draw = false;
drawSq = false;
}
}
and more:
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
draw = false;
mouseX = null;
mouseY = null;
}
//null values allow freehand style drawing
int? mouseX = null;
int? mouseY = null;
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
//creates a pen tool and sets properties by mouse location
if (draw)
{
Pen pen = new Pen(btnColor.ForeColor, float.Parse(txtBox1.Text));
g.DrawLine(pen, new Point(mouseX ?? e.X, mouseY ?? e.Y), new Point(e.X, e.Y));
mouseX = e.X;
mouseY = e.Y;
}
}
Let's try to fix this.
Start by creating your image first:
Bitmap bmp;
protected override void OnLoad(EventArgs e) {
base.OnLoad(e);
bmp = new Bitmap(panel1.ClientSize.Width, panel1.ClientSize.Height);
}
Now when you want to draw on it:
void panel1_MouseMove(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left) {
using (Graphics g = Graphics.FromImage(bmp)) {
g.FillEllipse(Brushes.Red, new Rectangle(e.X - 4, e.Y - 4, 8, 8));
}
panel1.Invalidate();
}
}
And display the results:
void panel1_Paint(object sender, PaintEventArgs e) {
e.Graphics.DrawImage(bmp, Point.Empty);
}
To save, just use your bitmap:
bmp.Save(#"c:\filename.png", ImageFormat.Png);
Use Double buffering with Panel to avoid the flickering.
This will works fine. I tested it and worked well........
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace drawing
{
public partial class Form2 : Form
{
Graphics g;
bool startPaint = false;
int? initX = null;
int? initY = null;
bool drawSquare = false;
bool drawRectangle = false;
bool drawCircle = false;
public Form2()
{
InitializeComponent();
bmp = new Bitmap(panel1.ClientSize.Width, panel1.ClientSize.Height);
}
Bitmap bmp;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
}
void panel1_MouseMove(object sender, MouseEventArgs e)
{
if (startPaint)
{
using ( g = Graphics.FromImage(bmp))
{
// g.FillEllipse(Brushes.Black, new Rectangle(e.X, e.Y , 5, 5));
Pen p = new Pen(btn_PenColor.BackColor, float.Parse(cmb_PenSize.Text));
g.DrawLine(p, new Point(initX ?? e.X, initY ?? e.Y), new Point(e.X, e.Y));
initX = e.X;
initY = e.Y;
//g.DrawImage(bmp, new Rectangle(e.X - 4, e.Y - 4, 8, 8));
}
panel1.Invalidate();
}
}
private void pnl_Draw_MouseDown(object sender, MouseEventArgs e)
{
startPaint = true;
if (drawSquare)
{
//Use Solid Brush for filling the graphic shapes
SolidBrush sb = new SolidBrush(btn_PenColor.BackColor);
//setting the width and height same for creating square.
//Getting the width and Heigt value from Textbox(txt_ShapeSize)
g.FillRectangle(sb, e.X, e.Y, int.Parse(txt_ShapeSize.Text), int.Parse(txt_ShapeSize.Text));
//setting startPaint and drawSquare value to false for creating one graphic on one click.
startPaint = false;
drawSquare = false;
}
if (drawRectangle)
{
SolidBrush sb = new SolidBrush(btn_PenColor.BackColor);
//setting the width twice of the height
g.FillRectangle(sb, e.X, e.Y, 2 * int.Parse(txt_ShapeSize.Text), int.Parse(txt_ShapeSize.Text));
startPaint = false;
drawRectangle = false;
}
if (drawCircle)
{
SolidBrush sb = new SolidBrush(btn_PenColor.BackColor);
g.FillEllipse(sb, e.X, e.Y, int.Parse(txt_ShapeSize.Text), int.Parse(txt_ShapeSize.Text));
startPaint = false;
drawCircle = false;
}
}
private void pnl_Draw_MouseUp(object sender, MouseEventArgs e)
{
startPaint = false;
initX = null;
initY = null;
}
void panel1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawImage(bmp, Point.Empty);
}
private void button1_Click(object sender, EventArgs e)
{
bmp.Save("D://filename.jpg", ImageFormat.Png);
}
}
}
I have a png image that have transparent parts, how to set this png image like background image for my WinForms form and not lose transparency? i Use C#. Thanks!
Here I have written a code for painting the form. You can change the color and transparency according to our requirement. I used colors as background of the form. You can change it as picture as per your requirement. It is a sample code.
First you need to create a static class containing these functions
public enum FormType
{
MDI,
Child
}
public static void PaintFrom(Form frm, PaintEventArgs e, FormType formType)
{
if (formType == FormType.MDI)
{
Graphics mGraphics = e.Graphics;
Pen pen1 = new Pen(Color.FromArgb(96, 155, 173), 1);
Rectangle Area1 = new Rectangle(0, 0, frm.Width - 1, frm.Height - 1);
LinearGradientBrush LGB = new LinearGradientBrush(Area1, Color.FromArgb(96, 155, 173), Color.FromArgb(245, 251, 251), LinearGradientMode.Vertical);
mGraphics.FillRectangle(LGB, Area1);
mGraphics.DrawRectangle(pen1, Area1);
PictureBox picBox = new PictureBox();
Color backColor = Color.Transparent;
Bitmap bm = new Bitmap(ImagePath + "title_bar.png");
//frm.Controls.Add(picBox);
Point pt = new Point(0, 0);
picBox.Location = pt;
picBox.Image = bm;
picBox.Width = frm.Width - 1;
picBox.Height = 24;//frm.Height - 1;
picBox.BackColor = backColor;
picBox.BackgroundImageLayout = ImageLayout.Stretch;
PictureBox closeBox = new PictureBox();
//frm.Controls.Add(closeBox);
bm = new Bitmap(ImagePath + "close.gif");
pt = new Point(frm.Width - (bm.Width), -1);
closeBox.Location = pt;
closeBox.Image = bm;
closeBox.Width = bm.Width + 1;
closeBox.Height = bm.Width + 1;
closeBox.BackColor = backColor;
closeBox.BackgroundImageLayout = ImageLayout.Stretch;
PictureBox minBox = new PictureBox();
//frm.Controls.Add(closeBox);
bm = new Bitmap(ImagePath + "close.gif");
pt = new Point(frm.Width - (2*(bm.Width))-1, bm.Width);
minBox.Location = pt;
minBox.Image = bm;
minBox.Width = bm.Width + 1;
minBox.Height = bm.Width + 1;
minBox.BackColor = backColor;
minBox.BackgroundImageLayout = ImageLayout.Stretch;
frm.Controls.Add(picBox);
picBox.Controls.Add(closeBox);
picBox.Controls.Add(minBox);
minBox.Click+=new EventHandler(minBox_Click);
closeBox.Click += new EventHandler(closeBox_Click);
}
else
{
PaintForm(frm, e);
}
}
public static void PaintForm(Form frm, PaintEventArgs e)
{
Graphics mGraphics = e.Graphics;
Pen pen1 = new Pen(Color.FromArgb(96, 155, 173), 1);
Rectangle Area1 = new Rectangle(0, 0, frm.Width - 1, frm.Height - 1);
LinearGradientBrush LGB = new LinearGradientBrush(Area1, Color.FromArgb(96, 155, 173), Color.FromArgb(245, 251, 251), LinearGradientMode.Vertical);
mGraphics.FillRectangle(LGB, Area1);
mGraphics.DrawRectangle(pen1, Area1);
PictureBox picBox=new PictureBox();
Color backColor = Color.Transparent;
Bitmap bm=new Bitmap(ImagePath+"title_bar.png");
//frm.Controls.Add(picBox);
Point pt=new Point(0,0);
picBox.Location = pt;
picBox.Image = bm;
picBox.Width = frm.Width - 1;
picBox.Height = 24;//frm.Height - 1;
picBox.BackColor = backColor;
picBox.BackgroundImageLayout = ImageLayout.Stretch;
PictureBox closeBox = new PictureBox();
//frm.Controls.Add(closeBox);
bm = new Bitmap(ImagePath + "close.gif");
pt = new Point(frm.Width - (bm.Width), -1);
closeBox.Location = pt;
closeBox.Image = bm;
closeBox.Width = bm.Width + 1;
closeBox.Height = bm.Width + 1;
closeBox.BackColor = backColor;
closeBox.BackgroundImageLayout = ImageLayout.Stretch;
foreach (Control ctr in frm.Controls)
{
if (ctr.HasChildren)
{
if (ctr is DataGridView)
{
DataGridView dtg = ctr as DataGridView;
DataGridViewCellStyle dtstyle=new DataGridViewCellStyle();
dtstyle.BackColor = Color.FromArgb(96, 155, 173);
dtg.ColumnHeadersDefaultCellStyle = dtstyle;
}
else if (ctr is TextBox)
{
}
else if (ctr is TabControl)
{
}
else
{
ctr.BackColor = backColor;
}
}
if (ctr is Label)
{
ctr.BackColor = backColor;
}
}
frm.Controls.Add(picBox);
picBox.Controls.Add(closeBox);
closeBox.Click+=new EventHandler(closeBox_Click);
}
static void closeBox_Click(object sender, EventArgs e)
{
PictureBox close = sender as PictureBox;
PictureBox pic = close.Parent as PictureBox;
Form fm = pic.Parent as Form;
fm.Close();
}
static void minBox_Click(object sender, EventArgs e)
{
PictureBox min = sender as PictureBox;
PictureBox pic = min.Parent as PictureBox;
Form fm = pic.Parent as Form;
fm.WindowState = FormWindowState.Minimized;
}
Then you need to call a Paint Event for the form and in this event you can paint the form like this
private void frmComplaints_Paint(object sender, PaintEventArgs e)
{
UI.Common.PaintForm(this, e);
}
I have used a static class UI.Common for this function and i used an image for titlebar. In your case you can use a png image for background. The ImagePath in the code is a constant variable where you can set the path for directory where the image is saved
I want to crop an image in c#. As in most photo editing software I want to use the rectangle box which can be resized and repositioned via a mouse. In addition, I would like to know how to highlight the cropped area, as show in this photo.
Your image link is no longer available.
So assuming that in a panel you have your picturebox with the image to crop.
First you need to create event handlers for mouse actions to be able to draw a rectangular region which you wish to crop :
private void picBox_MouseDown(object sender, MouseEventArgs e)
{
Cursor = Cursors.Default;
if (Makeselection)
{
try
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
Cursor = Cursors.Cross;
cropX = e.X;
cropY = e.Y;
cropPen = new Pen(Color.Crimson, 1);
cropPen.DashStyle = DashStyle.Solid;
}
picBox.Refresh();
}
catch (Exception ex)
{
}
}
}
private void picBox_MouseUp(object sender, MouseEventArgs e)
{
if (Makeselection)
{
Cursor = Cursors.Default;
}
}
private void picBox_MouseMove(object sender, MouseEventArgs e)
{
Cursor = Cursors.Default;
if (Makeselection)
{
picBox.Cursor = Cursors.Cross;
try
{
if (picBox.Image == null)
return;
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
picBox.Refresh();
cropWidth = e.X - cropX;
cropHeight = e.Y - cropY;
picBox.CreateGraphics().DrawRectangle(cropPen, cropX, cropY, cropWidth, cropHeight);
}
}
catch (Exception ex)
{
}
}
}
private void picBox_MouseLeave(object sender, EventArgs e)
{
tabControl.Focus();
}
private void picBox_MouseEnter(object sender, EventArgs e)
{
picBox.Focus();
}
Now, comes the button click function for cropping the image :
private void btnCrop_Click_1(object sender, EventArgs e)
{
Cursor = Cursors.Default;
try
{
if (cropWidth < 1)
{
return;
}
Rectangle rect = new Rectangle(cropX, cropY, cropWidth, cropHeight);
//First we define a rectangle with the help of already calculated points
Bitmap OriginalImage = new Bitmap(picBoxScreenshot.Image, picBoxScreenshot.Width, picBoxScreenshot.Height);
//Original image
Bitmap _img = new Bitmap(cropWidth, cropHeight);
// for cropinfo image
Graphics g = Graphics.FromImage(_img);
// create graphics
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
//set image attributes
g.DrawImage(OriginalImage, 0, 0, rect, GraphicsUnit.Pixel);
picBox.Image = _img;
picBox.Width = _img.Width;
picBox.Height = _img.Height;
PictureBoxLocation();
cropWidth = 0;
}
catch (Exception ex){}
}
private void PictureBoxLocation()
{
int _x = 0;
int _y = 0;
if (panel1.Width > picBox.Width)
{
_x = (panel1.Width - picBox.Width) / 2;
}
if (panel1.Height > picBox.Height)
{
_y = (panel1.Height - picBox.Height) / 2;
}
picBox.Location = new Point(_x, _y);
picBox.Refresh();
}
In order to draw a picture lighter or darker (or alter the colors in any way) you use a ColorMatrix, like this.
The outside of the selection box seems to have a black image laid over it with a alpha of about 30%. To do this you would just take each pixel outside of the content area and draw a black pixel with a 30% alpha on top of it. This would give the desired dimmed out effect.
As for how you can get a rectangle to be dynamically seizable in C#.