如何使用GDI +对旋转的图像进行居中?

时间:2009-05-28 18:19:22

标签: image-processing gdi+ c++-cli

我正在尝试使用GDI +将旋转的图像居中到目标缓冲区。源缓冲区和目标缓冲区的大小不同。

源缓冲区是图像数据的大小:(宽度,高度) 目标缓冲区是适合整个旋转图像所需的矩形大小:(rotateWidth,rotatingHeight)

这是我正在尝试的代码:

// Calculate the size needed for the image to be rotated into   
int width = /* some width */;
int height = /* some height */;
System::Windows::Size destSize 
  = IPMathUtilities::CalculateRotatedImageSize(rotateAreaBoundingPoints, 
    rotationDegree, width, height);

//
// Create source bitmap object
Bitmap^ sourceBitmap = gcnew Bitmap(width, height, width * 2, 
  PixelFormat::Format16bppRgb555, ptrSourceBuffer);

//
// Create destination bitmap object
int destBufferSize = destSize.Width * destSize.Height * 2;
BYTE* pDestBuffer = new BYTE[destBufferSize];
memset(pDestBuffer, 0, destBufferSize);
Bitmap^ destBitmap = gcnew Bitmap(destSize.Width, destSize.Height, 
  destSize.Width * 2, PixelFormat::Format16bppRgb555, (IntPtr)pDestBuffer);

//
// Draw rotated source image in destination image
Graphics^ g = Graphics::FromImage(destBitmap);
g->TranslateTransform(-width/2, -height/2);
g->RotateTransform(rotationDegree, MatrixOrder::Append);
g->TranslateTransform(destSize.Width / 2.0, destSize.Height / 2.0, 
  MatrixOrder::Append);
g->DrawImage(sourceBitmap, 0, 0, width, height);

几乎有效。它很接近 - 我发现如果 height 大于 width ,旋转图像的左侧位置是不正确的。同样,如果 width 大于 height ,则旋转图像的顶部位置不正确。

一些注意事项:

  • IPMathUtilities是我写的实用工具类。
  • 我100%肯定IPMathUtilities::CalculateRotatedImageSize()计算适合整个旋转图像所需的矩形的正确大小。 100%肯定。我已经彻底测试了它的确有效。
  • 我最近问了一个类似的问题:Why is iplRotate() not giving me correct results?。我结束了放弃IPL / IPP并尝试GDI +。

有什么想法吗?

1 个答案:

答案 0 :(得分:6)

旋转后,首先将图像移回原始位置,然后另外将新画布的差异减半。如果您在CalculateRotatedImageSize中的计算确实是正确的,那么它应该完全适合。刚刚测试了这段代码,它似乎有效:

g.TranslateTransform((float)(org.Width / -2), (float)(org.Height / -2));
g.RotateTransform(45, System.Drawing.Drawing2D.MatrixOrder.Append );
g.TranslateTransform((float)(org.Width / 2), (float)(org.Height / 2), System.Drawing.Drawing2D.MatrixOrder.Append);
g.TranslateTransform((float)((rotated.Width - org.Width) / 2), (float)((rotated.Height - org.Height) / 2), System.Drawing.Drawing2D.MatrixOrder.Append);

编辑:抱歉,当然

g.TranslateTransform((float)(org.Width / 2), (float)(org.Height / 2), System.Drawing.Drawing2D.MatrixOrder.Append);
g.TranslateTransform((float)((rotated.Width - org.Width) / 2), (float)((rotated.Height - org.Height) / 2), System.Drawing.Drawing2D.MatrixOrder.Append);

完全相同
g.TranslateTransform((float)(rotated.Width / 2), (float)(rotated.Height / 2), System.Drawing.Drawing2D.MatrixOrder.Append);

这只是您发布的代码。似乎对我来说工作正常。

EDIT2:也许错误只是

g->DrawImage(sourceBitmap, 0, 0, width, height);

尝试

g->DrawImage(sourceBitmap, 0, 0);

代替