WPF εφαρμογή διαχείρισης εικόνων
Σε αυτόν το άρθρο – οδηγό, θα δημιουργήσουμε μια WPF εφαρμογή διαχείρισης εικόνων. Αυτή η εφαρμογή θα κάνει Zoom In – Zoom Out και θα μετακινεί την εικόνα σε ένα καθορισμένο αρχικό πλαίσιο. Μπορείτε να κατεβάσετε τον πηγαίο κώδικα τις εφαρμογής εδώ.
WPF εφαρμογή διαχείρισης εικόνων: Κατασκευή του UI μέσω XAML.
Για τις ανάγκες αυτού του οδηγού θα κατασκευάσουμε ένα απλό περιβάλλον χρήστη μέσω της γλώσσας XAML που χρησιμοποιούν οι WPF εφαρμογές.
Το περιβάλλον αυτό θα αποτελείται από ένα πλέγμα (Grid), ένα control που θα ορίζει τα όρια (Border), μια εικόνα (Image) και ένα control κειμένου (Label).
<Window x:Class="WPFImagePanAndZoom.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="WPFWindow" Title="WPF Pan And Zoom" mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" Height="610" Width="566"> <Grid x:Name="LayoutRoot" > <Grid.RowDefinitions> <RowDefinition Height="52.92"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Border Grid.Row="1" Name="border" ClipToBounds="True"> <Image Name="image" Opacity="1" Source="/WPF%20Image%20Pan%20and%20Zoom;component/Images/test.tif" /> </Border> <Label Content="Mousewheel to zoom. Hold left mousebutton to pan." Height="35" HorizontalAlignment="Center" Margin="123,12,128,0" Name="label1" VerticalAlignment="Top" Width="293" /> </Grid> </Window>
Εδώ αξίζει να σημειώσουμε πως η ιδιότητα cliptobounds στο control όταν είναι αληθείς (true), μας εξασφαλίζει πως η εικόνα που εμπεριέχεται μέσα σε αυτό το control, δεν θα επικαλύψει άλλα σημεία του παραθύρου και θα κινηθεί αυστηρά μέσα στα πλαίσια αυτού.
Το αποτέλεσμα του παραπάνω κώδικα είναι αυτό:
WPF εφαρμογή διαχείρισης εικόνων: Χτίσιμο κώδικα C#.
Δημιουργήσαμε αρκετά events που θα ενεργοποιούνται όταν ο κέρσορας του ποντικιού θα βρίσκεται μέσα στα όρια της αρχικής εικόνας.
WPFWindow.MouseWheel += MainWindow_MouseWheel; image.MouseLeftButtonDown += image_MouseLeftButtonDown; image.MouseLeftButtonUp += image_MouseLeftButtonUp; image.MouseMove += image_MouseMove;
Έπειτα ορίσαμε 2 global μεταβλητές που θα κρατάνε την θέση του κέρσορα πάνω στην εικόνα όταν το αριστερό κουμπί του ποντικιού πατηθεί για πρώτη φορά.
private Point origin; // Original Offset of image private Point start; // Original Position of the mouse
Το παρακάτω event, που ενεργοποιείται όταν πατηθεί το αριστερό κουμπί από το ποντίκι, ορίζει το περιεχόμενο των παραπάνω μεταβλητών.
private void image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { if (image.IsMouseCaptured) return; image.CaptureMouse(); start = e.GetPosition(border); origin.X = image.RenderTransform.Value.OffsetX; origin.Y = image.RenderTransform.Value.OffsetY; }
Το παρακάτω event, που ενεργοποιείται κατά την κίνηση του ποντικιού πάνω στην εικόνα, αναλαμβάνει την μετακίνηση της εικόνας καθώς μετακινούμε το ποντίκι.
private void image_MouseMove(object sender, MouseEventArgs e) { if (!image.IsMouseCaptured) return; Point p = e.MouseDevice.GetPosition(border); Matrix m = image.RenderTransform.Value; m.OffsetX = origin.X + (p.X - start.X); m.OffsetY = origin.Y + (p.Y - start.Y); image.RenderTransform = new MatrixTransform(m); }
Το παρακάτω event, που ενεργοποιείται όταν κινηθεί η ροδέλα του ποντικιού και ο κέρσορας βρίσκεται μέσα στα όρια της εικόνας, αναλαμβάνει την μεγέθυνση-σμίκρυνσή της εικόνας. Παράλληλα αυτό το event χρησιμοποιεί την μέθοδο ScaleAtPrepend έτσι ώστε, όχι μόνο να μεγενθύνει αλλά να κράτα και την εστίαση στο σημείο που μεγενθύνεται σταθερή.
private void MainWindow_MouseWheel(object sender, MouseWheelEventArgs e) { Point p = e.MouseDevice.GetPosition(image); Matrix m = image.RenderTransform.Value; if (e.Delta > 0) m.ScaleAtPrepend(1.1, 1.1, p.X, p.Y); else m.ScaleAtPrepend(1/1.1, 1/1.1, p.X, p.Y); image.RenderTransform = new MatrixTransform(m); }