I have an image rendered big and need a zoomed section of what's under user cursor.
My image is inside a Grid and is defined in XAML this way:
<Grid x:Name="RootImgGrid" Background="#FF333333" >
<Viewbox x:Name="imgViewBox" Margin="1,1,1,1" Stretch="Fill" >
<Canvas x:Name="imgCanvas" ClipToBounds="True" Width="{Binding ElementName=RootImgGrid, Path=ActualWidth}" Height="{Binding ElementName=RootImgGrid, Path=ActualHeight}">
<Image x:Name="imgObj" MouseWheel="img_MouseWheel" Cursor="Hand" MouseMove="Img_MouseMove" MouseDown="Img_MouseDown" MouseUp="Img_MouseUp" >
<Image.RenderTransform>
<TransformGroup x:Name="imgTransformGroup">
<ScaleTransform x:Name="imgScaleTransform"></ScaleTransform>
<TranslateTransform x:Name="imgTranslateTransform"></TranslateTransform>
</TransformGroup>
</Image.RenderTransform>
<Image.LayoutTransform>
<RotateTransform x:Name="imgRotateTransform"></RotateTransform>
</Image.LayoutTransform>
</Image>
</Canvas>
</Viewbox>
</Grid>
And I have a zoomed area where should appear the image under my cursor zoomed 2x.
<Viewbox x:Name="imgViewBoxMagnifier" Width="400" Height="90">
<Canvas x:Name="imgCanvasMagnifier" Width="400" Height="90">
<Canvas.Clip>
<RectangleGeometry Rect="0,0,400,90" />
</Canvas.Clip>
<Image x:Name="imgMagnifier" Margin="2" Width="400" Height="90">
<Image.RenderTransform>
<TransformGroup x:Name="imgMagnifierTransformGroup">
<ScaleTransform x:Name="imgMagnifierScaleTransform"></ScaleTransform>
<TranslateTransform x:Name="imgMagnifierTranslateTransform"></TranslateTransform>
</TransformGroup>
</Image.RenderTransform>
<Image.LayoutTransform>
<RotateTransform x:Name="imgMagnifierRotateTransform"></RotateTransform>
</Image.LayoutTransform>
</Image>
</Canvas>
</Viewbox>
Now, in my .CS code I've got the function that should show the zoomed image:
public void Magnifier(Canvas imgCanvas, Image imgObject, Image imgMagnifier, MouseEventArgs e)
{
Int32 width = 400;
Int32 height = 90;
if (imgMagnifier.Source != imgObject.Source)
{
imgMagnifier.Source = imgObject.Source;
}
Size size = imgObject.RenderSize;
RotateTransform rt = (RotateTransform)imgObject.LayoutTransform;
TranslateTransform tt = (TranslateTransform)((TransformGroup)imgObject.RenderTransform).Children[1];
ScaleTransform st = (ScaleTransform)((System.Windows.Media.TransformGroup)(imgObject.RenderTransform)).Children[0];
Double x = e.GetPosition(imgCanvas).X - tt.X;
Double y = e.GetPosition(imgCanvas).Y - tt.Y;
Point pos = e.MouseDevice.GetPosition(imgCanvas);
TransformGroup transformGroup = new TransformGroup();
ScaleTransform scale = new ScaleTransform();
scale.CenterX = x;
scale.CenterY = y;
scale.ScaleX = st.ScaleX * 10;
scale.ScaleY = st.ScaleY * 10;
transformGroup.Children.Add(scale);
TranslateTransform translate = new TranslateTransform();
translate.X = ??????????????????;
translate.Y = ??????????????????;
transformGroup.Children.Add(translate);
imgMagnifier.RenderTransform = transformGroup;
}
How can I find the correct value of those "????????"
translate.X = -x * 10 / (size.Width / 400);
translate.Y = -y * 10 / (size.Height / 90);
It shows the correct image, zoomed, but it doesn't show the image area under my cursor.
Thanks in advance.
Since I didn't find any packed solution, I've developed from scratch a fully functional Microsoft VS 2010 Project Magnifier Zoom C# 4.0 WPF.
It includes zoom in, zoom out, rotate, fit to width and the magnified area.
Feel free to download, and make it even better.
Hope you enjoy. Vote up if you find it useful.
public void Magnifier(Canvas imgCanvas, Image imgObject, Canvas imgCanvasMagnifier, Image imgMagnifier, MouseEventArgs e)
{
Double width = imgCanvasMagnifier.Width;
Double height = imgCanvasMagnifier.Height;
Int32 zoom = 3;
String txtDebug = String.Empty;
String txtZoom = String.Empty;
if (imgMagnifier.Source != imgObject.Source)
{
imgMagnifier.Source = imgObject.Source;
}
Size size = imgObject.RenderSize;
RotateTransform rt = (RotateTransform)imgObject.LayoutTransform;
TranslateTransform tt = (TranslateTransform)((TransformGroup)imgObject.RenderTransform).Children[1];
ScaleTransform st = (ScaleTransform)((System.Windows.Media.TransformGroup)(imgObject.RenderTransform)).Children[0];
Double x = e.GetPosition(imgCanvas).X - tt.X;
Double y = e.GetPosition(imgCanvas).Y - tt.Y;
Point pos = e.MouseDevice.GetPosition(imgCanvas);
var wnd = Canvas.GetTop(imgObject);
TransformGroup transformGroup = new TransformGroup();
ScaleTransform scale = new ScaleTransform();
scale.ScaleX = st.ScaleX * zoom;
scale.ScaleY = st.ScaleY * zoom;
RotateTransform rotate = new RotateTransform();
rotate.Angle = rt.Angle;
TranslateTransform translate = new TranslateTransform();
Double centerX = st.CenterX * (st.ScaleX - 1);
Double centerY = st.CenterY * (st.ScaleY - 1);
if (rt.Angle == 0)
{
translate.X = -(x + centerX) / st.ScaleX;
translate.Y = -(y + centerY) / st.ScaleY;
scale.CenterX = (x + centerX) / st.ScaleX;
scale.CenterY = (y + centerY) / st.ScaleY;
}
if (rt.Angle == 90)
{
translate.X = -(x + centerX) / st.ScaleX;
translate.Y = -(y + centerY) / st.ScaleY;
translate.X += imgObject.ActualHeight * st.ScaleX * zoom;
scale.CenterX = (x + centerX) / st.ScaleX;
scale.CenterY = (y + centerY) / st.ScaleY;
}
if (rt.Angle == 180)
{
translate.X = -(x + centerX) / st.ScaleX;
translate.Y = -(y + centerY) / st.ScaleY;
translate.X += imgObject.ActualWidth * st.ScaleX * zoom;
translate.Y += imgObject.ActualHeight * st.ScaleY * zoom;
scale.CenterX = (x + centerX) / st.ScaleX;
scale.CenterY = (y + centerY) / st.ScaleY;
}
if (rt.Angle == 270)
{
translate.X = -(x + centerX) / st.ScaleX;
translate.Y = -(y + centerY) / st.ScaleY;
translate.Y += imgObject.ActualWidth * st.ScaleX * zoom;
scale.CenterX = (x + centerX) / st.ScaleX;
scale.CenterY = (y + centerY) / st.ScaleY;
}
translate.X += width / 2;
translate.Y += height / 2;
transformGroup.Children.Add(rotate);
transformGroup.Children.Add(scale);
transformGroup.Children.Add(translate);
imgMagnifier.RenderTransform = transformGroup;
}