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

Rob*_*Rob 6 gdi+ c++-cli image-processing

我正在尝试使用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);
Run Code Online (Sandbox Code Playgroud)

几乎可行.它很接近 - 我发现如果高度大于宽度,旋转图像的左侧位置是不正确的.同样,如果width大于height,则旋转图像的顶部位置不正确.

一些说明:

  • IPMathUtilities 是我写的实用类.
  • 我100%肯定,IPMathUtilities::CalculateRotatedImageSize()计算适合整个旋转图像所需的矩形的正确大小.100%肯定.我已经彻底测试了它的确有效.
  • 我最近问了一个类似的问题:为什么iplRotate()不给我正确的结果?.我结束了放弃IPL/IPP并尝试GDI +.

有任何想法吗?

Ben*_*ehn 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);
Run Code Online (Sandbox Code Playgroud)

编辑:抱歉,当然

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);
Run Code Online (Sandbox Code Playgroud)

真是一样的

g.TranslateTransform((float)(rotated.Width / 2), (float)(rotated.Height / 2), System.Drawing.Drawing2D.MatrixOrder.Append);
Run Code Online (Sandbox Code Playgroud)

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

编辑2:也许错误只是

g->DrawImage(sourceBitmap, 0, 0, width, height);
Run Code Online (Sandbox Code Playgroud)

尝试

g->DrawImage(sourceBitmap, 0, 0);
Run Code Online (Sandbox Code Playgroud)

代替