Rotate a picture.

Windows Photos application allows a user to rotate an image and save a copy to a local storage. How would you implement the same functionality in your app?

There are two approaches:

  1. We can get a raw pixel data of a picture and then rotate the array of bytes;
  2. Universal Windows Platform has API, which helps to solve this task.

Let’s take a look at both of them.

Access a raw pixel data.

To access a pixel data we have to utilize a chain of objects. First of all, we need to decode an input image data with an instance of BitmapDecoder. From BitmapDecoder, we can get an instance of PixelDataProvider. And then, use PixelDataProvider.DetachPixelData to get an array of pixel data.

The code bellow demonstrates how to do it:

Rotate a pixel data clockwise.

A picture rotation implies rotation of a two-dimensional matrix. Such kind of a transformation means that columns of an input array are converted to rows of an output array and rows of the input becomes columns of the output. Taking that in account, we can express the logic of a matrix transformation in the following code:

I set variable output to a two-dimensional array of int and used number of columns as number of rows for the output. I’m using a row index of the output array to access columns of the input array. And index of an input row can be calculated from an output column index.

When dealing with a picture, we have a one-dimensional array of a pixel data and a pixel length typically is 4 bytes. The algorithm to rotate a one-dimensional array has 3 steps:

  1. Calculate row and column indexes of a two-dimensional matrix from an index of an input array;
  2. Calculate rotated row and column indexes;
  3. Use the values calculated at the step 2 and convert them to one-dimensional index.

I wrapped it up in RotateClockwise method:

The method takes pixel data and size of a picture. When rotated row and column indexes are calculated, I’m traversing a nested loop to copy values from an input pixel to a rotated pixel. By rotated pixel, I mean a pixel from the rotated matrix.

Save an image.

Now, we can save transformed matrix to a local storage. BitmapEncoder can help us with that. I call a staic method BitmapEncoder.CreateForTranscodingAsync to create an instance of encoderAnd afterwards I use BitmapEncoder.SetPixelData and BitmapEncoder.FlushAsync to apply a pixel data and save the result.

The height of the original image should be used as a value for width parameter and the width for height parameter when calling SetPixelData

Rotate using BitmapTransform.

The described approach of a rotation gives us basic understanding of simple transformations that can be applied on a bitmap. But in a real project we don’t need to manipulate with pixels. BitmapTransform class has a set of properties, which can modify a picture depending on our needs. I updated SaveRotateAsync to use BitmapTransform to achieve the desired result:

We can not only rotate, but flip and scale with the help of an instance of BitmapTransform class.

Wish you fruitful coding!

Leave a Reply