Search code examples
bitmaptransformationdirect2d

Flip ID2D1Bitmap horizontally when redendering


I have a Direct2D ID2D1Bitmap that I display using ID2D1HwndRenderTarget::DrawBitmap(). I am trying to flip the image horizontally.

I read this article that explains how to flip an image that is read from a file, but I have ID2D1Bitmap.

I see references to using a IWICBitmapFlipRotator, but IWICBitmapFlipRotator::Initialize() takes a IWICBitmapSource rather than an ID2D1Bitmap. (I am pretty sure I had a WIC bitmap in a IWICFormatConverter when the image was first loaded, but I can't afford to save WIC objects for the ~100 images that are loaded. And I only need to flip images occasionally.)

I saw examples of using a transform matrix, which looks promising and would be an excellent option (I already apply a D2D1::Matrix3x2F::Rotation() transformation), however nothing appears on the display when I apply this transformation.

D2D1_MATRIX_3X2_F flip = D2D1::Matrix3x2F(-1, 0, 0, 1, 0, 0);
m_pTarget->SetTransform(flip);
m_pTarget->DrawBitmap(pBitmap, ...);

I've seen a few references to D2D1_ORIENTATION_FLIP_HORIZONTAL, but no examples of how to use it.

I'm obviously a Direct2D novice. Thanks for your assistance!

UPDATE: I discovered that the Matrix3x2F(-1, 0, 0, 1, 0, 0) code shown above does indeed horizontally flip (aka "mirror") the image when rendered. However, it also shifts the image to the left so it wasn't visible. To adjust for this, I also apply a Matrix3x2F::Translation(xShift, 0) to reposition the bitmap. I determine the xShift value via a convoluted (aka lame, bogus, embarrassing) formula that is based on the intended location of the bitmap and the bitmap's width. I'm sure there's a cleaner way to accommodate the required x-axis shift, but this solution worked.


Solution

  • I discovered that the Matrix3x2F(-1, 0, 0, 1, 0, 0) code shown above does indeed horizontally flip (aka "mirror") the image when rendered. However, it also shifts the image to the left so it wasn't visible. To adjust for this, I also apply a Matrix3x2F::Translation(xShift, 0) to reposition the bitmap. I determine the xShift value via a convoluted (aka lame, bogus, embarrassing) formula that is based on the intended location of the bitmap and the bitmap's width. I'm sure there's a cleaner way to accommodate the required x-axis shift, but this solution worked.