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?
Related
I'm coding a small app to take a screenshot every X seconds and I've ran into a small but annoying roadblock. Take this image, for example:
Screen captured using the default 'Print Screen' function on Windows 7
If I try to take the same screenshot by using the default .NET 4 Graphics library, the circled area doesn't show up. Same happens with Visual Studio tabbed menus and some other apps I can't remember. The rest of the image comes out fine, tho.
This is the code I'm using. I might be screwing something up but I can't figure it for the life of me. Any help would be appreciated:
memoryImage = new Bitmap(resolution.Width, resolution.Height);
Size s = new Size(memoryImage.Width, memoryImage.Height);
// Create graphics
Console.WriteLine("Creating Graphics...");
Console.WriteLine();
Graphics memoryGraphics = Graphics.FromImage(memoryImage);
// Copy data from screen
Console.WriteLine("Copying data from screen...");
Console.WriteLine();
memoryGraphics.CopyFromScreen(0, 0, 0, 0, s);
This test saves correctly the whole screen on my configuration (Windows 10, VS 2015) =>
Rectangle screenBounds = Screen.GetBounds(System.Drawing.Point.Empty);
using (Bitmap bitmap = new Bitmap(screenBounds.Width, screenBounds.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
{
using (Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(0, 0, 0, 0, bitmap.Size, CopyPixelOperation.SourceCopy);
}
bitmap.Save("e:\\ScreenCopy.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}
I have a C# WPF application which cuts a image to the size I need it. The WPF window is used to put in a user ID to save the image into a database. When I test my application it works sometimes and sometimes i get a error in gdi+ on the line I save the image to the file system.
Here is my code:
public static void CutImage(Image image)
{
//create new image
Bitmap source = new Bitmap(image);
//cut image
Bitmap cuttedImage = source.Clone(new System.Drawing.Rectangle(250, 0, 5550, 4000), source.PixelFormat);
//copy bitmap to avoid "general error in gdi+"
Bitmap copyImage = new Bitmap(cuttedImage.Width, cuttedImage.Height, PixelFormat.Format24bppRgb);
Graphics g = Graphics.FromImage(copyImage);
g.DrawImageUnscaled(cuttedImage, 0, 0);
//dispose graphics object
g.Dispose();
//dispose image
cuttedImage.Dispose();
//save image to filesystem
copyImage.Save(#"path\tmp.jpg", ImageFormat.Jpeg);
}
//get image
Image i = Image.FromFile(path\image.jpg);
//cut image
CutImage(i);
I searched for a solution and somebody said I have to create a copy of the image I got from Image.FromFile(). But the error still happens sometimes. I tried it a few times and it seems to be random when it happens. The error is always on the Image.Save() line.
Does somebody know how to solve this problem or is there a alternative to Image.Save()?
Thanks for your help!
You're creating so many bitmaps and you're not disposing them. Every single IDisposable must be explicitly disposed when you're finished with them.
Try this and see if the error goes away:
public static void CutImage(Image image)
{
using (Bitmap source = new Bitmap(image))
{
using (Bitmap cuttedImage = source.Clone(new System.Drawing.Rectangle(250, 0, 5550, 4000), source.PixelFormat))
{
using (Bitmap copyImage = new Bitmap(cuttedImage.Width, cuttedImage.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb))
{
using (Graphics g = Graphics.FromImage(copyImage))
{
g.DrawImageUnscaled(cuttedImage, 0, 0);
copyImage.Save(#"path\tmp.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
}
}
}
I have a C# WPF application which cuts a image to the size I need it. The WPF window is used to put in a user ID to save the image into a database. When I test my application it works sometimes and sometimes i get a error in gdi+ on the line I save the image to the file system.
Here is my code:
public static void CutImage(Image image)
{
//create new image
Bitmap source = new Bitmap(image);
//cut image
Bitmap cuttedImage = source.Clone(new System.Drawing.Rectangle(250, 0, 5550, 4000), source.PixelFormat);
//copy bitmap to avoid "general error in gdi+"
Bitmap copyImage = new Bitmap(cuttedImage.Width, cuttedImage.Height, PixelFormat.Format24bppRgb);
Graphics g = Graphics.FromImage(copyImage);
g.DrawImageUnscaled(cuttedImage, 0, 0);
//dispose graphics object
g.Dispose();
//dispose image
cuttedImage.Dispose();
//save image to filesystem
copyImage.Save(#"path\tmp.jpg", ImageFormat.Jpeg);
}
//get image
Image i = Image.FromFile(path\image.jpg);
//cut image
CutImage(i);
I searched for a solution and somebody said I have to create a copy of the image I got from Image.FromFile(). But the error still happens sometimes. I tried it a few times and it seems to be random when it happens. The error is always on the Image.Save() line.
Does somebody know how to solve this problem or is there a alternative to Image.Save()?
Thanks for your help!
You're creating so many bitmaps and you're not disposing them. Every single IDisposable must be explicitly disposed when you're finished with them.
Try this and see if the error goes away:
public static void CutImage(Image image)
{
using (Bitmap source = new Bitmap(image))
{
using (Bitmap cuttedImage = source.Clone(new System.Drawing.Rectangle(250, 0, 5550, 4000), source.PixelFormat))
{
using (Bitmap copyImage = new Bitmap(cuttedImage.Width, cuttedImage.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb))
{
using (Graphics g = Graphics.FromImage(copyImage))
{
g.DrawImageUnscaled(cuttedImage, 0, 0);
copyImage.Save(#"path\tmp.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
}
}
}
I'm trying to make an application that I can open and minimize or just leave it there, then with the help of a hotkey I want it to capture a portion of a screen, I got all that covered and working fine except for when I hit the hotkey and I have a game window opened, instead of taking a screenshot of the game it takes a screenshot of what's underneath that window, I've searched literally everywhere and couldn't find an answer, this is the closest I got to:
c# screenshot of active window but doesn't caputre the window
Here's my code:
Bitmap printscreen = new Bitmap(40, 20);
Graphics graphics = Graphics.FromImage(printscreen as Image);
graphics.CopyFromScreen(775, 515, 0, 0, printscreen.Size);
printscreen = Transform(printscreen);
Bitmap newImage = new Bitmap(100, 50);
using (Graphics gr = Graphics.FromImage(newImage))
{
gr.SmoothingMode = SmoothingMode.HighQuality;
gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
gr.DrawImage(printscreen, new Rectangle(0, 0, 100, 50));
newImage.Save("code.jpg");
}
What I'm trying to achieve is capturing a portion of the screen of the active window or a specific window, thanks!
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();
}