microsoft / Windows.UI.Composition-Win32-Samples

Windows.UI.Composition Win32 Samples
MIT License
469 stars 186 forks source link

Capturing a user defined area. #72

Closed MartinClementson closed 3 years ago

MartinClementson commented 4 years ago

Good day!

Are there any plans to add a way to capture a user-defined rectangle to the API? It would be a neat functionality to have. I imagine something like this: image

At the moment I am working on implementing that myself with a few approaches in mind.

1) Capture "All monitors" and use a custom RECT to "CopySubresourceRegion". This has two implications, firstly is the big overhead of capturing all the monitors just to output a (potentially) small rectangle. Second is that the virtual screen coordinate space that the dimensions is most likely based on does not correlate to that of the texture: I am not sure about the following, correct me if I am wrong, but it seems to me that the output texture of "capture all" is the same as the virtual screen, but with different coordinates? image

This means, that if you have a region in monitor 2, it will have values that are < 0 if you got it from the virtual screen space. Which will cause a crash in the cropping stage.

2) Call "MonitorFromRect()" with the coordinates you want to capture, capture the Monitor returned. Convert the coordinates from the virtual screen space to the individual monitor. This comes with the issue that the region can't overlap between monitors.

3) Create a transparent, style, and borderless window, start a capture with that HWND.

At the moment I have a window to set the desktop area to capture. I use the windows client coordinates to get a RECT. But that is in virtual screen coordinates. image

Regarding the picker, I think it's a fantastic and nice-looking UI to use for the capture features. Is there a way to add custom UI drawing to it with WM_PAINT in a winproc callback, or does this window belong to the DWM fully?

I apologize if this question is a bit irrelevant to the usage of the API. I'm keen to hear if you (the devs) have had any ideas of this kind of feature and if there is something along the likes planned for a future version.

Have a great day! Martin

Update: I went with option 2 which works well. DPI scaling was a bit of an issue but setting the process to per-monitor DPI-aware fixed that. I also realized that in the image above, the origin for DX textures are in the top left corner (not the bottom), in case anyone gets confused.

MartinClementson commented 4 years ago

I've been thinking how nice it would be to have functionality that will act in the same way as the windows Snip & Sketch. Where the user can create a rectangular area that will be captured. I'm not sure if the Snip & Sketch is a part of the composition team's work, but I wonder if it would be possible to expose some of the snipping tools API in the future..

robmikh commented 4 years ago

We'll consider it, but we can't make any promises at this stage. Thanks for the feedback 🙂

As for your question about customizing the picker, that's not something we provide today, and I'm not sure it's something we would provide in the future. But let us know what you have in mind.

In the mean time, you'll probably want to explore building this yourself if you want this kind of experience. My recommendation would be to capture each monitor separately and have a window for each monitor. This will give you more control when it comes to things like DPI.