How to Crop an Image using the WriteableBitmap class?



Some time we need to crop an image uploaded by user in Silverlight or Windows Phone applications. Sometime we also need to do a rotate transform or skew transform to the image before saving it. So, how to achieve it?

 

This blog post will cover the code with details using the WriteableBitmap class that comes with the SDK. Continue reading to know more about it.

 

The WriteableBitmap class inherited from BitmapSource is present in the System.Windows.Media.Imaging namespace and provides the user a BitmapSource that can be written to and updated. Using this WriteableBitmap class, you can crop your images easily in your Silverlight or Windows Phone applications. Let’s write the code to implement the cropping functionality.

 

To crop an image, we will need an image source, the (x, y) co-ordinates of the image and the height & width of the cropped image. The API will crop the original image from the (x, y) co-ordinates to the dimension specified.

 

Here is the C# Code implementation:

 
private static WriteableBitmap CropImage(WriteableBitmap source, 
                                                         int xOffset, int yOffset, 
                                                         int width, int height)
{
    // Get the width of the source image
    var sourceWidth = source.PixelWidth;
 
    // Get the resultant image as WriteableBitmap with specified size
    var result = new WriteableBitmap(width, height);
 
    // Create the array of bytes
    for (var x = 0; x <= height - 1; x++)
    {
        var sourceIndex = xOffset + (yOffset + x) * sourceWidth;
        var destinationIndex = x * width;
 
        Array.Copy(source.Pixels, sourceIndex, result.Pixels, destinationIndex, width);
    }
    return result;
}

 

 

Here is the VB.Net Code implementation:

 
Private Shared Function CropImage(source As WriteableBitmap, 
                                  xOffset As Integer, yOffset As Integer,
                                  width As Integer, height As Integer) As WriteableBitmap
    ' Get the width of the source image
    Dim sourceWidth = source.PixelWidth
 
    ' Get the resultant image as WriteableBitmap with specified size
    Dim result = New WriteableBitmap(width, height)
 
    ' Create the array of bytes
    For x As var = 0 To height - 1
        Dim sourceIndex = xOffset + (yOffset + x) * sourceWidth
        Dim destinationIndex = x * width
 
        Array.Copy(source.Pixels, sourceIndex, result.Pixels, destinationIndex, width)
    Next
    Return result
End Function

 

 

The above code implementation will return you a cropped image based on the size specified. As it will return an WriteableBitmap instance, you can directly bind it to an image control or create image stream to save it in disk.

 

To know more about saving to an image stream, read this post: How to create Image Stream of XAML Page using Telerik’s ExportExtension method?

 

Now, we will need a XAML page to design our sample application where we will have two image controls and a button as shown below. You will be very easily able to create the XAML page and hence I am not sharing the whole code here.

 

Original Image

 

The sample application consists of one large image (Original Image) at the left side and one small image (Cropped Image will show here) at the right side. Our implementation will be to crop a specified dimension of the original image and show it at the second image control on click of the button control.

 

To do this, first we will need to create a WriteableBitmap instance from the original image control and in case we need to do an transform operation on top of the image, we need to specify here, else we can put a “null” as the second parameter to it. Then call the CropImage() method with the required parameters to get the crop version of the original image as shown below.

 

Here is the C# version of the Code implementation:

 
// Create an instance of WriteableBitmap from the original image.
// If you want to Skew or Rotate the cropped image, specify it as the second parameter.
// Just pass "null" if you want to use the original image directly.
var writeableBitmap = new WriteableBitmap(OriginalImage, null);
 
// Crop and set the new WriteableBitmap as the image source
CroppedImage.Source = CropImage(writeableBitmap, X, Y, WIDTH, HEIGHT);

 

Here is the VB.Net version of the Code implementation:

 
' Create an instance of WriteableBitmap from the original image.
' If you want to Skew or Rotate the cropped image, specify it as the second parameter.
' Just pass "null" if you want to use the original image directly.
Dim writeableBitmap = New WriteableBitmap(OriginalImage, Nothing)
 
' Crop and set the new WriteableBitmap as the image source
CroppedImage.Source = CropImage(writeableBitmap, X, Y, WIDTH, HEIGHT)

 

 

Now once you click the Crop button, you will notice that the second image at the right side has been changed with a cropped version of the image based on the size specified as the parameter to the CropImage() method. Here is the screenshot of the same:

 

After Crop Operation

 

I hope that, this post will help you to understand the use of WriteableBitmap and how to use this class to crop an image to specified dimension. If you have further queries on this, drop a line below and I will try to answer you as soon as I can.

 

In the mean time, don’t forget to connect with me on Twitter, Facebook and Google+. Also subscribe to my blog’s RSS Feed and Email Newsletter to get update on recently published articles directly delivered to your inbox. Cheers. Happy coding.

1 comments

  1. Hi
    Your sample seems to be good, but its not working for me, ie. writableImage is in windows.ui.xaml.imaging.

    I have a game and use what I call an image strip, a successive set of images used that I crop out and load into game objects as needed. So, then load each image into a byte buffer array. When a new object is created, set the source to one of the images in the array.

    I have recently loaded Win 8 and VS Express for doing App Store development. I cant seem to get this to work. Microsoft has moved and changed stuff so much that every example that I have found fails for one reason or another. I found one complete function in VB, but cant get the decoder coded correctly to pass it in as a parm. The Reversi sample does it, but it is in C# and uses MVVM.

    I have the code written in an older version of VB. There is a lot of code that I don't want to re-do in c#, or I guess MS is pushing javascript now.

    So, is there a chance that you can do a blog with this as the topic (or a link to a good sample). By the time you do it, hopefully I will have figured it out. Still, a lot of people want to do a game and there are still a lot of VB coders out there. This should be helpful.

    And include imports. Almost no one includes imports or using statements in the samples.

    Keith JunkCathcher@isildo.com


    ReplyDelete


 
© 2008-2014 Kunal-Chowdhury.com | Designed by Kunal Chowdhury
Back to top