潘& 缩放图像
我想在 WPF 中创建一个简单的图像查看器,使用户能够:
- 平移(通过鼠标拖动图像)。
- 缩放(使用滑块)。
- 显示叠加(例如矩形选择)。
- 显示原始图像(如果需要,带有滚动条)。
你能解释一下如何做吗?
我在网上没有找到好的示例。 我应该使用 ViewBox 吗? 还是图像画笔? 我需要 ScrollViewer 吗?
I want to create a simple image viewer in WPF that will enable the user to:
- Pan (by mouse dragging the image).
- Zoom (with a slider).
- Show overlays (rectangle selection for example).
- Show original image (with scroll bars if needed).
Can you explain how to do it?
I didn't find a good sample on the web.
Should I use ViewBox? Or ImageBrush?
Do I need ScrollViewer?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
使用这个问题的样本后,我制作了完整版本的 pan & 缩放应用程序具有相对于鼠标指针的适当缩放。 所有平底锅和 缩放代码已移至名为 ZoomBorder 的单独类。
ZoomBorder.cs
MainWindow.xaml
MainWindow.xaml.cs
After using samples from this question I've made complete version of pan & zoom app with proper zooming relative to mouse pointer. All pan & zoom code has been moved to separate class called ZoomBorder.
ZoomBorder.cs
MainWindow.xaml
MainWindow.xaml.cs
我解决这个问题的方法是将图像放置在 Border 中,并将其 ClipToBounds 属性设置为 True。 然后将图像上的 RenderTransformOrigin 设置为 0.5,0.5,以便图像将开始在图像中心缩放。 RenderTransform 还设置为包含 ScaleTransform 和 TranslateTransform 的 TransformGroup。
然后我处理图像上的 MouseWheel 事件以实现缩放
为了处理平移,我做的第一件事是处理图像上的 MouseLeftButtonDown 事件,捕获鼠标并记录它的位置,我还存储 TranslateTransform 的当前值,这是为了实现平移而更新的。
然后我处理 MouseMove 事件来更新 TranslateTransform。
最后不要忘记释放鼠标捕获。
至于用于调整大小的选择手柄可以使用装饰器来完成,请查看这篇文章 了解更多信息。
The way I solved this problem was to place the image within a Border with it's ClipToBounds property set to True. The RenderTransformOrigin on the image is then set to 0.5,0.5 so the image will start zooming on the center of the image. The RenderTransform is also set to a TransformGroup containing a ScaleTransform and a TranslateTransform.
I then handled the MouseWheel event on the image to implement zooming
To handle the panning the first thing I did was to handle the MouseLeftButtonDown event on the image, to capture the mouse and to record it's location, I also store the current value of the TranslateTransform, this what is updated to implement panning.
Then I handled the MouseMove event to update the TranslateTransform.
Finally don't forget to release the mouse capture.
As for the selection handles for resizing this can be accomplished using an adorner, check out this article for more information.
答案已发布在上面,但并不完整。 这是完整的版本:
XAML
代码隐藏
我有一些源代码演示了这个 记下便签应用。
The answer was posted above but wasn't complete. here is the completed version:
XAML
Code Behind
I have some source code demonstrating this Jot the sticky note app.
试试这个 Zoom 控件: http://wpfextensions.codeplex.com
该控件的用法很简单,参考wpfextensions 组件比:
目前不支持滚动条。 (它将在一到两周内发布的下一个版本中)。
Try this Zoom Control: http://wpfextensions.codeplex.com
usage of the control is very simple, reference to the wpfextensions assembly than:
Scrollbars not supported at this moment. (It will be in the next release which will be available in one or two week).
@Anothen 和 @Number8 - Vector 类在 Silverlight 中不可用,因此要使其工作,我们只需要记录上次调用 MouseMove 事件时看到的最后位置,然后比较两个点以找出差异; 然后调整变换。
XAML:
代码隐藏:
另请注意,您不需要 TransformGroup 或集合来实现平移和缩放; 相反,CompositeTransform 会减少麻烦。
我很确定这在资源使用方面确实效率很低,但至少它有效:)
@Anothen and @Number8 - The Vector class is not available in Silverlight, so to make it work we just need to keep a record of the last position sighted the last time the MouseMove event was called, and compare the two points to find the difference; then adjust the transform.
XAML:
Code-behind:
Also note that you don't need a TransformGroup or collection to implement pan and zoom; instead, a CompositeTransform will do the trick with less hassle.
I'm pretty sure this is really inefficient in terms of resource usage, but at least it works :)
要相对于鼠标位置进行缩放,您需要做的是:
To zoom relative to the mouse position, all you need is:
我也尝试了这个答案,但对结果并不完全满意。 我一直在谷歌上搜索,终于找到了一个 Nuget 包,它可以帮助我在 2021 年管理我想要的结果。我想与 Stack Overflow 的前开发人员分享它。
我使用了 这个 Nuget 包 Gu.WPF.Geometry此 Github 存储库找到。 所有开发功劳都应归于 Johan Larsson,该软件包的所有者。
我如何使用它? 我希望将命令作为缩放框下方的按钮,如
MachineLayoutControl.xaml
中所示。在底层视图模型中,我有以下相关代码:
此外,我希望在加载时立即执行统一填充命令,这是我在代码中设法做到的事情-后面
MachineLayoutControl.xaml.cs
。 您会看到,我仅在执行命令时将 Zoombox 设置为可见,以避免加载用户控件时出现“闪烁”。I also tried this answer but was not entirely happy with the result. I kept googling around and finally found a Nuget Package that helped me to manage the result I wanted, anno 2021. I would like to share it with the former developers of Stack Overflow.
I used this Nuget Package Gu.WPF.Geometry found via this Github Repository. All credits for develoment should go to Johan Larsson, the owner of this package.
How I used it? I wanted to have the commands as buttons below the zoombox, as shown here in
MachineLayoutControl.xaml
.In the underlying Viewmodel, I had the following relevant code:
Also, I wanted that immediately on loading, the Uniform to Fill Command was executed, this is something that I managed to do in the code-behind
MachineLayoutControl.xaml.cs
. You see that I only set the Zoombox to visible if the command is executed, to avoid "flickering" when the usercontrol is loading.@ Merk
对于您的 lambda 表达式的解决方案,您可以使用以下代码:
此代码可以按原样用于 .Net Framework 3.0 或 2.0
希望它可以帮助您:-)
@ Merk
For ur solution insted of lambda expression you can use following code:
this code can be use as is for .Net Frame work 3.0 or 2.0
Hope It helps you :-)
同类控件的另一个版本。 它具有与其他控件类似的功能,但它添加了:
用法很简单:
代码:
Yet another version of the same kind of control. It has similar functionality as the others, but it adds:
Usage is simple:
And the code:
这将放大、缩小和平移,但将图像保持在容器的边界内。 作为控件编写,因此可以直接或通过
Themes/Viewport.xaml
将样式添加到App.xaml
中。为了便于阅读,我还在 gist 和 github
我还将其打包在 nuget
./Controls/Viewport.cs:
./Themes/Viewport.xaml:
./App.xaml
用法:
任何问题,给我一个喊。
快乐编码:)
This will zoom in and out as well as pan but keep the image within the bounds of the container. Written as a control so add the style to the
App.xaml
directly or through theThemes/Viewport.xaml
.For readability I've also uploaded this on gist and github
I've also packaged this up on nuget
./Controls/Viewport.cs:
./Themes/Viewport.xaml:
./App.xaml
Usage:
Any issues, give me a shout.
Happy coding :)
@Wiesław Šoltés 答案 上面 提供的出色解决方案的一个补充
现有代码使用右键单击重置图像位置,但我我更习惯通过双击来完成此操作。 只需替换现有的 child_MouseLeftButtonDown 处理程序:
这样:
One addition to the superb solution provided by @Wiesław Šoltés answer above
The existing code resets the image position using right click, but I am more accustomed to doing that with a double click. Just replace the existing child_MouseLeftButtonDown handler:
With this:
使用 Nuget 包并添加包 wpf.Controls.PanAndZoom
然后在 usercontrol 中放入以下代码:
Use Nuget package and add the package wpf.Controls.PanAndZoom
Then in usercontrol put this code: