I have a picturebox (pictureBox1), and it gets lines drawn on it, from the paint event. I was wondering how to convert that drawing (with the lines) to a bitmap, and save it as a file. I've tried:
Bitmap bmp = new Bitmap(pictureBox1.Width, pictureBox.Height);
pictureBox1.DrawToBitmap(bmp, pictureBox1.Bounds);
bmp.Save("MyImage.bmp");
But that is a blank image, without the lines. Does anyone know how I can save it with the lines? Thank you.
int bitmapX = 100
int bitmapY = 100
Bitmap imgToSave = new Bitmap(bitmapX, bitmapY);
Graphics gfx = Graphics.FromImage(imgToSave);
// draw on the image with
gfx.DrawLine() // or whatever you want to draw
// save the screenshot
string saveFilePath = Application.StartupPath + "\<name of the image>.png";
imgToSave.Save(saveFilePath, ImageFormat.Png);
This is a code snippet that works for me.
Don't use the PictureBox.Bounds property but instead use a simple Rectangle object/structure filled with the `PictureBox' width and height like this:
var bitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
pictureBox1.DrawToBitmap(bitmap, new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height));
bitmap.Save("c:\\temp\\image.bmp");
Using the Bounds property you are fetching the correct size of the picture box control, but depending on the position not the 0,0 coordinate, but the control position, which leads to an empty bitmap.
Related
I have a Rectangle (rec) that contains the area in which a smaller image is contained within a larger image. I want to display this smaller image on a Picturebox. However, what I really am doing is using the smaller image as a picture detector for a larger image that is 333x324. So what I want to do is use the coordinates of the smaller image rectangle, and then draw to the Picturebox, starting from lefthand side of the rectangle, going outwards by 333 width and 324 height.
Currently my code works but it only displays the small image that was being used for detection purposes. I want it to display the smaller image + 300 width and + 300 height.
I fiddled with this code for hours and I must be doing something extremely basic wrong. If anyone can help me I would appreciate it so much!
My code for the class:
public static class Worker
{
public static void doWork(object myForm)
{
//infinitely search for maps
for (;;)
{
//match type signature for Threading
var myForm1 = (Form1)myForm;
//capture screen
Bitmap currentBitmap = new Bitmap(CaptureScreen.capture());
//detect map
Detector detector = new Detector();
Rectangle rec = detector.searchBitmap(currentBitmap, 0.1);
//if it actually found something
if(rec.Width != 0)
{
// Create the new bitmap and associated graphics object
Bitmap bmp = new Bitmap(rec.X, rec.Y);
Graphics g = Graphics.FromImage(bmp);
// Draw the specified section of the source bitmap to the new one
g.DrawImage(currentBitmap, 0,0, rec, GraphicsUnit.Pixel);
// send to the picture box &refresh;
myForm1.Invoke(new Action(() =>
{
myForm1.getPicturebox().Image = bmp;
myForm1.getPicturebox().Refresh();
myForm1.Update();
}));
// Clean up
g.Dispose();
bmp.Dispose();
}
//kill
currentBitmap.Dispose();
//do 10 times per second
System.Threading.Thread.Sleep(100);
}
}
}
If I understand correctly, the rec variable contains a rectangle with correct X and Y which identifies a rectangle with Width=333 and Height=324.
So inside the if statement, start by setting the desired size:
rec.Width = 333;
rec.Height = 324;
Then, note that the Bitmap constructor expects the width and height, so change
Bitmap bmp = new Bitmap(rec.X, rec.Y);
to
Bitmap bmp = new Bitmap(rec.Width, rec.Height);
and that's it - the rest of the code can stay the way it is now.
I have an image that contains some letters. Each of the letters has been placed in a Rectangle object.
The rectangles are of different sizes, but i want to save each of them to a new image which has the same size. In this case 260x260.
Here is my approach:
foreach(Rectangle letter in letters)
{
Bitmap letterBitmap = img2.Clone(letter, img2.PixelFormat);
Image newImage = (Image) letterBitmap;
Bitmap newLetterBitmap = new Bitmap(newImage, new Size(260, 260));
}
The Problem is that the size of the rectangle gets changed, so it fits the new size of the Bitmap. I just want the new image to have a black background and be bigger than the original rectangle.
Try something like this:
Bitmap newLetterBitmap = new Bitmap(260, 260);
Graphics g = Graphics.FromImage(newLetterBitmap);
g.DrawImageUnscaled(newImage, 0, 0);
I have seen, that the drawing of two images is time consuming, so I want to reduce drawing these images as much as possible. I use pictureedit and have overriden the ondraw event.
Here I added the below part, but it ends up uin a black image. I do want to check, whether I need to draw at all. This check works. Then I draw the background and overlay it by another one and I want to store this as image and put it as background for my control.
If I do not redraw the background I just call:
g.Clear(Color.Transparent);
in my pictureEdit paint event.
Did I something wrong?
Best Regards,
Patrick
//Recalculate the background
if (redrawBackground)
{
g.FillRectangle(Brushes.White, 0, 0, backGroundImage.Width, backGroundImage.Height);
g.Clear(Color.White);
//this is drawn without aspect ration. The matrix is stored, since drawing images is expensive
GenerateTransformation(g, false);
g.DrawImageUnscaled(backGroundImage, new Rectangle(0, 0, backGroundImage.Width, backGroundImage.Height));
lastTransformation = g.Transform;
GenerateTransformation(g, true);
g.DrawImage(foreGroundImage, new Rectangle(0, 0, backGroundImage.Width, backGroundImage.Height));
lastTransformationAspect = g.Transform;
//Save bitmap as background
Bitmap bmp = new Bitmap(backGroundImage.Width, backGroundImage.Height, e.Graphics);
//Trick the background by a new image
pictureEdit.Image = bmp;
}
Your code (new Bitmap(backGroundImage.Width, backGroundImage.Height, e.Graphics);
) does not copy the image to the Bitmap; it only associates the Graphics object with the bitmap.
Try this:
Bitmap bmp = new Bitmap(width, height);
Graphics g = Graphics.FromImage(bmp);
g.DrawSomething(); // This draws to the bitmap
I have written a small application which will be used in my work environment for cropping images. The windows form (.NET 3.5) that contains the image has a transparent rectangle which I use for dragging over a section of an image and hitting a button to get me whatever was behind the rectangle.
Currently I am using the code below, this is causing me issues because the area that it is capturing is off by quite a few pixels, and I think it's something to do with my CopyFromScreen function.
//Pass in a rectangle
private void SnapshotImage(Rectangle rect)
{
Point ptPosition = new Point(rect.X, rect.Y);
Point ptRelativePosition;
//Get me the screen coordinates, so that I get the correct area
ptRelativePosition = PointToScreen(ptPosition);
//Create a new bitmap
Bitmap bmp = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb);
//Sort out getting the image
Graphics g = Graphics.FromImage(bmp);
//Copy the image from screen
g.CopyFromScreen(this.Location.X + ptPosition.X, this.Location.Y + ptPosition.Y, 0, 0, bmp.Size, CopyPixelOperation.SourceCopy);
//Change the image to be the selected image area
imageControl1.Image.ChangeImage(bmp);
}
If anyone can spot why when the image is redrawn its quite a bit out, I'd be eternally grateful at this point. Also, the ChangeImage function is fine - it works if I use a form as a select area but using a rectangle has jazzed things up a bit.
You've retrieved the relative position to the screen as ptRelativePosition, but you never actually use that - you add the rectangle's location to your form's location, which doesn't account for the form's border.
Here's that fixed, with a few optimizations:
// Pass in a rectangle
private void SnapshotImage(Rectangle rect)
{
// Get me the screen coordinates, so that I get the correct area
Point relativePosition = this.PointToScreen(rect.Location);
// Create a new bitmap
Bitmap bmp = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb);
// Copy the image from screen
using(Graphics g = Graphics.FromImage(bmp)) {
g.CopyFromScreen(relativePosition, Point.Empty, bmp.Size);
}
// Change the image to be the selected image area
imageControl1.Image.ChangeImage(bmp);
}
Interestingly, this was because of the space between the main form and the control that the image was on and the toolbar at the top of the form separating the control and the top of the main form. To get around this I simply modified one line in capture screen to account for those pixels, as shown below:
g.CopyFromScreen(relativePosition.X + 2, relativePosition.Y+48, Point.Empty.X, Point.Empty.Y, bmp.Size);
Cheers
I'm trying to build a treeview like file list in a richtext box.
It should look like an explorer treeview. My code is able to get an resize the icon, but the transparency is missing (light gray background instead of transparency). What do I need to change here? Is the Image format wrong?
Is there a better way to add an image to a richtextbox?
// Get file info
FileInfo f = new FileInfo("myfile.name");
// Get icon for fileinfo
Icon ico = Icon.ExtractAssociatedIcon(f);
// Convert icon to bitmap
Bitmap bm = ico.ToBitmap();
// create new image with desired size
Bitmap img = new Bitmap(16,16,PixelFormat.Frmat32bpRgb);
// Create graphics with desired sized image
Graphics g = Graphics.FormImage(img);
// set interpolation mode
g.InterpolationMode = InterpolationMode.HighQualityBiCubic;
// draw/resize image
g.DrawImage(bm, new Rectangle(0,0,16,16), new Rectangle(0, 0, bm.Width, bm,Height), GraphicalUnit.Pixel);
// Paste to clipboard
Clipboard.SetImage(bm);
// Paste in RichtextBox
rtb.Paste();
Example:
Edit:
I've figured out that the image is transparent, but using Clipboard.SetImage() doesn't publish it as transparent image.
Any ideas why and what can I do to fix it? Do I need to switch to a differn textbox control?
I've had some luck going through Graphics.
Bitmap b = new Bitmap(pbAssetLoaded.Width, pbAssetLoaded.Height);
using (Graphics g = Graphics.FromImage(b))
{
g.DrawIcon(SystemIcons.Information, 0, 0);
}
This draws the icon with transparency to the Bitmap.
Try
img.MakeTransparent();
after you contruct it.
Note that this will change your PixelFormat to Format32bppArgb.