Okay, it appears that you have a calculation error - one of the values may be
double.NAN[
^].
This code has the same problem and was not picked up by those that responded:
c# - Crop Image using Canvas Rectangle - Stack Overflow[
^]
The problem is with these calculations:
rcFrom.X = (int)((rect1.X) * (image1.Source.Width) /(image1.Width));
rcFrom.Y = (int)((rect1.Y) *(image1.Source.Height) / (image1.Height));
rcFrom.Width = (int)((rect1.Width) * (image1.Source.Width) /(image1.Width));
rcFrom.Height = (int)((rect1.Height) * (image1.Source.Height) /(image1.Height));
Testing & debugging has shown that
image1.Height
and
image1.Width
are returning
double.NAN
properties. What they should be using is
image1.ActualHeight
and
Actualimage1.Width
properties.
Here is a corrected working version of the code (above link in this solution) working with an image size of 3840 x 2160 jpeg image:
XAML MainWindow:
<Window
x:Class="WpfCropImage.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
mc:Ignorable="d"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="CodeProject Answer - WPF Scale & Crop Images"
Height="600" Width="1200" WindowStartupLocation="CenterScreen">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid x:Name="Gridimage1">
<Image Name="image1" Stretch="Uniform"
Source="http://eskipaper.com/images/cool-morning-fog-wallpaper-1.jpg"/>
<Canvas x:Name="BackPanel"
Height="{Binding ElementName=image1, Path=ActualHeight}"
Width="{Binding ElementName=image1, Path=ActualWidth}">
<Rectangle x:Name="selectionRectangle"
Stroke="LightBlue" Fill="#220000FF" Visibility="Collapsed" />
</Canvas>
</Grid>
<Button Content=">>" Grid.Column="1" Name="Go"
Click="Go_Click" FontWeight="Bold"
VerticalAlignment="Center" Margin="10"/>
<Image Grid.Column="2" Name="image2" Stretch="Uniform" />
</Grid>
</Window>
And the MainWindow code-behind:
UPDATE Aug 16, 2017: The new sample image showed that the scaling calculation was incorrect. Below code has the correction.
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Imaging;
namespace WpfCropImage
{
public partial class MainWindow : Window
{
private bool isDragging;
private Point anchorPoint = new Point();
public MainWindow()
{
InitializeComponent();
Gridimage1.MouseLeftButtonDown += new MouseButtonEventHandler(image1_MouseLeftButtonDown);
Gridimage1.MouseMove += new MouseEventHandler(image1_MouseMove);
Gridimage1.MouseLeftButtonUp += new MouseButtonEventHandler(image1_MouseLeftButtonUp);
Go.IsEnabled = false;
image2.Source = null;
}
private void Go_Click(object sender, RoutedEventArgs e)
{
if (image1.Source != null)
{
var rect1 = new Rect()
{
X = Canvas.GetLeft(selectionRectangle),
Y = Canvas.GetTop(selectionRectangle),
Width = selectionRectangle.Width,
Height = selectionRectangle.Height
};
var img = image1.Source as BitmapSource;
var scaleWidth = (img.PixelWidth) / (image1.ActualWidth);
var scaleHeight = (img.PixelHeight) / (image1.ActualHeight);
var rcFrom = new Int32Rect()
{
X = (int)(rect1.X * scaleWidth),
Y = (int)(rect1.Y * scaleHeight),
Width = (int)(rect1.Width * scaleWidth),
Height = (int)(rect1.Height * scaleHeight)
};
image2.Source = new CroppedBitmap(inputImage, rcFrom);
}
}
#region "Mouse events"
private void image1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (!isDragging)
{
anchorPoint.X = e.GetPosition(BackPanel).X;
anchorPoint.Y = e.GetPosition(BackPanel).Y;
isDragging = true;
}
}
private void image1_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging)
{
double x = e.GetPosition(BackPanel).X;
double y = e.GetPosition(BackPanel).Y;
selectionRectangle.SetValue(Canvas.LeftProperty, Math.Min(x, anchorPoint.X));
selectionRectangle.SetValue(Canvas.TopProperty, Math.Min(y, anchorPoint.Y));
selectionRectangle.Width = Math.Abs(x - anchorPoint.X);
selectionRectangle.Height = Math.Abs(y - anchorPoint.Y);
if (selectionRectangle.Visibility != Visibility.Visible)
selectionRectangle.Visibility = Visibility.Visible;
}
}
private void image1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (isDragging)
{
isDragging = false;
if (selectionRectangle.Width > 0)
{
Go.Visibility = Visibility.Visible;
Go.IsEnabled = true;
}
if (selectionRectangle.Visibility != Visibility.Visible)
selectionRectangle.Visibility = Visibility.Visible;
}
}
private void RestRect()
{
selectionRectangle.Visibility = Visibility.Collapsed;
isDragging = false;
}
#endregion
}
}