Bild anzeigen mit Zoom und Move

  • WPF

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von MasterQ.

    Bild anzeigen mit Zoom und Move

    Hallo,

    ich möchte in einem WPF-Fenster ein Bild anzeigen (jpg). Der Nutzer soll dann mit der Maus reinzoomen und auch den Bildausschnitt mit der Maus verschieben können.

    Da sowas öfters zur Anwendung kommt, würde es mich nicht wundern, wenn es da was Fertiges gäbe.

    Hat jemand einen Tipp wo ich das abkupfern kann?

    Gruß

    MQ
    Mach dir ein eigenes Control und lass es von PictureBox erben. Das dient dazu, die Mausinteraktion zu vereinfachen.

    Dann brauchst du Code mit dem Ziel, nur den Bitmap-Deskriptor, auch bekannt als RectangleF, zu behandeln, der die Grenzen einer Bitmaps definiert, wobei die Summe der Effekte berücksichtigt wird, die nur im letzten Moment angewendet wurden. Auf diese Weise musst du nur die Form eines Bildes und nicht dessen Inhalt behandeln.
    Hallo

    Mir ist nichts fertiges bekannt. Sollte aber recht einfach gehen wenn man einen Container und eine ViewBox verwendet.
    Ich denke das sollte mit Boardmitteln möglich sein.

    Falls du mit den Heinweisen nicht weiter kommst melde dich gerne nochmals.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Hallo,

    nee, da ist nicht viel dahinter. Mit WinForms hatte ich diesbezüglich schon rumgespielt, da allerdings mit PictureBox.

    Jetzt, wie in meinem anderen Post abzulesen, verwende ich ein Canvas mit einem Image. Das klappt gut, ist aber noch nicht "fertig". Ich kann das Bild verschieben und Zoomen. Das war's.

    Hier mal der aktuelle Stand:

    XML-Quellcode

    1. <UserControl x:Class="DSOHelfer.Controls.ImageZoomMove"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    5. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    6. xmlns:class="clr-namespace:DSOHelfer.Classes"
    7. xmlns:local="clr-namespace:DSOHelfer.Controls"
    8. mc:Ignorable="d"
    9. d:DesignHeight="450"
    10. d:DesignWidth="800"
    11. DataContext="{Binding RelativeSource={RelativeSource Self}}"
    12. >
    13. <UserControl.Resources>
    14. <class:ImageSourceConverter x:Key="imageSourceConverter"/>
    15. </UserControl.Resources>
    16. <Grid>
    17. <Canvas SizeChanged="Canvas_SizeChanged">
    18. <Image Name="image"
    19. Source="{Binding SourceImageZoomMove, Converter={StaticResource imageSourceConverter}}"
    20. MouseDown="image_MouseDown"
    21. MouseUp="image_MouseUp"
    22. MouseWheel="image_MouseWheel"
    23. MouseMove="image_MouseMove"
    24. Width="auto"
    25. Height="auto"
    26. Stretch="Uniform"
    27. />
    28. </Canvas>
    29. </Grid>
    30. </UserControl>


    C#-Quellcode

    1. using System;
    2. using System.ComponentModel;
    3. using System.Runtime.CompilerServices;
    4. using System.Windows;
    5. using System.Windows.Controls;
    6. using System.Windows.Input;
    7. using System.Windows.Media.Imaging;
    8. namespace DSOHelfer.Controls {
    9. /// <summary>
    10. /// Interaktionslogik für ImageZoomMove.xaml
    11. /// </summary>
    12. public partial class ImageZoomMove :UserControl {
    13. public static readonly DependencyProperty SourceImageZoomMoveProperty = DependencyProperty.Register( "SourceImageZoomMove", typeof(string), typeof(ImageZoomMove));
    14. public string SourceImageZoomMove {
    15. get { return (string)GetValue(SourceImageZoomMoveProperty); }
    16. set {
    17. if ((string)GetValue(SourceImageZoomMoveProperty) != value) {
    18. SetValue( SourceImageZoomMoveProperty, value);
    19. }
    20. }
    21. }
    22. public ImageZoomMove() {
    23. InitializeComponent();
    24. }
    25. bool _gedrückt = false;
    26. bool Gedrückt {
    27. get { return _gedrückt; }
    28. set {
    29. _gedrückt = value;
    30. }
    31. }
    32. public event PropertyChangedEventHandler PropertyChanged;
    33. private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") {
    34. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    35. }
    36. System.Windows.Point _start;
    37. System.Windows.Point Start {
    38. get { return _start; }
    39. set { _start = value; }
    40. }
    41. Thickness margin;
    42. double zoom = 1;
    43. private void image_MouseDown(object sender, MouseButtonEventArgs e) {
    44. Gedrückt = true;
    45. margin = image.Margin;
    46. Start = e.GetPosition((IInputElement)this);
    47. }
    48. private void image_MouseUp(object sender, MouseButtonEventArgs e) {
    49. Gedrückt = false;
    50. }
    51. private void image_MouseWheel(object sender, MouseWheelEventArgs e) {
    52. double factor = 1 + e.Delta / 6000F;
    53. zoom *= factor;
    54. image.Width = image.ActualWidth * factor;
    55. image.Height = image.ActualHeight * factor;
    56. }
    57. private void image_MouseMove(object sender, MouseEventArgs e) {
    58. if (Gedrückt) {
    59. Vector pos = e.GetPosition(this) - Start;
    60. var marginneu = new Thickness();
    61. marginneu.Top = margin.Top + pos.Y;
    62. marginneu.Left = margin.Left + pos.X;
    63. image.Margin = marginneu;
    64. }
    65. }
    66. private void Canvas_SizeChanged(object sender, SizeChangedEventArgs e) {
    67. var ich = (sender as Canvas);
    68. var ratioX = e.NewSize.Width / e.PreviousSize.Width;
    69. var ratioY = e.NewSize.Height / e.PreviousSize.Height;
    70. var imgRatio = image.ActualWidth / image.ActualHeight;
    71. var zoomX = e.NewSize.Width / image.ActualWidth;
    72. var zoomY = e.NewSize.Height / image.ActualHeight;
    73. var virtualWidth = image.ActualWidth * zoomY;
    74. var virtualHeight = image.ActualHeight * zoomX;
    75. if (virtualHeight > e.NewSize.Height) {
    76. image.Height = ich.ActualHeight;
    77. image.Width = image.Height * imgRatio;
    78. }
    79. else {
    80. image.Width = ich.ActualWidth;
    81. image.Height = image.Width / imgRatio;
    82. }
    83. }
    84. }
    85. }


    C#-Quellcode

    1. internal class ImageSourceConverter :IValueConverter {
    2. object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture) {
    3. BitmapImage ret;
    4. if (value != null) {
    5. ret = new BitmapImage(new Uri((string)value, UriKind.RelativeOrAbsolute));
    6. }
    7. else {
    8. ret = new BitmapImage(new Uri("/Resources/lock-locked-8x.png",UriKind.Relative));
    9. }
    10. return ret;
    11. }
    12. object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
    13. throw new NotImplementedException();
    14. }


    Einiges ist in diesem Stadium noch nicht notwendig bzw. überflüssig. Anderes fehlt. Aber als Ausgangspunkt ist das schon ganz brauchbar.

    Gruß

    MQ