在WPF中截取一个截图? [英] Taking a round screenshot in WPF?

查看:414
本文介绍了在WPF中截取一个截图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嘿伙计们,尽快需要一些帮助!

我有一个创建新用户窗口,在其中我可以选择拍摄个人资料图片。现在,配置文件图像在加载时输入到imageBrush控件中的System.Windows.Shape.Path控件内,并且在path.Data中,我将CombineGeometry与EllipseGeometry一起输入(我们称之为circle)。

现在,当鼠标悬停在图片上时,圆圈跟随光标,无论它走到哪里,在mouse_double_click事件上,我希望代码截取圆圈的截图,只有 圆圈

打印路径本身没问题(因为它的类是Visual)。打印圈子组件是其他东西(媒体类)。

有没有人知道如何开始这个???

我正在添加相关的xaml,但我不确定这里的代码是否可读:

< path x:name =pathFrontrendertransformorigin =0.5,0.5xmlns:x =#unknown >

Stroke =TransparentStrokeThickness =1Stretch =NoneMargin =1>

< path.rendertransform>

< transformgroup> < skewtransform anglex =0angley =0>

< rotatetransform x:name =rtAngle2angle =0>

< translatetransform x =0>

< path.fill>

< ImageBrush x:Name =imgFront

Stretch =FillAlignmentX =Center AlignmentY =CenterOpacity =1/>



< path.effect>

< blureffect x:name = imgFrontBlurRadiusradius =15renderingbias =Qualityframeworkelement.flowdirection =RightToLeft>



< path.data>

< combinedgeometry geometrycombinemode =Exclude>

< combinedgeometry.geometry1>

< ellipsegeometry x:name =circle2radiusx =113radiusy =113center =115,115>



< combinedgeometry.geometry2>

< ellipsegeometry x:name =circle 中心r =120,120radiusx =65radiusy =65>







< br $>






我尝试过:



i试图在没有运气的情况下截取圆圈内的区域,尝试创建具有相同半径圆形的矩形然后再次打印并且没有运气...

解决方案

在我对这个问题的评论中,我解释说你必须使外部像素透明,并解释为什么其他一切都是荒谬的,或者至少是不切实际的。在不切实际的情况下,效果与透明像素相同,因为没有无像素这样的概念。



这是你怎么做的这一切: WriteableBitmap Class(System .Windows.Media.Imaging) [ ^ ]。



所有用法都在文档中有详细说明。注意一个关键的事情:你需要使用 PixelFormat ,其中包括每个像素的不透明度,即 alpha-channel 。另请参阅: PixelFormat Structure(System.Windows。媒体) [ ^ ]。



你必须将每个外部像素的不透明度(alpha值)设置为零,但我会建议在圆形线周围进行一些平滑过渡,以提供一种抗锯齿。这不是那么简单的事情,但很少有实验会给你合理的渲染。



你还需要绘图方面的帮助吗?这是一个非常简单的话题。总的来说,整个问题相当简单,只需要一些逻辑和理解。



-SA


< blockquote>简单,解决方案是:

  private   void  SnapShot()
{

RenderTargetBitmap rtb = new RenderTargetBitmap(Convert.ToInt32(pathBack.ActualWidth) ),Convert.ToInt32(pathBack.ActualHeight), 0 0 ,PixelFormats.Pbgra32);
pathBack.Clip = circle;
rtb.Render(pathBack);
PngBitmapEncoder pngImage = new PngBitmapEncoder();
pngImage.Frames.Add(BitmapFrame.Create(rtb));
使用(流fileStream = File.Create( @ C:\ Users \אורון\Desktop\EW\test\1.png))
{
pngImage.Save(fileStream);
}
}


我差点忘了:还有一个完全不同的解决方案。



您可以创建渲染位图的非矩形控件。你可以用它做圆形。然后你可以把这个控件作为任何其他控件的孩子:他们不需要的像素将真正失踪。但是,它们都在位图中,正如我已经解释的那样,根据定义,它是矩形的。



这是如何:你创建一个自定义控件(但是它甚至可以是一些 Panel 类或从它派生的类)并在其上放置一个图像(矩形)。完成。现在,你删除了这个控件的一部分。这是通过以下方式完成的:将非矩形几何对象分配给属性 Clip

UIElement.Clip Property(System .Windows) [ ^ ](请参阅此处的代码示例),

