none
Cropping 2 images

    Question

  • Hello! I saw a lot of posts like that, but i can't solce my problem :(

    My app shoud load a photo from the camera and put it into a 450*600 Image (called imgOrig).

    After that, the app should create 2 little images cropped from imgOrig like these 2 red squares:

    I can't solce this boring problem... Every piece of code i write doesn't work... Can you help me please?

    I wrote this:

    img1.Clip = new RectangleGeometry() { Rect = new Rect(0, 0, 150, 150) }; img2.Clip = new RectangleGeometry() { Rect = new Rect(150, 0, 150, 150) };

    The first instruction works fine. The second shows nothing.

    Both of them had a width and height of 150px and a Source property set on imgOrig.Source

    Can anyone help me? I'm crying :(

    Thank you and sorry for my bad english... Greets from Italy :)

    Sergio

    Sunday, June 03, 2012 1:18 PM

Answers

  • Hi Sergio,

    Your app can load a cropped version of the bitmap from the StorageFile returned by the CameraCaptureUI by opening the file into a stream and then running it through a BitmapDecoder with a BitmapTransform set to crop to the 150x150 sub-images:

                IRandomAccessStream stream = await img.OpenReadAsync();
                // Set the original full sized image
                BitmapImage bmp = new BitmapImage();
                bmp.SetSource(stream);
                originalImage.Source = bmp;
    
                // Go back to the beginning and set up a bitmapDecoder
                stream.Seek(0);
                BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
                
                // With our cropping BitmapTransform
                BitmapTransform transform = new BitmapTransform();
                BitmapBounds bounds = new BitmapBounds();
                bounds.X = bounds.Y = 0;
                bounds.Height = bounds.Width = 150;
                transform.Bounds = bounds;
    
                // Get the cropped pixels
                PixelDataProvider pix = await decoder.GetPixelDataAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, transform, ExifOrientationMode.RespectExifOrientation, ColorManagementMode.ColorManageToSRgb);
                byte[] pixels = pix.DetachPixelData();
    
                // And stream them into a WriteableBitmap
                WriteableBitmap cropBmp = new WriteableBitmap(150, 150);
                Stream pixStream = cropBmp.PixelBuffer.AsStream();
                pixStream.Write(pixels, 0, 150 * 150 * 4);
                // Which we set on our first cropped Image
                crop1.Source = cropBmp;
    
                // Then move the crop to the second location
                bounds.X = 150;
                transform.Bounds = bounds;
    
                // And decode again
                pix = await decoder.GetPixelDataAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, transform, ExifOrientationMode.RespectExifOrientation, ColorManagementMode.ColorManageToSRgb);
                pixels = pix.DetachPixelData();
                cropBmp = new WriteableBitmap(150, 150);
                pixStream = cropBmp.PixelBuffer.AsStream();
                pixStream.Write(pixels, 0, 150 * 150 * 4);
               
                // Then set to the second cropped image
                crop2.Source = cropBmp;

    --Rob
    Tuesday, June 05, 2012 12:25 AM
    Owner
  • Hi Sergio,

    AsStream is an extension method, so you need to include the appropriate "using" statement:

    using System.Runtime.InteropServices.WindowsRuntime;
    

    You can figure this out by going to the object browser, searching on AsStream, and looking to see which namespace it is defined in.

    --Rob

    • Marked as answer by supermelo Tuesday, June 05, 2012 10:45 PM
    Tuesday, June 05, 2012 8:40 PM
    Owner

All replies

  • Hi Sergio,

    Your app can load a cropped version of the bitmap from the StorageFile returned by the CameraCaptureUI by opening the file into a stream and then running it through a BitmapDecoder with a BitmapTransform set to crop to the 150x150 sub-images:

                IRandomAccessStream stream = await img.OpenReadAsync();
                // Set the original full sized image
                BitmapImage bmp = new BitmapImage();
                bmp.SetSource(stream);
                originalImage.Source = bmp;
    
                // Go back to the beginning and set up a bitmapDecoder
                stream.Seek(0);
                BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
                
                // With our cropping BitmapTransform
                BitmapTransform transform = new BitmapTransform();
                BitmapBounds bounds = new BitmapBounds();
                bounds.X = bounds.Y = 0;
                bounds.Height = bounds.Width = 150;
                transform.Bounds = bounds;
    
                // Get the cropped pixels
                PixelDataProvider pix = await decoder.GetPixelDataAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, transform, ExifOrientationMode.RespectExifOrientation, ColorManagementMode.ColorManageToSRgb);
                byte[] pixels = pix.DetachPixelData();
    
                // And stream them into a WriteableBitmap
                WriteableBitmap cropBmp = new WriteableBitmap(150, 150);
                Stream pixStream = cropBmp.PixelBuffer.AsStream();
                pixStream.Write(pixels, 0, 150 * 150 * 4);
                // Which we set on our first cropped Image
                crop1.Source = cropBmp;
    
                // Then move the crop to the second location
                bounds.X = 150;
                transform.Bounds = bounds;
    
                // And decode again
                pix = await decoder.GetPixelDataAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, transform, ExifOrientationMode.RespectExifOrientation, ColorManagementMode.ColorManageToSRgb);
                pixels = pix.DetachPixelData();
                cropBmp = new WriteableBitmap(150, 150);
                pixStream = cropBmp.PixelBuffer.AsStream();
                pixStream.Write(pixels, 0, 150 * 150 * 4);
               
                // Then set to the second cropped image
                crop2.Source = cropBmp;

    --Rob
    Tuesday, June 05, 2012 12:25 AM
    Owner
  • Hi Rob!

    First, i would like to thank you for your answer and the time you spend on my problem :) You're great! However, I copied your code, but Visual Studio returned me 2 errors...

    Error 1 'Windows.Storage.Streams.IBuffer' does not contain a definition for 'AsStream' and the best extension method overload 'System.IO.WindowsRuntimeStreamExtensions.AsStream(Windows.Storage.Streams.IRandomAccessStream)' has some invalid arguments C:\Users\Sergio\Desktop\MyApp\MyApp\MainPage.xaml.cs 98 36 MyApp

    Error 2 'Windows.Storage.Streams.IBuffer' does not contain a definition for 'AsStream' and the best extension method overload 'System.IO.WindowsRuntimeStreamExtensions.AsStream(Windows.Storage.Streams.IRandomAccessStream)' has some invalid arguments C:\Users\Sergio\Desktop\MyApp\MyApp\MainPage.xaml.cs 111 29 MyApp

    The error is under

    Stream pixStream = cropBmp.PixelBuffer.AsStream();

    and

     pixStream = cropBmp.PixelBuffer.AsStream();

    instructions.

    Any ideas?

    Thank you very much!

    Sergio


    Sergio Meloni

    Tuesday, June 05, 2012 7:07 PM
  • Hi Sergio,

    AsStream is an extension method, so you need to include the appropriate "using" statement:

    using System.Runtime.InteropServices.WindowsRuntime;
    

    You can figure this out by going to the object browser, searching on AsStream, and looking to see which namespace it is defined in.

    --Rob

    • Marked as answer by supermelo Tuesday, June 05, 2012 10:45 PM
    Tuesday, June 05, 2012 8:40 PM
    Owner
  • OMG, You saved my work! If I'll ever come to USA, I absolutely have to offer you a coffee!!

    Thank you very much!

    Sergio


    Sergio Meloni

    Tuesday, June 05, 2012 10:44 PM