I am working on taking screenshot of UI Element (WPF) in various size and i'm able to achieve this using "RenderTargetBitmap. But the UIElement
which has an Adorner
part is not coming while take copy. What should i do to achieve this. Any reference or code snippet?
相关问题
- Sorting 3 numbers without branching [closed]
- Graphics.DrawImage() - Throws out of memory except
- Why am I getting UnauthorizedAccessException on th
- 求获取指定qq 资料的方法
- How to know full paths to DLL's from .csproj f
You can use the native WPF Printing name space to print to an XPS file and this will include the adorner in the result (I tested it successfully)...
If you did not want to use the PrintDialog (which actually opens a dialog box). You can use the XpsDocumentWriter class to programmatically control the process. The enabling snippet for this is...
...which was extracted from here: Print FixedDocument programmatically And there are more articles about fine-tuning the process if that is part of your requirements. NOTE that the XPS file is actually a 'zip' file masquerading as an 'xps' file, so you can unzip it by changing the extension to see if the contents are of any use.
Secondarily, I tested saving a window with an adorner on a TextBox with this code...
...with good results. I.e., the adorner appeared in the saved bitmap with its red border. This might differ from your code because I use a Png encoder (but saved to a 'jpg' file).
Although I have tested both approaches successfully, you'll need to check them on your hardware.
And lastly, as a last-ditch resort, you can deactivate WPF's hardware rendering mode and set it to software rendering...
...for which there's a nice SO thread here: Software rendering mode - WPF
In my case all I needed was call the AdornerLayer class like so:
This works if you want to include ALL adorners in your canvas.
As far as I know, elements don't have direct references to their adorners. Adorners do reference their element through AdornedElement though, so you could search for adorners assigned to your element like this:
Here
GetVisualChildren
is an extension method which is defined as:The size of the adorner seems to include the size of the adorned element (although I'm not sure if this is always the case), so if there is only one adorner, that is your screenshot size. If there is more than one adorner, you would need to find the maximum for each bound (left, top, right, bottom) to calculate the screenshot region.
You will need to capture the
AdornerDecorator
which contains both the elements being adorned and theAdornerLayer
(layer
in the above code). That would be the visual parent of the layer:Once you have the container, you can render it with
RenderTargetBitmap
and crop it to the screenshot region.For the screenshot region, you need the element bounds relative to the container. First, get the non-relative bounds:
Then get those bounds relative to the container:
As I mentioned above, you will need to do this for the element as well as each of its adorners and combine the maximum bounds into one final Rect which is just large enough to contain all of them.
Finally, use CroppedBitmap to get a cropped version of the
RenderTargetBitmap
:CroppedBitmap
andRenderTargetBitmap
both inherit fromBitmapSource
, so you should be able to save it the same way.