Geometry Class(System.Windows.Media) [ ^ ]。



这种方法的问题:使用解决方案1,你不会得到抗锯齿。



-SA

Hey guys, need some help asap!
i have a "create new user" window which in it i have an option to take profile image. Now, the profile image, when loaded, is entered inside System.Windows.Shape.Path control in an imageBrush control and inside the path.Data i have CombineGeometry with EllipseGeometry (lets call it "circle").
Now, when the mouse is hover the picture, the "circle" is follow the cursor wherever it go and on a mouse_double_click event i want the code to take screenshot of the circle and only the circle.
printing the path itself is no problem (since its class is "Visual"). printing the "circle" component is somthing else ("Media" class).
does anyone has any idea how to get started with this???
i'm adding the relevent xaml but i'm not sure the code will be readable in here:
<path x:name="pathFront" rendertransformorigin="0.5,0.5" xmlns:x="#unknown">
Stroke="Transparent" StrokeThickness="1" Stretch="None" Margin="1" >
<path.rendertransform>
<transformgroup> <skewtransform anglex="0" angley="0">
<rotatetransform x:name="rtAngle2" angle="0">
<translatetransform x="0">
<path.fill>
<ImageBrush x:Name="imgFront"
Stretch="Fill" AlignmentX="Center" AlignmentY="Center" Opacity="1"/>

<path.effect>
<blureffect x:name="imgFrontBlurRadius" radius="15" renderingbias="Quality" frameworkelement.flowdirection="RightToLeft">

<path.data>
<combinedgeometry geometrycombinemode="Exclude">
<combinedgeometry.geometry1>
<ellipsegeometry x:name="circle2" radiusx="113" radiusy="113" center="115,115">

<combinedgeometry.geometry2>
<ellipsegeometry x:name="circle" center="120,120" radiusx="65" radiusy="65">







What I have tried:

i have tryed to take screenshot of the area inside the circle with no luck, tryed to create rectangle with the same radius of the circle and then print it and again with no luck...

解决方案

In my comments to the question, I explained that you have to make outside pixels transparent, and explained why everything else would be just absurd, or at least impractical. In the "impractical" case, the effect is the same as with transparent pixels, because there is no such notion as "no pixel".

This is how you can do it all: WriteableBitmap Class (System.Windows.Media.Imaging)[^].

All the usage is well explained in documentation. Note one key thing: you need to use PixelFormat which include opacity for each pixels, which is the alpha-channel. See also: PixelFormat Structure (System.Windows.Media)[^].

You have to set opacity (alpha value) of each outside pixels to zero, but I would advice some smooth transition around the circular line, to provide a kind of anti-aliasing. This is not so trivial thing, but little experimenting will give you the reasonable rendering.

Do you also need help with drawing? This is a pretty simple topic. Overall, the whole problem is fairly simple, just needs some logic and understanding.

—SA


Simpley as can be, the solution is:

private void SnapShot()
       {

           RenderTargetBitmap rtb = new RenderTargetBitmap(Convert.ToInt32(pathBack.ActualWidth) , Convert.ToInt32(pathBack.ActualHeight), 0, 0, PixelFormats.Pbgra32);
           pathBack.Clip = circle;
           rtb.Render(pathBack);
           PngBitmapEncoder pngImage = new PngBitmapEncoder();
           pngImage.Frames.Add(BitmapFrame.Create(rtb));
           using (Stream fileStream = File.Create(@"C:\Users\אורון\Desktop\EW\test\1.png"))
           {
               pngImage.Save(fileStream);
           }
       }


I almost forgot: there is one more radically different solution.

You can create a non-rectangular control rendering the bitmap. You can make it with the round shape. And then you can put this control as a child of any other control: they unwanted pixels will truly me "missing". But still, they all be in the bitmap, which is, as I already explained, is rectangular by definition.

Here is how: you create a custom control (but it can be even some Panel class or the class derived form it) and put an image (rectangular) on it. Done. Now, you cut out a part of this control. This is done in the following way: assign a non-rectangular Geometry object to the property Clip:
UIElement.Clip Property (System.Windows)[^] (see the code samples here),
Geometry Class (System.Windows.Media)[^].

The problem of this approach: you won't get anti-aliasing possible with Solution 1.

—SA


这篇关于在WPF中截取一个截图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