I need to display a cropped region of an image source within a DrawingVisual, but for the past few hours I've just drawn blanks for what should be a simple task.
My plan is to implement timed animation (for a HMI system) which will take a big image containing various frames. Depending on a state variable, the DrawingVisual will extract from this big image, the current frame to show - hence the need to crop.
My code stands as follows:
int width = Convert.ToInt32(_imageSource.Width / 2);
int height = Convert.ToInt32(_imageSource.Height);
BitmapImage bm = _imageSource.Clone() as BitmapImage;
bm.BaseUri = BaseUriHelper.GetBaseUri(this);
CroppedBitmap c = new CroppedBitmap(bm, new Int32Rect(0, 0, width, height));
ImageDrawing id = new ImageDrawing(c, new Rect(0, 0, width, height));
dg.Children.Add(id);
dc.DrawDrawing(dg);
However, upon creating the cropped image, I receive
"value does not fall within expected range"
BTW The image is a png loaded within a resource dictionary (in the current assembly) as
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<BitmapImage x:Key="elbowSmallBlueBL" UriSource="./Assets/HMI/Elbows/Small/Elbow Blue BottomLeft.png" />
and then assigned to the DrawingVisual using (ImageSource)FindResource("...
Firstly I don't understand the error message and can't find an satisfactory explanation anywhere and secondly, why is it sooooo difficult to perform a simple task?
Thanks for any help.
p.s. I think this due to not being able to locate the resource. But if the original imagesource is fine why would the cloned version behave any differently? p.p.s Removing the line "bm.BaseUri = ..." results in same error.
To simplify things, I've created a test project that only has a button which attempts to create CroppedBitmap when clicked.
The button click =
private void Button_Click(object sender, RoutedEventArgs e)
{
BitmapSource i = (BitmapSource)FindResource("elbowSmallBlueBL");
try
{
CroppedBitmap c = new CroppedBitmap(i, new Int32Rect(0, 0, 100, 100));
}
catch (Exception ex)
{
}
}
}
The resource dictionary references the bitmap :
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- Elbows -->
<BitmapImage x:Key="elbowSmallBlueBL" UriSource="./Assets/HMI/Elbows/Small/Elbow Blue BottomLeft.png" />
and included the App.xaml
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="rdHMIControls.xaml" />
The BitmapSource (i) is valid and the call to CroppedBitmap throws the ArgumentException, "Value does not fall within the accepted range".
Creating, or trying to create a cropped image surely can't be any simpler than this?
Another example which I've taken off MSDN
BitmapSource i = (BitmapSource)this.FindResource("test");
try
{
// Create an Image element.
Image croppedImage = new Image();
croppedImage.Width = 200;
croppedImage.Margin = new Thickness(5);
// Create a CroppedBitmap based off of a xaml defined resource.
CroppedBitmap cb = new CroppedBitmap(
i,
new Int32Rect(30, 20, 105, 50)); //select region rect
croppedImage.Source = cb; //set image source to cropped
Again new CroppedBitmap throws InvalidArgument exceptin
Any thoughts?
Thanks