如何使用 GDI 居中旋转图像?
我正在尝试使用 GDI+ 将旋转图像居中到目标缓冲区中。 源缓冲区和目标缓冲区的大小不同。
源缓冲区是图像数据的大小:(宽度,高度)。
目标缓冲区是适合整个旋转图像所需的矩形大小:(rotatedWidth,rotatedHeight)。
这是我正在尝试的代码:
// 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);
这几乎有效。 它很接近 - 我发现如果高度大于宽度,则旋转图像的左侧位置不正确。 同样,如果宽度大于高度,则旋转图像的顶部位置不正确。
一些注释:
IPMathUtilities
是我编写的一个实用程序类。- 我 100% 肯定
IPMathUtilities::CalculateRotatedImageSize()
计算出适合整个旋转图像所需的矩形的正确大小。 100%确定。 我已经彻底测试过它并且有效。 - 我最近问了一个类似的问题: 为什么是
iplRotate()< /code> 没有给我正确的结果?
。 我最终放弃了 IPL/IPP 并尝试了 GDI+。
有任何想法吗?
I'm trying to center a rotated image into a destination buffer using GDI+. The source buffer and the destination buffer are different sizes.
The source buffer is the size of the image data: (width, height).
The destination buffer is the size of the rectangle required to fit the entire rotated image: (rotatedWidth, rotatedHeight).
This is the code I'm trying:
// 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);
This almost works. It's close - I'm finding if height is greater than width, the left position of the rotated image is incorrect. Similarly, if width is greater than height, the top position of the rotated image is incorrect.
Some notes:
IPMathUtilities
is a utility class I wrote.- I'm 100% positive that
IPMathUtilities::CalculateRotatedImageSize()
calculates the correct size of the rectangle required to fit the entire rotated image. 100% certain. I've tested it thoroughly and it works. - I recently asked a similar question: Why is
iplRotate()
not giving me correct results?. I ended giving up on IPL/IPP and trying GDI+.
Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
旋转后,首先将图像移回原始位置,然后再增加一半的差异,使新画布变大。 如果您在CalculateRotatedImageSize 中的计算确实正确,那么它应该完全适合。 刚刚测试了这段代码,它似乎有效:
编辑:抱歉,当然
实际上相同
与您发布的代码 。 不过似乎对我来说效果很好。
错误只是
尝试
EDIT2:也许
After the rotate, first move the image back to the original position, then additionally by half the difference the new canvas is larger. If your calculation in CalculateRotatedImageSize is indeed correct, it should then fit exactly. Just tested this code and it seems to work:
EDIT: sorry, of course
is really the same as
which is just the code you posted. Seems to work fine for me though.
EDIT2: perhaps the error is just
Try
instead