Need to delete a file, in use by my own app - c#

I'm fiddling with a desktop gadget (a clock). It has a reflection effect underneath it that needs to be transparent, and I'm using CopyFromScreen to get the background, then just setting the form background to this.
Like so (part of a "dock/undock" button):
Rectangle bounds = this.Bounds;
using (Bitmap ss = new Bitmap(bounds.Width, bounds.Height))
using (Graphics g = Graphics.FromImage(ss))
{
this.Opacity = 0;
g.CopyFromScreen(this.Location, Point.Empty, bounds.Size);
ss.Save(#"C:\clock1s\bg", ImageFormat.Png);
this.Opacity = 100;
this.BackgroundImage = new Bitmap(#"C:\clock1s\bg");
g.Dispose();
}
Now, whenever I want to use this again (e.g move the clock) I'm not able to delete that file or resave it because it is currently in use. I've already tried setting the form BG to something else, but that didn't work.
How do I go about?
EDIT: Sorted, thanks (Lance McNearney).
Now, what if I had to save it to file?
Also, bonus question:
the goddamn batwatch http://upload.snelhest.org/images/100219batwatch.jpg
Selections and icons ending up underneath the form is a minor annoyance, and if possible I'd like them to either end up on top, or below (keeping the smooth anti-aliasing). I'm assuming that's way out of my leauge to fix though.

Do you really need to save the image to the file system? Can't you store it in memory just for your application (and you won't have the problem anymore)?
A MemoryStream should work as a drop-in replacement for the file path in your code (although I obviously can't compile to test it):
Rectangle bounds = this.Bounds;
using (Bitmap ss = new Bitmap(bounds.Width, bounds.Height))
using (Graphics g = Graphics.FromImage(ss))
{
this.Opacity = 0;
g.CopyFromScreen(this.Location, Point.Empty, bounds.Size);
using(MemoryStream ms = new MemoryStream()) {
ss.Save(ms, ImageFormat.Png);
this.Opacity = 100;
this.BackgroundImage = new Bitmap(ms);
}
g.Dispose();
}

Related

How can I create a screenshot?

How can i create screenshot in c# Windows Forms App?
I tried:
ScreenCapture sc = new ScreenCapture();
Image img = sc.CaptureScreen();
this.imageDisplay.Image = img;
sc.CaptureWindowToFile(this.Handle, "C:\\temp2.png", ImageFormat.png);`
Second Attempt
using (var bitmap = new Bitmap(1680, 1050))
{
DrawToBitmap(bitmap, new Rectangle(0, 0, bitmap.Width, bitmap.Height));
bitmap.Save(#"c:\TEST.bmp");
}
I would have refered you to this post on the same topic Capture screenshot of active window? but it looks like the accepted answer is where you copied your original code from. That code relies on an 3rd party library from 2004 (https://www.developerfusion.com/code/4630/capture-a-screen-shot/) so you need to add that to your project in order to use your code.
But the same question has 10 other answers which does not rely on 3rd party libraries and most of them should work just fine.
Like this one for example:
Rectangle bounds = Screen.GetBounds(Point.Empty);
using(Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height)) {
using(Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
}
bitmap.Save("test.jpg", ImageFormat.Jpeg);
}
https://stackoverflow.com/a/1163770/612620
This question should probably be marked as a duplicate of Capture screenshot of active window?

Save panel or Form as image with High quality

I am currently using this code to screen capture the panel I created, but whenever I am saving it, the quality is bad. Is there any way to maintain the good quality when saving it?
I tried resizing the panel but the result is still the same.
I tried doing a normal screen shot with the snipping tool and it also has the same result with the codes I use.
Any suggestions? or help?
private void SaveControlImage(Control theControl)
{
snapCount++;
int width = panel1.Size.Width;
int height = panel1.Size.Height;
Bitmap bm = new Bitmap(width, height, PixelFormat.Format64bppPArgb);
panel1.DrawToBitmap(bm, new Rectangle(0, 0, width, height));
//bm.Save(#"D:\TestDrawToBitmap.bmp", ImageFormat.Bmp);
bm.Save(deskTopPath + #"/Offer_" + snapCount.ToString() + "_" + DateTime.Now.ToString("yyyyMMdd") + #".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}
Like here, it looks pixelated if you compare it to what you're reading now (like this website). I tried to screen cap the form but it looks like the uploaded picture so its useless
Screenshot:
Bitmap bmp= new Bitmap(controls.Width, controls.Height-50, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
Graphics Grap = Graphics.FromImage(bmp);
Grap.CopyFromScreen(PointToScreen(controls.Location).X, PointToScreen(controls.Location).Y, 0, 0, AnhDoThi.Size, CopyPixelOperation.SourceCopy);
SaveFileDialog save = new SaveFileDialog();
save.Filter = "JPEG|*.jpg";
DialogResult tl = save.ShowDialog();
if (tl == DialogResult.OK)
{
bmp.Save(save.FileName);
MessageBox.Show("Completed !");
}
This is what I use to save a screenshot:
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
private void SaveControlAsImage(Control control, string path)
{
Bitmap bitmap = new Bitmap(control.Width, control.Height);
control.DrawToBitmap(bitmap, control.Bounds);
using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.ReadWrite))
{
/* using ImageFormat.Png or ImageFormat.Bmp saves the image with better quality */
bitmap.Save(fs, ImageFormat.Png);
}
}
Control screenshot using Windows Snipping Tool
Control screenshot using SaveControlAsImage (ImageFormat.Png)
Control screenshot using SaveControlAsImage (ImageFormat.Jpeg)
It's not the best quality (just a little blurry), but this removes the distortion around the text and keeps the right color.
Sidenote: You're not using the parameter (theControl) passed to your method, so you might as well remove it (not recommended), or change all the calls to panel1 inside the method to theControl and call the method like
this.SaveControlImage(this.panel1);
Also, when you're accessing just a property (i.e. this.panel1.Size.Width) it's better to just call the property instead of assign it to a variable. If you're calling a method and getting a value back (which you'll be using more than once), you must assign it to a variable (i.e. int arrayCount = array.Count()).
Windows Forms is not using vector graphics to draw the user interface. Therefore, all you can get generically is to draw the control to a Bitmap instead of to the screen. This works independently of whether your control is visible on the screen, but there is not more than that. If you want a higher-resolution image from a Windows Forms control, the only way is to resize the control and hope that it supports zooming.

text not showing on bitmap image in C#

I can't seem to get the text I've written to show up on my image Here's the code I'm using
//Creates a bitmap with the path to the current image
Bitmap LabelImage = new Bitmap(dtImages.Rows[intCurrentImage]["ImageURL"].ToString());
Graphics graphic = Graphics.FromImage(LabelImage);
graphic.DrawString("Hello", new Font("Tahoma",40), Brushes.Azure, new System.Drawing.Point(0,0));
//put Image that I just created and put the text on into an Infragistics UltraPicureBox
picImage.Image = LabelImage
You did not update your original image (LabelImage), so why should the text you added to the Graphics object show up?.
From MSDN, Graphics.FromImage:
Creates a new Graphics from the specified Image.
(emphasis mine)
After you have added the text, you need to save the changes:
graphic.Save();
Unrelated to your question, you should really put the creation of the Graphics object in a using statement, to ensure proper disposal:
using(Graphics graphic = Graphics.FromImage(LabelImage))
{
// use graphic here
}
I just tried this
Bitmap bitmap = new Bitmap("C:\\Untitled.png");
Graphics g = Graphics.FromImage(bitmap);
g.DrawString("Hello", new Font("Tahoma", 40), Brushes.Azure, new System.Drawing.Point(0, 0));
pictureBox1.Image = bitmap;
and it works fine for me. Just try to pick a contrasting brush.

Saving System.Drawing.Graphics to a png or bmp

I have a Graphics object that I've drawn on the screen and I need to save it to a png or bmp file. Graphics doesn't seem to support that directly, but it must be possible somehow.
What are the steps?
Here is the code:
Bitmap bitmap = new Bitmap(Convert.ToInt32(1024), Convert.ToInt32(1024), System.Drawing.Imaging.PixelFormat.Format32bppArgb);
Graphics g = Graphics.FromImage(bitmap);
// Add drawing commands here
g.Clear(Color.Green);
bitmap.Save(#"C:\Users\johndoe\test.png", ImageFormat.Png);
If your Graphics is on a form, you can use this:
private void DrawImagePointF(PaintEventArgs e)
{
... Above code goes here ...
e.Graphics.DrawImage(bitmap, 0, 0);
}
In addition, to save on a web page, you could use this:
MemoryStream memoryStream = new MemoryStream();
bitmap.Save(memoryStream, ImageFormat.Png);
var pngData = memoryStream.ToArray();
<img src="data:image/png;base64,#(Convert.ToBase64String(pngData))"/>
Graphics objects are a GDI+ drawing surface. They must have an attached device context to draw on ie either a form or an image.
Copy it to a Bitmap and then call the bitmap's Save method.
Note that if you're literally drawing to the screen (by grabbing the screen's device context), then the only way to save what you just drew to the screen is to reverse the process by drawing from the screen to a Bitmap. This is possible, but it would obviously be a lot easier to just draw directly to a Bitmap (using the same code you use to draw to the screen).
Try this, works fine for me...
private void SaveControlImage(Control ctr)
{
try
{
var imagePath = #"C:\Image.png";
Image bmp = new Bitmap(ctr.Width, ctr.Height);
var gg = Graphics.FromImage(bmp);
var rect = ctr.RectangleToScreen(ctr.ClientRectangle);
gg.CopyFromScreen(rect.Location, Point.Empty, ctr.Size);
bmp.Save(imagePath);
Process.Start(imagePath);
}
catch (Exception)
{
//
}
}
Graphics graph = CreateGraphics();
Bitmap bmpPicture = new Bitmap("filename.bmp");
graph.DrawImage(bmpPicture, width, height);
You are likely drawing either to an image or on a control. If on image use
Image.Save("myfile.png",ImageFormat.Png)
If drawing on control use Control.DrawToBitmap() and then save the returned image as above.
Thanks for the correction - I wasn't aware you can draw directly to the screen.

How do I display an image within a region defined in a Picturebox?

As a follow on to my previous question I have gotten my region but spent the last two hours trying to display tiny pictures wihing that region alone; with the end goal being to be able to arbitarily display any number of images I choose.
so far this is my code:
void OnPaintRadar(Object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
Bitmap blip = new Bitmap(tst_Graphics.Properties.Resources.dogtag);
Rectangle radar_rect = new Rectangle(myRadarBox.Left + 80, myRadarBox.Left + 7, myRadarBox.Width - 200, myRadarBox.Height + 200);
using (Pen drw_pen = new Pen(Color.White, 1) )
{
using (GraphicsPath path = new GraphicsPath())
{
path.AddPie(radar_rect, 180, 180);
path.CloseFigure();
using (Region rdRegion = new Region(path) )
{
g.DrawPath(drw_pen, path);
g.Clip = rdRegion;
PictureBox pb = new PictureBox();
pb.Image = (blip);
pb.Size = blip.Size;
g.DrawImage(blip, radar_rect);
}
}
}
}// end paint method
I have tried the DrawImageUnscaled method also but I either get a my tiny picture blown to fill the pie region or nothing is displayed.
Click here to run a sample application that demonstrates the basics of how to do radar (or one way, at least). Note: this application does not do double-buffering or transparency of the tiny image.
Source code for the project is here.
This line:
pb.Image = (blip);
is what's causing the tiny image to appear large. Basically, you pulling a tiny bitmap out of resources, and then setting the PictureBox's Image property to that bitmap (I'm assuming "pb" is a PictureBox on your form). Try commenting out that line and the line below it.

Categories

Resources