Image Preview Window in WPF (Windows Presentation Foundation)
In some of my WPF developments, I create image previews using the Transform class and its derived classes. In this article, I'm going to talk about how to easily develop an image preview that allows zooming in, zooming out, rotating, and moving with the mouse pointer.
What is Transform class ?
The Transform class serves as an abstract base class in the graphics and rendering subsystem. In this case, I'm going to use four of transformations classes.
Let's discuss how to use above Classes along with image preview example.
Create Window Structure
We need an Image element to load the Image
<Image x:Name="ImgPreview" Stretch="Fill"/>
There are two ways to load image to a image element
<Image x:Name="ImgPreview" Source="YourImagePath.jpg" Stretch="Fill"/>
2. load from the code
Uri imagePath = new Uri("YourImagePath.jpg", UriKind.RelativeOrAbsolute);
ImgPreview.Source = new BitmapImage(imagePath);
We want Three buttons to Control the zooming in, zooming out and rotating.
<!--button panel-->
<!--zoom in-->
<Button x:Name="BtnZoomIn" Margin="5" Width="60" Height="60" Click="BtnZoomIn_Click"/>
<!--zoom out-->
<Button x:Name="BtnZoomOut" Margin="5" Width="60" Height="60" Click="BtnZoomOut_Click"/>
<!--rotate-->
<Button x:Name="BtnRotate" Margin="5" Width="60" Height="60" Click="BtnRotate_Click"/>
We want to mouse events to move the Image
<Image x:Name="ImgPreview" Stretch="Fill" MouseMove="ImgPreview_MouseMove" MouseLeftButtonDown="ImgPreview_MouseLeftButtonDown" MouseLeftButtonUp="ImgPreview_MouseLeftButtonUp"/>
Only consider the names of the above elements. You can decorate those you want.
Recommended by LinkedIn
Now, Lets implement the Code.
// When the window is loaded, lets initializes transformation objects
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// Initialize a TransformGroup to combine multiple transformations
TransformGroup transformGroup = new TransformGroup();
// Create individual transformations
ScaleTransform scaleTransform = new ScaleTransform();
RotateTransform rotateTransform = new RotateTransform();
TranslateTransform translateTransform = new TranslateTransform();
// Add individual transformations to the TransformGroup
transformGroup.Children.Add(scaleTransform);
transformGroup.Children.Add(rotateTransform);
transformGroup.Children.Add(translateTransform);
// Assign the TransformGroup to the ImgPreview element
ImgPreview.RenderTransform = transformGroup;
}
As above code shows, first we want to initialize a TransformGroup to combine multiple transformations. Then initialize individual transformation objects of ScaleTransform, RotateTransform and TranslateTransform and add to the TransformGroup. Finally assign the TransformGroup to the ImgPreview element.
Zoom In using ScaleTransform object
private void BtnZoomIn_Click(object sender, RoutedEventArgs e)
{
try
{
if (ImgPreview.Source != null)
{
// Retrieve the ScaleTransform from the RenderTransform of ImgPreview
var transform = (ScaleTransform)((TransformGroup)ImgPreview.RenderTransform).Children.First(c => c is ScaleTransform);
transform.ScaleX += 0.2;
transform.ScaleY += 0.2;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Increase the scale factors by 0.2 for both X and Y axes. You can change the factor as you wish.
Zoom Out using ScaleTransform object
private void BtnZoomOut_Click(object sender, RoutedEventArgs e)
{
try
{
if (ImgPreview.Source != null)
{
// Retrieve the ScaleTransform from the RenderTransform of ImgPreview
var transform = (ScaleTransform)((TransformGroup)ImgPreview.RenderTransform).Children.First(c => c is ScaleTransform);
transform.ScaleX -= 0.2;
transform.ScaleY -= 0.2;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Rotate using RotateTransform object
private void BtnRotate_Click(object sender, RoutedEventArgs e)
{
try
{
if (ImgPreview.Source != null)
{
//Retrieve the RotateTransform from the RenderTransform of ImgPreview
var transform = (RotateTransform)((TransformGroup)ImgPreview.RenderTransform).Children.First(c => c is RotateTransform);
//Calculate the center of ImgPreview to rotate around
double centerX = ImgPreview.ActualWidth / 2;
double centerY = ImgPreview.ActualHeight / 2;
//Set the center of rotation to the RotateTransform object
transform.CenterX = centerX;
transform.CenterY = centerY;
//Rotate the image by 90 degrees
transform.Angle += 90;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
You can change the transform.Angle as you wish and also the centre.
Image move with the mouse pointer.
//Move with mouse pointer
private Point origin;
private Point start;
private void ImgPreview_MouseMove(object sender, MouseEventArgs e)
{
try
{
if (ImgPreview.Source != null)
{
if (!ImgPreview.IsMouseCaptured) return;
//Retrieve the TranslateTransform from the RenderTransform of ImgPreview
var translateTransform = (TranslateTransform)((TransformGroup)ImgPreview.RenderTransform).Children.First(c => c is TranslateTransform);
//Only move inside the border
Vector v = start - e.GetPosition(border);
translateTransform.X = origin.X - v.X;
translateTransform.Y = origin.Y - v.Y;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void ImgPreview_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
ImgPreview.Cursor = Cursors.Hand;
try
{
if (ImgPreview.Source != null)
{
//Capture the mouse inside the image
ImgPreview.CaptureMouse();
//Retrieve the TranslateTransform from the RenderTransform of ImgPreview
var translateTransform = (TranslateTransform)((TransformGroup)ImgPreview.RenderTransform).Children.First(c => c is TranslateTransform);
//Record the starting position of the mouse click and the current translation
start = e.GetPosition(border);
origin = new Point(translateTransform.X, translateTransform.Y);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void ImgPreview_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
ImgPreview.Cursor = Cursors.Arrow;
try
{
if (ImgPreview.Source != null)
{
//Release the Image from the Mouse Pointer
ImgPreview.ReleaseMouseCapture();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Using the above codes makes it very easy to build an image preview for yourself also. Instead of using buttons for zooming in and out, you can also utilize left and right mouse clicks but the code remains the same.
I believe you could create an image preview using the above code. For further information, I have provided the GitHub repository of my project below. Feel free to use it if you like. Good Luck!
Thank you.
GitHub Repo :