2

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

Muckers Mate
  • 399
  • 8
  • 23
  • It could just be me, but your question seems to make little sense to me. For example: *Depending on a state variable, the DrawingVisual will extract from this big image, the current frame to show - hence the need to crop*... what? – Sheridan Jul 08 '14 at 10:59
  • Why do you call `_imageSource.Clone()` and assign `bm.BaseUri`? It should work with just `new CroppedBitmap(_imageSource, ...)`. – Clemens Jul 08 '14 at 11:00
  • Where exactly is the exception thrown? Is it this line: `CroppedBitmap c = new CroppedBitmap(bm, new Int32Rect(0, 0, width, height));`? If yes, what are the values of `width` and `height` when the exception is thrown and what are the image's dimensions? –  Jul 08 '14 at 11:01
  • And why the ImageDrawing/DrawDrawing thing? Why not just call `dc.DrawImage`? This all seems unnecessary complicated. – Clemens Jul 08 '14 at 11:01
  • @Sheridan - The "State" will be the current frame within the animation. So it the imagesource represents 10 frames and the DrawingVisual is on frame (state) 9, then the 9th frame is cropped from the imageSource and shown. – Muckers Mate Jul 08 '14 at 11:12
  • @Clemens - CroppedImage takes a bitmap image as first parameter. I was originally passing "imageSource as bitmapimage", but this resulted in the same error. Regarding the dc.DrawImage, this drawing is meant to be of part of an extensive drawinggroup. I've removed all the other drawing for clarity - just showing my attempts at cropping – Muckers Mate Jul 08 '14 at 11:15
  • @Clemens - I've checked the dimensions and they are correct. Exception is thrown on the creation of the cropped image – Muckers Mate Jul 08 '14 at 11:16
  • When `_imageSource` contains your BitmapImage resource, the cast should work. Cloning is definitely not necessary. Why isn't `_imageSource` a `BitmapSource` anyway? – Clemens Jul 08 '14 at 11:19
  • @clemens. Changing imageSource to BitmapSource has made no difference. I've updated my main question with the exception details. – Muckers Mate Jul 08 '14 at 11:27

0 Answers0