snapshot on C# (without monitor or even graphic card installed) - c#

I'm trying to record all what happens in my little program(video and audio). I've found on forums people mentioning that there can be a big problem if screenshot is made on the machine without monitor - no monitor physically connected or when graphics card places monitor in sleep mode or even without graphics card installed (servers). is there a way to solve this issue? currently i haven't access to server and even don't know it's configuration(((
currently i'm using this code to make snapshots every 50 milliseconds and it's works great on desktop pc(can't check this code without monitor... i'm using HP touchsmart monoblock desktop)
IntPtr myIntptr = FormElement.Handle;
int hwndInt = myIntptr.ToInt32();
IntPtr hwnd = myIntptr;
Bitmap bm = new Bitmap(FormElement.Width, FormElement.Height);
Graphics g = Graphics.FromImage(bm);
IntPtr hdc = g.GetHdc();
bool result = PrintWindow(hwnd, hdc, 0);
g.ReleaseHdc(hdc);
g.Flush();
if (result == true)
{
bm.Save(aFileName, ImageFormat.Jpeg);
}
this doent work if i minimize my window and this is not good too.
sorry for my english and thanx for any advice.

Try like this:
public static void ScreenCapture(string filename, int width, int height)
{
var bounds = new Rectangle(0, 0, width, height);
using (var bitmap = new Bitmap(bounds.Width, bounds.Height))
using (Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(
new Point(bounds.Left, bounds.Top), Point.Empty, bounds.Size
);
bitmap.Save(filename, ImageFormat.Jpeg);
}
}

Related

can't capture Full Screen image ?? (with taskbar and any other open windows)

i have a problem with this code :
i need to screenshot the full screen that i see with all things (taskbar, anything open).
my code is just giving me a cropped pic of just one window
Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height);
Graphics graphics = Graphics.FromImage(bitmap as Image);
graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size);
bitmap.Save("D://Changes.jpg", ImageFormat.Jpeg);
Your display settings are set to 125% (or higher) zoom.
Your application isn't DPI aware. You can correct that by updating your application's manifest.
If that doesn't work for you (or you'd rather not use the manifest), you can pinvoke GetDeviceCaps API to get the correct width and height for CopyFromScreen.
Here are your native definitions:
private static class Win32Native
{
public const int DESKTOPVERTRES = 0x75;
public const int DESKTOPHORZRES = 0x76;
[DllImport("gdi32.dll")]
public static extern int GetDeviceCaps(IntPtr hDC, int index);
}
And you'd call it as so:
int width, height;
using(var g = Graphics.FromHwnd(IntPtr.Zero))
{
var hDC = g.GetHdc();
width = Win32Native.GetDeviceCaps(hDC, Win32Native.DESKTOPHORZRES);
height = Win32Native.GetDeviceCaps(hDC, Win32Native.DESKTOPVERTRES);
g.ReleaseHdc(hDC);
}
using (var img = new Bitmap(width, height))
{
using (var g = Graphics.FromImage(img))
{
g.CopyFromScreen(0, 0, 0, 0, img.Size);
}
img.Save(#"C:\users\andy\desktop\test.jpg", ImageFormat.Jpeg);
}

Printing only the active window in C#

I want to print only the active window from a C# application. Using CopyFromScreen() does not work as it takes a screenshot and the window can be partially hidden by other transient windows appearing. So I tried PrintWindow():
private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
e.Graphics.PageScale = 10.0f;
Graphics g = e.Graphics;
PrintWindow(this.Handle, g.GetHdc(), 0);
}
This produces a tiny stamp-sized printout of the window regardless of which PageScale I use.
Any ideas?
EDIT
This does the trick:
private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
Graphics myGraphics = CreateGraphics();
var bitmap = new Bitmap(Width, Height, myGraphics);
DrawToBitmap(bitmap, new Rectangle(0, 0, bitmap.Width, bitmap.Height));
e.Graphics.DrawImage(bitmap, 0, 0);
}
Some googling around, and I found: Copying content from a hidden or clipped window in XP?
It seems you will need to prepare a bitmap for storing the page:
// Takes a snapshot of the window hwnd, stored in the memory device context hdcMem
HDC hdc = GetWindowDC(hwnd);
if (hdc)
{
HDC hdcMem = CreateCompatibleDC(hdc);
if (hdcMem)
{
RECT rc;
GetWindowRect(hwnd, &rc);
HBITMAP hbitmap = CreateCompatibleBitmap(hdc, RECTWIDTH(rc), RECTHEIGHT(rc));
if (hbitmap)
{
SelectObject(hdcMem, hbitmap);
PrintWindow(hwnd, hdcMem, 0);
DeleteObject(hbitmap);
}
DeleteObject(hdcMem);
}
ReleaseDC(hwnd, hdc);
}

