Drawing a Panels Handle to a Bitmap - c#

I have a WPF-Application which hosts a WinformsPanel
<WindowsFormsHost>
<windowsForms:Panel
x:Name="PlayerHost">
</windowsForms:Panel>
<WindowsFormsHost>
I then use this Panel to display a video. I'm using Mpv.NET lib to do this.
The video player is initialized properly:
//panel.Handle is the windowsForms:Panel named PlayerHost
player = new MpvPlayer(panel.Handle, Common.IO.FindLib.FindMpvLib(binaryPath));
player.Load(videoFilePath);
Now, if I try to draw the panels content, the resulting image remains blank. The code to draw the image is as follows:
using (var bmp = new Bitmap(panel.ClientSize.Width, panel.ClientSize.Height))
{
panel.DrawToBitmap(bmp, panel.ClientRectangle);
bmp.Save(#"Some:\path.bmp", System.Drawing.Imaging.ImageFormat.Bmp);
}
To make it clear: The video gets displayed. I can see the video content. And I start drawing to an image when the media is properly loaded. I even offloaded the drawing command to a button click. So while the video was running I tried to take a "frame capture" so to say. But the image remains blank.
How can I capture the panels content? Has it something to do with the native Handle being provided to the video player? Thanks in advance.

You can save the panels content to a bitmap with the following code:
using (Bitmap b = new Bitmap(panel.Width, panel.Height))
{
panel.DrawToBitmap(b, new Rectangle(0, 0, b.Width, b.Height));
b.Save("test.png");
}

Related

Photo captured using CameraCaptureUI is getting stretched when saving

This is for developing a Windows 10 application.
I am trying to capture an image using the camera, edit the captured image,
CameraCaptureUI captureUI = new CameraCaptureUI();
captureUI.PhotoSettings.Format = CameraCaptureUIPhotoFormat.Jpeg;
captureUI.PhotoSettings.AllowCropping = true;
captureUI.PhotoSettings.CroppedAspectRatio = new Windows.Foundation.Size(4, 3);
//captureUI.PhotoSettings.CroppedSizeInPixels = new Windows.Foundation.Size(0,0);
captureUI.PhotoSettings.MaxResolution = Windows.Media.Capture.CameraCaptureUIMaxPhotoResolution.HighestAvailable;
StorageFile file = await captureUI.CaptureFileAsync(CameraCaptureUIMode.Photo);
This shows up the camera, and I am able to preview and click to capture the image. The captured image is shown in another window over the original camera image windows. I am able to crop and click to save this captured image.
However, right after I click save, the image is getting stretched, and after it is saved, it remains stretched as well. In essence, the image I capture and save is being stretched,
I tried changing the CroppedSizeInPixels with size from (0,0) to (200,200). And also various CroppedAspectRatios.
What am I doing wrong? Should I be using any other values for these settings?
Any help here is appreciated.

Why if I call pictureBoxPreview1.Image.Dispose() for only one camera, memory usage spikes?

I am showing the images that I capture from two cameras in a picturebox (the same for both). Each camera image is shown in a different ROI of the picturebox.
My problem is that the memory used by the application is increasing continuously, most probably I am missing freeing some resources, but I cannot find what I am missing.
This is the code:
// bitmap: input new image
// srcRoi: a rectangle with the ROI for the input image
// dstRoi: a rectangle with the ROI for the pictureBox
// reset: true for the first camera, false for the second one.
if (reset)
{
pictureBoxPreview1.Image.Dispose();
}
if (pictureBoxPreview1.Image == null || reset)
{
pictureBoxPreview1.Image = new Bitmap(pictureBoxPreview1.Width,
pictureBoxPreview1.Height);
}
using (Graphics g = Graphics.FromImage(pictureBoxPreview1.Image))
{
using (var img = Image.FromHbitmap(bitmap.GetHbitmap()))
{
g.DrawImage(img, dstRoi, srcRoi, GraphicsUnit.Pixel);
}
}
if (reset) {
pictureBoxPreview1.Invalidate();
}
The problem is not happening if pictureBoxPreview1.Image.Dispose() is call for both cameras, but then only the image of one camera is shown each time.
I don't understand why if I am only creating a new image and disposing it for half of the images the problem is solved when the same thing is done for all the images.
You can follow the answer from the following link WPF CreateBitmapSourceFromHBitmap() memory leak
In brief bitmap.GetHbitmap() is leaking and must be disposed
BTW in case of your bitmap being System.Drawing.Bitmap you can just write
g.DrawImage(bitmap, dstRoi, srcRoi, GraphicsUnit.Pixel);
since Bitmap is Image
BTW you can cache your image by picture box size and reuse it until resized.

Take screenshot at specified coordinates

In a Windows Forms application, how do I take a "screenshot" of certain coordinates?
In the picture below, you see a Window and inside that window is a little gray box, somewhere near the center.
Where every I might place that box, how can I take a "screenshot" of it (including whatever content is inside it) programmatically?
Simple way
Simple, use Graphics.CopyFromScreen
private Bitmap bitmap;
private Graphics graph;
graph.CopyFromScreen(X, Y, 0, 0, Size, CopyPixelOperation.SourceCopy);
Now you can use bitmap, that contains a source copy of the area.
Hacky way
SendKeys.Send("%{PRTSC}"); //Alt + PrtSc to screenshot just the active window.
Bitmap clipboardImage = Clipboard.GetImage(); //Get image from the clipboard
//Here you crop the image using Bitmap.Clone();
//Be happy and question yourself why you are doing this way.

Draw rectangle on picturebox that is showing stream from webcam

I am currently working on a tracking algorithm using C#. I use a picturebox to display the video streams from the webcam:
CameraVideo = new Camera(pbVideo.Handle, pbVideo.Location.X, pbVideo.Location.Y, pbVideo.Size.Width, pbVideo.Size.Height);
CameraVideo.OpenCamera();
new I want to use a rectangle to local the object that I am tracking, but I found that the
Graphics tg = pbVideo.CreateGraphics();
tg.DrawRectangle(......)
cannot show the rectangle that I want. is there anyway to overcome this? Thank you very much!

Take screenshot of wpf popup window

I try to take a screenshot of an application writen in WPF and the application is not captured, must I use a special tool to take the screenshot?
You can use RenderTargetBitmap to generate an image from your WPF control.
public const int IMAGE_DPI = 96;
public Image GenerateImage(T control)
where T : Control, new()
{
Size size = RetrieveDesiredSize(control);
Rect rect = new Rect(0, 0, size.Width, size.Height);
RenderTargetBitmap rtb = new RenderTargetBitmap((int)size.Width, (int)size.Height, IMAGE_DPI, IMAGE_DPI, PixelFormats.Pbgra32);
control.Arrange(rect); //Let the control arrange itself inside your Rectangle
rtb.Render(control); //Render the control on the RenderTargetBitmap
//Now encode and convert to a gdi+ Image object
PngBitmapEncoder png = new PngBitmapEncoder();
png.Frames.Add(BitmapFrame.Create(rtb));
using (MemoryStream stream = new MemoryStream())
{
png.Save(stream);
return Image.FromStream(stream);
}
}
private Size RetrieveDesiredSize(T control)
{
if (Equals(control.Width, double.NaN) || Equals(control.Height, double.NaN))
{
//Make sure the control has measured first:
control.Measure(new Size(double.MaxValue, double.MaxValue));
return control.DesiredSize;
}
return new Size(control.Width, control.Height);
}
Note that this will generate a PNG image ;) If you wish to store it as a JPEG, I suggest you use another encoder :)
Image image = GenerateImage(gridControl);
image.Save("mygrid.png");
You can simply press PrtScr button (windows will copy whole descktop image to buffer), then paste it in Power Point and crop if you like.
I'm having the same issue, I need to take screenshots to document my tests but can't seem to get there.
The Window in question is a Borderless modal Window with rounded corners / transparency allowed. Here's my report:
HP Quality Center's Screenshot tool doesn't recognize it as a window and thus takes its screenshots as if the window weren't there.
SnagIt utilizes a keycombo to enter the capture mode. Once stroke is hit, the popup vanishes. It reappears after the capture has ended.
Standard Windows capture works OK (Alt + Prt Scr) and captures the window as it was intended to be captured.
Next thing I tried was capturing the window with an opened dropdownlist. None of the approaches mentioned above seems to work (the last approach captures the Window the same way it did before, without the open dropdown).
As far as I have understood all the talk correctly, the only thing you can do is implement this into the applications...

Categories

Resources