How can I transfer the values of my graphics to a bitmap so I can save it as jpg or bmp file.
here's my code:
private void pictureBox1_Paint_1(object sender, PaintEventArgs e)
{
using(var p = new Pen(Color.Blue, 4)){
for (int i = 0; i < _listPS.Count; i++)
{
e.Graphics.DrawLine(_pen, _listPS[i], _listPE[i]);
}
}
}
suppose that _listPS and _listPE have values.
ah! Solved it LOL! :)
Here's my solution:
private Bitmap _mybitmap;
private void pictureBox1_Paint_1(object sender, PaintEventArgs e)
{
_mybitmap = new Bitmap(pictureBox1.Width, pictureBox1.Heigth);
Graphics _tempg = Graphics.FromImage(_mybitmap);
using(var p = new Pen(Color.Blue, 4){
for (int i = 0; i < _listPS.Count; i++)
{
e.Graphics.DrawLine(_pen, _listPS[i], _listPE[i]);
_tempg.DrawLine(_pen, _listPS[i], _listPE[i]);
}
_tempg.Dispose();
}
}
Try this one
Bitmap _image = new Bitmap(100, 100);
Graphics _g = Graphics.FromImage(_image);
//Graphics _g = pictureBox1.CreateGraphics();
Pen _pen = new Pen(Color.Red, 3);
Point myPoint1 = new Point(10, 20);
Point myPoint2 = new Point(30, 40);
for (int i = 0; i < _listPS.Count; i++)
{
_g.DrawLine(_pen, _listPS[i], _listPE[i]);
}
_image.Save(#"D:\test.bmp");
_image.Dispose();
_g.Dispose();
Related
my code for crate rectangle :
Rectangle[] myRectangle = new Rectangle[100];
for(int i=1;i<=100;i++)
{
myRectangle[i] = new Rectangle();
// another code for create myRectangle[i]
}
When MouseEnter Rectangle[X] and I want to do something.What will i do?
Thank you.
Putting this here;
Rectangle[] myRectangle = new Rectangle[100];
for(int i = 0; i < 100; i++)
{
myRectangle[i] = new Rectangle();
myRectangle[i].Tag = i;
myRectangle[i].MouseEnter += MouseEnter;
}
private void MouseEnter(object sender, MouseEventArgs e)
{
Rectangle rect = (Rectangle)sender;
int idx = (int)rect.Tag;
MessageBox.Show(idx.ToString());
}
I am attempting to capture a full-page screenshot of any website a user is viewing using the WebBrowser component.
At present, I am able to only able to capture what a user is viewing from within the WebBrowser. However, the screenshot image created is the size of the webpage. For example, below is a (half-sized) screenshot of the BBC website, the black area is actually saved transparent but I've filled it black for visibility.
I have seen solutions where a new WebBrowser instance is used to fetch a fullpage snapshot. However, I need the screenshot to be exactly of the page as the user is viewing it at the time, much like how the full-page screenshot works in Firefox.
My code below that generated the above image:
private void button1_Click(object sender, EventArgs e)
{
while (webBrowser1.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
int scrollWidth = 0;
int scrollHeight = 0;
scrollHeight = webBrowser1.Document.Body.ScrollRectangle.Height;
scrollWidth = webBrowser1.Document.Body.ScrollRectangle.Width;
webBrowser1.Size = new Size(scrollWidth, scrollHeight);
Bitmap bm = new Bitmap(scrollWidth, scrollHeight);
webBrowser1.DrawToBitmap(bm, new Rectangle(0, 0, bm.Width, bm.Height));
bm.Save(#"D:\Screenshots\test.png", ImageFormat.Png);
}
I've got a good working one..
private void button1_Click(object sender, EventArgs e)
{
using (FileDialog fd = new SaveFileDialog())
{
fd.Filter = "Image (*.png)|*.png";
if (fd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
new WebPageSnap(webBrowser1.Url.ToString(), fd.FileName);
//might take 3 or 4 seconds to save cauz it has to load again.
}
}
}
class WebPageSnap
{
WebBrowser wb;
string outFile;
public WebPageSnap(string url, string outputFile)
{
wb = new WebBrowser();
wb.ProgressChanged += wb_ProgressChanged;
outFile = outputFile;
wb.ScriptErrorsSuppressed = true;
wb.ScrollBarsEnabled = false;
wb.Navigate(url);
}
void wb_ProgressChanged(object sender, WebBrowserProgressChangedEventArgs e)
{
if (e.CurrentProgress == e.MaximumProgress)
{
wb.ProgressChanged -= wb_ProgressChanged;
try
{
int scrollWidth = 0;
int scrollHeight = 0;
scrollHeight = wb.Document.Body.ScrollRectangle.Height;
scrollWidth = wb.Document.Body.ScrollRectangle.Width;
wb.Size = new Size(scrollWidth, scrollHeight);
Bitmap bitmap = new Bitmap(wb.Width, wb.Height);
for (int Xcount = 0; Xcount < bitmap.Width; Xcount++)
for (int Ycount = 0; Ycount < bitmap.Height; Ycount++)
bitmap.SetPixel(Xcount, Ycount, Color.Black);
wb.DrawToBitmap(bitmap, new Rectangle(0, 0, wb.Width, wb.Height));
bitmap.Save(outFile, ImageFormat.Png);
}
catch { }
}
}
}
.
;Here's the result
.
I've created a custom control in C#. A highly-simplified version of it is shown below:
class WellControl : Control
{
Pen circlePen = new Pen(Color.Black, 5);
Brush wellShader = new SolidBrush(Color.BlueViolet);
Brush wellBlanker = new SolidBrush(Color.LightGray);
public WellControl(int wellNum)
{
InitializeComponent();
}
private void DrawWell()
{
using (Graphics well = this.CreateGraphics())
{
this.Size = new Size(WellSize, WellSize);
if (this.selected)
{
well.FillEllipse(wellShader, ellipseCoords);
}
else
{
well.FillEllipse(wellBlanker, ellipseCoords);
}
well.DrawEllipse(circlePen, ellipseCoords);
using (Font wellNumberFont = new Font("Arial", 14, FontStyle.Bold))
{
well.DrawString(WellNum.ToString(), wellNumberFont, Brushes.Black, new Point(13, 13));
}
}
}
private void WellPaintEventHandler(object sender, EventArgs e)
{
DrawWell();
}
private void InitializeComponent()
{
this.SuspendLayout();
this.Paint += new System.Windows.Forms.PaintEventHandler(WellPaintEventHandler);
this.ResumeLayout();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
//dispose all the custom stuff
}
}
}
When I add it to a form, it renders properly (again, simplified example):
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
for (int i = 0; i < 4; i++)
{
WellControl newWell = new WellControl(i + 1);
newWell.Location = new Point(15, 50 * i);
newWell.Size = new System.Drawing.Size(45, 45);
this.Controls.Add(newWell);
}
}
}
I have another custom control, "Plate", which is intended to hold many "Wells". The code intended to draw the wells evenly across the plate probably sucks right now but I'm just trying to see something:
class PlateControl : Control
{
Pen blackPen = new Pen(Color.Black, 3);
public PlateControl()
{
this.Size = new Size(600, 800);
List<WellControl> plateWells = new List<WellControl>();
int column = 1;
int row = 0;
for (int i = 1; i <= 96; i++)
{
column = Convert.ToInt32(Math.Ceiling(Convert.ToDecimal(i / 8)));
row = i % 8;
WellControl newWell = new WellControl(i + 1);
newWell.Name = "wellControl" + i;
newWell.Location = new Point(column * 50, row * 50);
newWell.Size = new System.Drawing.Size(45, 45);
newWell.TabIndex = i;
newWell.WellSize = 45;
plateWells.Add(newWell);
newWell.Visible = true;
}
InitializeComponent();
}
private void InitializeComponent()
{
this.SuspendLayout();
this.Paint += new System.Windows.Forms.PaintEventHandler(PlatePaintEventHandler);
this.ResumeLayout();
}
private void DrawPlate()
{
using (Graphics plate = this.CreateGraphics())
{
Point topLeft = new Point(0, 0);
Point topRight = new Point(600, 0);
Point bottomRight = new Point(600, 400);
Point bottomLeft = new Point(0, 400);
plate.DrawLine(blackPen, topLeft, topRight);
plate.DrawLine(blackPen, topRight, bottomRight);
plate.DrawLine(blackPen, bottomRight, bottomLeft);
plate.DrawLine(blackPen, bottomLeft, topLeft);
}
}
private void PlatePaintEventHandler(object sender, EventArgs e)
{
DrawPlate();
}
}
If I add this control to a Winform using this.Controls.Add(new PlateControl()), the rectangle renders, but not the WellControls I added to the PlateControl in the constructor loop. What am I doing incorrectly?
You need to add List of WallControl to plate control.
public PlateControl()
{
this.Size = new Size(600, 800);
List<WellControl> plateWells = new List<WellControl>();
int column = 1;
int row = 0;
for (int i = 1; i <= 96; i++)
{
column = Convert.ToInt32(Math.Ceiling(Convert.ToDecimal(i / 8)));
row = i % 8;
WellControl newWell = new WellControl(i + 1);
newWell.Name = "wellControl" + i;
newWell.Location = new Point(column * 50, row * 50);
newWell.Size = new System.Drawing.Size(45, 45);
newWell.TabIndex = i;
newWell.WellSize = 45;
plateWells.Add(newWell);
newWell.Visible = true;
}
this.Controls.AddRange(plateWells.ToArray());
InitializeComponent();
}
If I put PictureBox initialization into form's constructor or form.Load / form.Shown handler nothing is drawn on PictureBox. If initialization is being made just before drawing, graphics appears.
Why this code draws an array on PictureBox:
public partial class Form1 : Form
{
Bitmap drawArea;
public Form1()
{
InitializeComponent();
}
private void drawArray(int[] arr, PictureBox box)
{
//=========== Attention to this code ================
drawArea = new Bitmap(pictureBox1.Size.Width, pictureBox1.Size.Height);
pictureBox1.Image = drawArea;
//===================================================
using (Graphics g = Graphics.FromImage(drawArea))
{
Pen mypen = new Pen(Brushes.Black);
g.Clear(Color.White);
for (int i = 0; i < arr.Length; i++)
g.DrawLine(mypen, i*2, drawArea.Height,
i*2, drawArea.Height - arr[i]);
}
}
private void button1_Click(object sender, EventArgs e)
{
int[] ar1 = randomArray(20, 1, 20);
drawArray(ar1, pictureBox1);
}
}
but this code doesn't?
public partial class Form1 : Form
{
Bitmap drawArea;
public Form1()
{
InitializeComponent();
//=========== Attention to this code ================
//Breakpoint here: pictureBox1.Size.Width==409, pictureBox1.Size.Height==205
drawArea = new Bitmap(pictureBox1.Size.Width, pictureBox1.Size.Height);
pictureBox1.Image = drawArea;
//===================================================
}
private void drawArray(int[] arr, PictureBox box)
{
using (Graphics g = Graphics.FromImage(drawArea))
{
Pen mypen = new Pen(Brushes.Black);
g.Clear(Color.White);
for (int i = 0; i < arr.Length; i++)
g.DrawLine(mypen, i*2, drawArea.Height,
i*2, drawArea.Height - arr[i]);
}
}
private void button1_Click(object sender, EventArgs e)
{
int[] ar1 = randomArray(20, 1, 20);
drawArray(ar1, pictureBox1);
}
}
It does not even work if I make a second button and put the initialization code in its handler (and of course click second button before clicking the first).
No exception is thrown.
Not sure...just Invalidate() the PictureBox in drawArray() so it refreshes itself:
private void drawArray(int[] arr, PictureBox box)
{
using (Graphics g = Graphics.FromImage(drawArea))
{
Pen mypen = new Pen(Brushes.Black);
g.Clear(Color.White);
for (int i = 0; i < arr.Length; i++)
g.DrawLine(mypen, i * 2, drawArea.Height,
i * 2, drawArea.Height - arr[i]);
}
box.Invalidate();
}
*Why were you passing the PictureBox anyways, if you weren't using it?
I am doing OCR application. I have this error when I run the system which the system will save the picturebox3.image into a folder.
//When user is selecting, RegionSelect = true
private bool RegionSelect = false;
private int x0, x1, y0, y1;
private Bitmap bmpImage;
private void loadImageBT_Click(object sender, EventArgs e)
{
try
{
OpenFileDialog open = new OpenFileDialog();
open.InitialDirectory = #"C:\Users\Shen\Desktop";
open.Filter = "Image Files(*.jpg; *.jpeg)|*.jpg; *.jpeg";
if (open.ShowDialog() == DialogResult.OK)
{
singleFileInfo = new FileInfo(open.FileName);
string dirName = System.IO.Path.GetDirectoryName(open.FileName);
loadTB.Text = open.FileName;
pictureBox1.Image = new Bitmap(open.FileName);
bmpImage = new Bitmap(pictureBox1.Image);
}
}
catch (Exception)
{
throw new ApplicationException("Failed loading image");
}
}
//User image selection Start Point
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
RegionSelect = true;
//Save the start point.
x0 = e.X;
y0 = e.Y;
}
//User select image progress
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
//Do nothing it we're not selecting an area.
if (!RegionSelect) return;
//Save the new point.
x1 = e.X;
y1 = e.Y;
//Make a Bitmap to display the selection rectangle.
Bitmap bm = new Bitmap(bmpImage);
//Draw the rectangle in the image.
using (Graphics g = Graphics.FromImage(bm))
{
g.DrawRectangle(Pens.Red, Math.Min(x0, x1), Math.Min(y0, y1), Math.Abs(x1 - x0), Math.Abs(y1 - y0));
}
//Temporary display the image.
pictureBox1.Image = bm;
}
//Image Selection End Point
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
// Do nothing it we're not selecting an area.
if (!RegionSelect) return;
RegionSelect = false;
//Display the original image.
pictureBox1.Image = bmpImage;
// Copy the selected part of the image.
int wid = Math.Abs(x0 - x1);
int hgt = Math.Abs(y0 - y1);
if ((wid < 1) || (hgt < 1)) return;
Bitmap area = new Bitmap(wid, hgt);
using (Graphics g = Graphics.FromImage(area))
{
Rectangle source_rectangle = new Rectangle(Math.Min(x0, x1), Math.Min(y0, y1), wid, hgt);
Rectangle dest_rectangle = new Rectangle(0, 0, wid, hgt);
g.DrawImage(bmpImage, dest_rectangle, source_rectangle, GraphicsUnit.Pixel);
}
// Display the result.
pictureBox3.Image = area;
** ERROR occuer here!!!!!**
area.Save(#"C:\Users\Shen\Desktop\LenzOCR\TempFolder\tempPic.jpg"); // error line occcur
singleFileInfo = new FileInfo("C:\\Users\\Shen\\Desktop\\LenzOCR\\TempFolder\\tempPic.jpg");
}
private void ScanBT_Click(object sender, EventArgs e)
{
var folder = #"C:\Users\Shen\Desktop\LenzOCR\LenzOCR\WindowsFormsApplication1\ImageFile";
DirectoryInfo directoryInfo;
FileInfo[] files;
directoryInfo = new DirectoryInfo(folder);
files = directoryInfo.GetFiles("*.jpg", SearchOption.AllDirectories);
var processImagesDelegate = new ProcessImagesDelegate(ProcessImages2);
processImagesDelegate.BeginInvoke(files, null, null);
//BackgroundWorker bw = new BackgroundWorker();
//bw.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
//bw.RunWorkerAsync(bw);
//bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
}
private void ProcessImages2(FileInfo[] files)
{
var comparableImages = new List<ComparableImage>();
var index = 0x0;
foreach (var file in files)
{
if (exit)
{
return;
}
var comparableImage = new ComparableImage(file);
comparableImages.Add(comparableImage);
index++;
}
index = 0;
similarityImagesSorted = new List<SimilarityImages>();
var fileImage = new ComparableImage(singleFileInfo);
for (var i = 0; i < comparableImages.Count; i++)
{
if (exit)
return;
var destination = comparableImages[i];
var similarity = fileImage.CalculateSimilarity(destination);
var sim = new SimilarityImages(fileImage, destination, similarity);
similarityImagesSorted.Add(sim);
index++;
}
similarityImagesSorted.Sort();
similarityImagesSorted.Reverse();
similarityImages = new BindingList<SimilarityImages>(similarityImagesSorted);
var buttons =
new List<Button>
{
ScanBT
};
if (similarityImages[0].Similarity > 70)
{
con = new System.Data.SqlClient.SqlConnection();
con.ConnectionString = "Data Source=SHEN-PC\\SQLEXPRESS;Initial Catalog=CharacterImage;Integrated Security=True";
con.Open();
String getFile = "SELECT ImageName, Character FROM CharacterImage WHERE ImageName='" + similarityImages[0].Destination.ToString() + "'";
SqlCommand cmd2 = new SqlCommand(getFile, con);
SqlDataReader rd2 = cmd2.ExecuteReader();
while (rd2.Read())
{
for (int i = 0; i < 1; i++)
{
string getText = rd2["Character"].ToString();
Action showText = () => ocrTB.AppendText(getText);
ocrTB.Invoke(showText);
}
}
con.Close();
}
else
{
MessageBox.Show("No character found!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
#endregion
Since it has been a while, I'm hoping you found your answer, but I'm going to guess that you needed to set the file format when you're saving a jpeg:
area.Save(#"C:\Users\Shen\Desktop\LenzOCR\TempFolder\tempPic.jpg",System.Drawing.Imaging.ImageFormat.Jpeg);
Past that, I can't remember if the picturebox control is double buffered or not which could be the problem (if it's not, you might not be able to access it for saving purposes while it is being rendered, but if you make a copy of area before setting the picturebox3.Image property that would fix that issue):
Bitmap SavingObject=new Bitmap(area);
picturebox3.Image=area;
SavingObject.Save(#"C:\Users\Shen\Desktop\LenzOCR\TempFolder\tempPic.jpg",System.Drawing.Imaging.ImageFormat.Jpeg);
Anyway, I hope you ended up finding your solution (considering it's been a couple months since this was posted).
This looks like a copy of this question:
c# A generic error occurred in GDI+
Same code, same error, same author.
Can't see any difference. But maybe I'm missing something.