c# screenshot of active window but doesn't caputre the window

I'm creating an application in which I need to create a PDF file with the screenshot of the application.
I found how to create the screenshot and how to put it in my file. All is working well in most situations.
My problem comes when I use more than one screen or a programm like Teamviewer. The problem is, my programm captures the right area (good coordinates on the screen whenever which screen) but it captures all what's behind the window but not the window.
Does somebody knows what am I doing wrong or if I missed a detail ?
Here is the code I'm currently using :
// creates an rectangle of the size of the window
Rectangle bounds = new Rectangle(
(int)System.Windows.Application.Current.MainWindow.Left+10,
(int)System.Windows.Application.Current.MainWindow.Top+10,
(int)System.Windows.Application.Current.MainWindow.Width-20,
(int)System.Windows.Application.Current.MainWindow.Height-20);
// creates a bitmap with a screenshot of the size of the window
Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height);
Graphics g = Graphics.FromImage(bitmap);
g.CopyFromScreen(new System.Drawing.Point(bounds.Left, bounds.Top), new System.Drawing.Point(0,0), bounds.Size);
Thanks in advance for any help or examples.
I don't understand exactly you. I think you need to do is capture the active window.
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);
}
//for capturing current window use
Rectangle bounds = this.Bounds;
using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height))
{
using (Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(new Point(bounds.Left,bounds.Top), Point.Empty, bounds.Size);
}
bitmap.Save("C://test.jpg", ImageFormat.Jpeg);
}
Source: Capture screenshot of active window?

Continuous creation of bitmaps leads to memory leak

I have a thread that continuously generates bitmaps and takes a screenshot of another program's window. Now, I have a pictureBox on my form, and that's constantly being updated with the bitmaps generated. Here's the code I have in the thread:
Bitmap bitmap = null;
while (true)
{
if (listBoxIndex != -1)
{
Rectangle rect = windowRects[listBoxIndex];
bitmap = new Bitmap(rect.Width, rect.Height);
Graphics g = Graphics.FromImage(bitmap);
IntPtr hdc = g.GetHdc();
PrintWindow(windows[listBoxIndex], hdc, 0);
pictureBox1.Image = bitmap;
g.ReleaseHdc(hdc);
}
}
As you can see, this leads to a memory leak, because of the continuous call to new Bitmap(rect.Width, rect.Height). I've tried adding "bitmap.Dispose()" to the bottom of the while loop, but that leads to the pictureBox's image also being disposed, which makes a giant red X in place of the actual image. Is there any way I can dispose of "bitmap" without disposing of the pictureBox image?
You're also "leaking" the Graphics object. Try this:
while (true)
{
if (listBoxIndex != -1)
{
Rectangle rect = windowRects[listBoxIndex];
Bitmap bitmap = new Bitmap(rect.Width, rect.Height);
using (Graphics g = Graphics.FromImage(bitmap))
{
IntPtr hdc = g.GetHdc();
try
{
PrintWindow(windows[listBoxIndex], hdc, 0);
}
finally
{
g.ReleaseHdc(hdc);
}
}
if (pictureBox1.Image != null)
{
pictureBox1.Image.Dispose();
}
pictureBox1.Image = bitmap;
}
}
The answered example has a leak with Graphics g
after g.ReleaseHdc(..);
Remember to dipose the graphics variable
as for example:
g.Dispose();

DrawThemeBackground to bitmap

I am trying to use DrawThemeBackground to draw to a bitmap in C#, but it always comes out as black.
Bitmap bmp = new Bitmap(this.Width, this.Height, PixelFormat.Format32bppArgb);
using (Graphics g = Graphics.FromImage(bmp))
{
g.Clear(Color.Green);
IntPtr hdc = g.GetHdc();
DrawThemeBackground(hTheme, hdc, 0, 1, ref rect, IntPtr.Zero);
g.ReleaseHdc(hdc);
}
It appears that DrawThemeBackground isn't looking at the background colour of the bitmap (green in this case) and is always blending with black. Am I missing something here? Is this even possible to do?

Categories

Resources