I'm trying to draw a few objects to a windows form, then create a image of that form and save it to a folder.
This is a two part question... Why isn't the image that is being drawn to the windows form showing up on the created image? Also second question is, how can I create an image of the windows form drawing, from say point 0,0 to point 500,500 without a background....
Here is the code I have at the moment....
Form draw = new Drawing(); // Opens the drawing form
draw.Show();
try
{
//Try to draw something...
System.Drawing.Pen myPen;
myPen = new System.Drawing.Pen(System.Drawing.Color.Red);
System.Drawing.Graphics formGraphics = draw.CreateGraphics();
formGraphics.DrawLine(myPen, 0, 0, 500, 500);
myPen.Dispose();
formGraphics.Dispose();
var path = this.outputFolder.Text; // Create variable with output path
if (!Directory.Exists(path))
{
DirectoryInfo di = Directory.CreateDirectory(path); // Create path if it doesn't exist
}
using (var bitmap = new Bitmap(draw.Width, draw.Height)) // Creating the .bmp file from windows form
{
draw.DrawToBitmap(bitmap, new Rectangle(0, 0, bitmap.Width, bitmap.Height));
bitmap.Save(path + "\\" + i + ".bmp");
}
}
catch { }
Can you see anything wrong here? What seems to be prohibiting the drawings to be saved to a .bmp file?
Thank in advance!
I ended up using the example shown here Saving System.Drawing.Graphics to a png or bmp
Form draw = new Drawing(); // Opens the drawing form
draw.Show();
try
{
var path = this.outputFolder.Text; // Path where images will be saved to
if (!Directory.Exists(path))
{
DirectoryInfo di = Directory.CreateDirectory(path); // Create a directory if it does not already exist
}
Bitmap bitmap = new Bitmap(Convert.ToInt32(1024), Convert.ToInt32(1024), System.Drawing.Imaging.PixelFormat.Format32bppArgb);
Graphics g = Graphics.FromImage(bitmap);
System.Drawing.Pen myPen;
myPen = new System.Drawing.Pen(System.Drawing.Color.Red);
g.DrawLine(myPen, 0, 0, 1024, 1024);
bitmap.Save(path + "\\" + i + ".png", ImageFormat.Png);
}
catch { }
And that has worked flawlessly for me now :D
Related
I am currently working on my first WPF project to make cards for a card game and save them into a folder as a PNG. Right now I am using the method explained in this other answer I found. Here is the code I'm using:
private void saveCard()
{
Rect bounds = VisualTreeHelper.GetDescendantBounds(cardArea);
double dpi = 96d;
RenderTargetBitmap rtb = new RenderTargetBitmap((int)bounds.Width, (int)bounds.Height, dpi, dpi, System.Windows.Media.PixelFormats.Default);
DrawingVisual dv = new DrawingVisual();
using (DrawingContext dc = dv.RenderOpen())
{
VisualBrush vb = new VisualBrush(cardArea);
dc.DrawRectangle(vb, null, new Rect(new Point(), bounds.Size));
}
rtb.Render(dv);
BitmapEncoder pngEncoder = new PngBitmapEncoder();
pngEncoder.Frames.Add(BitmapFrame.Create(rtb));
try
{
System.IO.MemoryStream ms = new System.IO.MemoryStream();
pngEncoder.Save(ms);
ms.Close();
System.IO.File.WriteAllBytes(System.AppDomain.CurrentDomain.BaseDirectory + "/Heroes/" + HeroName.Content + ".png", ms.ToArray());
}
catch (Exception err)
{
MessageBox.Show(err.ToString(), "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
It works fine, but I noticed that the saved pictures look "pixelated". This is especially noticeable when compared to the one in the canvas, or even a screenshot.
Here is an example.
I checked the resolution of both and they had the same dimensions. What am I doing wrong? Is there anything I can do to fix it? Should I save the picture under another file type?
Please let me know.
I have a datagridview with an image column on my form and I set its value to an image in some folder ..
Bitmap PicImage;
PicImage = new Bitmap(ImagePath);
Grid.Rows[i].Cells["ImageColumn"].Value = PicImage;
when I want to delete the row ,the image should be deleted too, but I get "the process cannot access the file..." message :
File.delete(ImagePath);
How can I solve it?
Use a file stream to unlock the file , so instead of:
PicImage = new Bitmap(ImagePath);
use:
using (var stream= new System.IO.FileStream(ImagePath, System.IO.FileMode.Open))
{
var bmp= new Bitmap(stream);
PicImage = (Bitmap) bmp.Clone();
}
Try first to unload the image from the Bitmap and then delete it.
The cleanest method is to load it without any links to files or streams. If it's just for showing on a UI, the simplest way to do this without deep-cloning using LockBits is simply to paint it on a new 32BPP ARGB image:
Bitmap image;
using (Bitmap tmpImage = new Bitmap(filepath))
{
image = new Bitmap(tmpImage.Width, tmpImage.Height, PixelFormat.Format32bppArgb);
using (Graphics gr = Graphics.FromImage(image))
gr.DrawImage(tmpImage, new Rectangle(0, 0, image.Width, image.Height));
}
// Bitmap "image" is now ready to use.
The following code unlinked the datagridview from the image file.
Bitmap timage;
using (Bitmap tmpImage = new Bitmap(tname))
{
timage = new Bitmap(tmpImage.Width, tmpImage.Height, PixelFormat.Format32bppArgb);
using (Graphics gr = Graphics.FromImage(timage))
gr.DrawImage(tmpImage, new Rectangle(0, 0, timage.Width, timage.Height));
}
fileGridView.Rows[dgIndex].Cells["thumbNail"].Value = timage;
I use this code to re-size images, but my problem is that I have to save the original picture then re-size that! How can I re-size a picture without saving it?
I want to re-size the picture first and then save it.
FileUpload1.SaveAs("saveOriginalFileFirstHere");
string thumbpath = "where resized pic should be saved";
MakeThumbnails.makethumb("saveOriginalFileFirstpath", thumbpath);
public static void makethumb(string savedpath, string thumbpath)
{
int resizeToWidth = 200;
int resizeToHeight = 200;
Graphics graphic;
//Image photo; // your uploaded image
Image photo = new Bitmap(savedpath);
// Image photo = new j
Bitmap bmp = new Bitmap(resizeToWidth, resizeToHeight);
graphic = Graphics.FromImage(bmp);
graphic.InterpolationMode = InterpolationMode.Default;
graphic.SmoothingMode = SmoothingMode.Default;
graphic.PixelOffsetMode = PixelOffsetMode.Default;
graphic.CompositingQuality = CompositingQuality.Default;
graphic.DrawImage(photo, 0, 0, resizeToWidth, resizeToHeight);
bmp.Save(thumbpath);
}
Use the InputStream property of the uploaded file instead:
I have modified your code to do so:
EDIT: You really should dispose of your IDisposables, such as your bitmaps and the stream, to avoid memory leakage. I have updated my code, so it will properly dispose these resources after it's done with them.
string thumbpath = "where resized pic should be saved";
MakeThumbnails.makethumb(FileUpload1.InputStream, thumbpath);
public static void makethumb(Stream stream, string thumbpath)
{
int resizeToWidth = 200;
int resizeToHeight = 200;
using (stream)
using (Image photo = new Bitmap(stream))
using (Bitmap bmp = new Bitmap(resizeToWidth, resizeToHeight))
using (Graphics graphic = Graphics.FromImage(bmp))
{
graphic.InterpolationMode = InterpolationMode.Default;
graphic.SmoothingMode = SmoothingMode.Default;
graphic.PixelOffsetMode = PixelOffsetMode.Default;
graphic.CompositingQuality = CompositingQuality.Default;
graphic.DrawImage(photo, 0, 0, resizeToWidth, resizeToHeight);
bmp.Save(thumbpath);
}
}
This should work the way you want it to, if it doesn't, or if anything is unclear, please let me know.
i am a new to c# programming and i am doing a project that can capture the screen and attach it to a pdf,in my project i need to attach an screenshot of my desktop or application directly to PDF file, i know how to attached a image that has been saved in to the Hard Drive, in this case i used iTextsharp library. what i need to know is there a way to attach the image directly to PDF without saving the image to Hard Drive. till now I can capture my screen and save it to the hard drive. please direct me to a path, Thanx In Advance , code i used is bellow
this is the code i used to capture the screen
string pHotoTime = DateTime.Now.ToString("yyyy-MM-dd, HH mm ss");
Size s = Screen.PrimaryScreen.Bounds.Size;
Bitmap bmp = new Bitmap(s.Width, s.Height);
Graphics g = Graphics.FromImage(bmp);
g.CopyFromScreen(0, 0, 0, 90, s);
System.IO.Stream stream = new System.IO.MemoryStream();
bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
stream.Position = 0;
// later:
//bmp.Save(#"C:\Users\NiyNLK\Documents\TESTs\" + pHotoTime + ".jpg");
bmp.Save(#"C:\Users\NiyNLK\Documents\TESTs\MyImage.jpg");
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox1.Image = bmp;
below code is used to attached the image
enter code here
iTextSharp.text.Rectangle r = new iTextSharp.text.Rectangle(400, 400);
var doc = new Document(r);
string path = #"c:\users\niynlk\documents\tests";
string Imagepath = #"C:\Users\NiyNLK\Documents\TESTs";
try
{
PdfWriter writer = PdfWriter.GetInstance(doc, new FileStream(path + "/Images.pdf", FileMode.Create));
doc.Open();
doc.Add(new Paragraph("Image"));
Image img = Image.GetInstance(Imagepath + "/MyImage.jpg");
img.ScalePercent(25f);
doc.Add(img);
}
catch (Exception)
{
throw;
}
finally
{
doc.Close();
}
protected void btnCropIt_Click(object s, EventArgs e)
{
System.Drawing.Image img = System.Drawing.Image.FromFile(Server.MapPath("../upload/" + u.Avatar));
var m = cropImage(img, new Rectangle(0, 0, 50, 50));
System.IO.File.Delete(Server.MapPath("../upload/" + u.Avatar));
m.Save(Server.MapPath("../upload/" + u.Avatar));
}
private static System.Drawing.Image cropImage(System.Drawing.Image img, Rectangle cropArea)
{
Bitmap bmpImage = new Bitmap(img);
Bitmap bmpCrop = bmpImage.Clone(cropArea, bmpImage.PixelFormat);
return (System.Drawing.Image)(bmpCrop);
}
System.IO.File.Delete(Server.MapPath("../upload/" + u.Avatar));
This line of code throws exception that it can't delete image, it's used by another process. Any Idea? How to overwrite it?
Your code is still using it. FromFile() keeps it locked until the image is disposed. It's kind of an obscure semantic, but the MSDN documentation does mention it.
You might try img.Finalize() right after cropImage() as a simple fix. If that doesn't work, pull it in with a FileStream, use the System.Drawing.Bitmap Stream constructor overload, then close the FileStream immediately.