none
problems with lumia imaging crop and save

    Question

  • I am using the Lumia Imaging SDK to create an image editor. I have all the filters working fine and I can save the image after a filter has been applied without issue. However, when I crop an image the cropped image (writeableBitmap) appears correct in the canvas but when I save I get black bars either top and bottom or left and right.

    I have been trying for days to come up with a way of doing this without the bars but nothing seems to work. If I debug the cropping method, the image, bitmap and canvas all stay the same size after cropping, I was expecting the writeable bitmap to have changed size.

    I am using this in a Windows Store app and not a Phone app.


    Mal

    • Moved by Jamles Hez Sunday, March 1, 2015 6:54 AM
    Tuesday, February 17, 2015 12:09 PM

Answers

  • Hi,

    Yes, there is a more general solution, I guess I should have given that right away. IImageProvider has a method GetInfoAsync that will return an ImageProviderInfo object, this has an ImageSize property that contains the infor you need to create a WriteableBitmap of the right size:

    // Get the "natural size" of the output image
    var imageInfo = await effect.GetInfoAsync();
    var size = imageInfo.ImageSize;
    
    // Create a new WriteableBitmap
    var targetBitmap = new WriteableBitmap((int)size.width, (int)size.height);
    
    // Render to the new bitmap
    var writableBitmapRenderer = new WriteableBitmapRenderer(effect, targetBitmap);
    await writableBitmapRenderer.RenderAsync();
    
    DoSomethingWith(targetBitmap);

    Regards,

    Jonas

    • Marked as answer by MalBall Monday, March 2, 2015 9:02 AM
    Monday, March 2, 2015 8:44 AM

All replies

  • Can you post the code you are using to Crop the Image?

    Are you using the CropFilter or ReframingFilter?

    Tuesday, February 17, 2015 2:36 PM
  • Using the crop filter as follows:

                        double left = vm.selectedRegion.SelectedRect.Left;
                        double top = vm.selectedRegion.SelectedRect.Top;
                        double width = vm.selectedRegion.SelectedRect.Width;
                        double height = vm.selectedRegion.SelectedRect.Height;
                        Rect rec = new Rect(left, top, width, height);
    
                        filterlist.Add(new Lumia.Imaging.Transforms.CropFilter(rec));
                        effect.Filters = filterlist;
                        writableBitmapRenderer = new WriteableBitmapRenderer(effect, writableBitmap);
                        await writableBitmapRenderer.RenderAsync();
                        writableBitmap.Invalidate();
    If there is a better way using the Reframing Filter then I am up for that


    Mal

    Tuesday, February 17, 2015 2:40 PM
  • Hi Mal,

    When you render to a WriteableBitmap, the content is scaled to fit the target bitmap. You can control how this is done by setting OutputOption to PreserveAspectRatio or Stretch. If PreserveAspectRatio, the default, is used, then black bands will appear if the aspect ratio of the content doesn't match that of the bitmap. The only way to get around this is to pass in a WriteableBitmap with the aspect ratio you want to the renderer.

    Regards,

    Jonas

    Thursday, February 26, 2015 7:57 AM
  • Thanks for the reply, still not sure how to proceed with this, I tried adding OutputOption line but still saves with the black bands.

    My code is in the original posting above, is it something here I should be doing or in my save code?

                        double left = vm.selectedRegion.SelectedRect.Left;
                        double top = vm.selectedRegion.SelectedRect.Top;
                        double width = vm.selectedRegion.SelectedRect.Width;
                        double height = vm.selectedRegion.SelectedRect.Height;
    
                        Rect rec = new Rect(left, top, width, height);
    
                        filterlist.Add(new Lumia.Imaging.Transforms.CropFilter(rec));
                        effect.Filters = filterlist;
                        writableBitmapRenderer.OutputOption = OutputOption.Stretch;
                        writableBitmapRenderer = new WriteableBitmapRenderer(effect, writableBitmap);
                        await writableBitmapRenderer.RenderAsync();
                        writableBitmap.Invalidate();


    Mal

    Thursday, February 26, 2015 11:21 AM
  • If you use the Stretch option, you should see the cropped content stretched to fit the bitmap, which means the image will be deformed. To maintain correct aspect ratio after the crop and not get black bands, you have to create a new WriteableBitmap with the desired dimensions and give that to the WriteableBitmapRenderer. It's not possible to resize a WriteableBitmap.

    Regards,

    Jonas

    Thursday, February 26, 2015 1:14 PM
  • Sorry to sound so dumb, its not a subject I have a lot of experience with. If I create a new Writeable bitmap with the new width and height it would be empty wouldn't it. Are you saying I should clone the existing one then use that?

    Mal

    Thursday, February 26, 2015 2:20 PM
  • No cloning, you need to create a new WriteableBitmap with the desired size, then render into that:

    double left = vm.selectedRegion.SelectedRect.Left; double top = vm.selectedRegion.SelectedRect.Top; double width = vm.selectedRegion.SelectedRect.Width; double height = vm.selectedRegion.SelectedRect.Height; Rect rec = new Rect(left, top, width, height); filterlist.Add(new Lumia.Imaging.Transforms.CropFilter(rec)); effect.Filters = filterlist; // Create a new WriteableBitmap var targetBitmap = new WriteableBitmap((int)width, (int)height); // Render to the new bitmap var writableBitmapRenderer = new WriteableBitmapRenderer(effect, targetBitmap); await writableBitmapRenderer.RenderAsync(); DoSomethingWith(targetBitmap);

    Regards,

    Jonas


    Friday, February 27, 2015 9:36 AM
  • Thanks Jonas that seems to have done the trick for cropped images, how about rotated images?

    I have tried the same method but keeps giving the black bars, I suspect its the new writeable bitmap size. I am unsure what I should be doing to get the right size because the orientation doesn't change until after the filter is applied therefore I cant create a new writeable bitmap.

    So if I rotate a landscape image by 90 degrees, it then ends up in portrait, do you know how I should approach that?


    Mal

    Friday, February 27, 2015 5:11 PM
  • Hi,

    Yes, there is a more general solution, I guess I should have given that right away. IImageProvider has a method GetInfoAsync that will return an ImageProviderInfo object, this has an ImageSize property that contains the infor you need to create a WriteableBitmap of the right size:

    // Get the "natural size" of the output image
    var imageInfo = await effect.GetInfoAsync();
    var size = imageInfo.ImageSize;
    
    // Create a new WriteableBitmap
    var targetBitmap = new WriteableBitmap((int)size.width, (int)size.height);
    
    // Render to the new bitmap
    var writableBitmapRenderer = new WriteableBitmapRenderer(effect, targetBitmap);
    await writableBitmapRenderer.RenderAsync();
    
    DoSomethingWith(targetBitmap);

    Regards,

    Jonas

    • Marked as answer by MalBall Monday, March 2, 2015 9:02 AM
    Monday, March 2, 2015 8:44 AM
  • Yes that's done the trick, thanks for all your help on this

    Mal

    Monday, March 2, 2015 9:02 AM