1

Rotating an Image using

image.RenderTransform = new RotateTransform()...

is almost immediate. On the other hand, using

bitmapEncoder.BitmapTransform.Rotation = BitmapRotation.Clockwise90Degrees...

is much slower (in the FlushAsync()) - more than half a second.

Why is that? And is there a way to harness the fast rotation in order to rotate bitmaps?

ispiro
  • 26,556
  • 38
  • 136
  • 291

1 Answers1

5

The first one image.RenderTransform will render the bitmap by using hardware rendering. (GPU) The image isn't rotate but will be displayed rotated/scaled. (will access only visible pixels directly from/in the videomemory)

The second one will rotate the image itself by the CPU (all pixels). It will create new memory for the result. (non-video memory)


update:

Is there a way to use the GPU to edit bitmaps? Depends on what you need:

If you want to use a GPU. You could use an managed wrapper (like Slim DX/Sharp DX) This will take much time to get results. Don't forget, rerasterizing images via gpu could lead to quality lost.

If you want to rotate images only (0, 90, 180, 270)? you could use a Bitmap class with de ScanLine0 option. (this is to preserve quality and size) and you could create a fast implementation.

Look here: Fast work with Bitmaps in C#

I would create an algoritm foreach angle (0,90,180,270). Because you don't want to calculate the x, y position for each pixel. Something like below..


Tip:

try to lose the multiplies/divides.

/*This time we convert the IntPtr to a ptr*/
byte* scan0 = (byte*)bData.Scan0.ToPointer();

for (int i = 0; i < bData.Height; ++i)
{
    for (int j = 0; j < bData.Width; ++j)
    {
        byte* data = scan0 + i * bData.Stride + j * bitsPerPixel / 8;

        //data is a pointer to the first byte of the 3-byte color data
    }
}

Becomes something like:

/*This time we convert the IntPtr to a ptr*/
byte* scan0 = (byte*)bData.Scan0.ToPointer();

byte* data = scan0;

int bytesPerPixel = bitsPerPixel / 8;

for (int i = 0; i < bData.Height; ++i)
{
    byte* data2 = data;
    for (int j = 0; j < bData.Width; ++j)
    {
        //data2 is a pointer to the first byte of the 3-byte color data

        data2 += bytesPerPixel;
    }
    data += bData.Stride;
}
Community
  • 1
  • 1
Jeroen van Langen
  • 21,446
  • 3
  • 42
  • 57
  • Thanks. +1. If you have some docs for that that would be nice. More importantly: Is there a way to use the GPU to edit bitmaps? – ispiro Sep 05 '16 at 12:08
  • Those micro-optimizations aren't going to do much, if anything at all. Do not underestimate the compiler's optimizer. Always look at the compiler's output. And always do profile when applying any changes. – IInspectable Sep 05 '16 at 16:25
  • From my experience, there was a big difference between the execution times. I agree with, you should never pre-optimize code, because it could be less readable and takes more development time. – Jeroen van Langen Sep 05 '16 at 17:07
  • Thanks. Unfortunately UWP doesn't let us use Bitmaps, only similar objects. But I get the point. – ispiro Sep 05 '16 at 17:41