使用 Borland C++ Builder 和 Windows API 函数旋转图像
Rotating an image using Borland C++ Builder and Windows API functions
我构建此示例是为了快速将图像旋转 90 度,但我总是在图像的侧面进行切割。经过多次测试,不幸的是我仍然不明白问题的原因。
void rotate()
{
Graphics::TBitmap *SrcBitmap = new Graphics::TBitmap;
Graphics::TBitmap *DestBitmap = new Graphics::TBitmap;
SrcBitmap->LoadFromFile("Crayon.bmp");
DestBitmap->Width=SrcBitmap->Width;
DestBitmap->Height=SrcBitmap->Height;
SetGraphicsMode(DestBitmap->Canvas->Handle, GM_ADVANCED);
double myangle = (double)(90.0 / 180.0) * 3.1415926;
int x0=SrcBitmap->Width/2;
int y0=SrcBitmap->Height/2;
double cx=x0 - cos(myangle)*x0 + sin(myangle)*y0;
double cy=y0 - cos(myangle)*y0 - sin(myangle)*x0;
xForm.eM11 = (FLOAT) cos(myangle);
xForm.eM12 = (FLOAT) sin(myangle);
xForm.eM21 = (FLOAT) -sin(myangle);
xForm.eM22 = (FLOAT) cos(myangle);
xForm.eDx = (FLOAT) cx;
xForm.eDy = (FLOAT) cy;
SetWorldTransform(DestBitmap->Canvas->Handle, &xForm);
BitBlt(DestBitmap->Canvas->Handle,
0,
0,
SrcBitmap->Width,
SrcBitmap->Height,
SrcBitmap->Canvas->Handle,
0,
0,
SRCCOPY);
DestBitmap->SaveToFile("Crayon2.bmp");
delete DestBitmap;
delete SrcBitmap;
}
曾经遇到过类似的问题。
我想围绕一个公共旋转点旋转两个图像。但是我不能用标准函数来做,因为它不允许旋转点分散到中心。
不过当时我已经对标准函数做了笔记。也许他们可以帮助你。
我记得目标图像的大小正确很重要!如果纵向图像变成横向图像,图像变宽,因此 BitBlt 函数还必须指定目标图像的大小。
这是我对标准功能的说明。
填充 xForm 参数对我来说与您的代码片段不太一样。
这就是我用来绕任何中心旋转的函数。
如果旋转整个图像,目标图像的宽度和高度应该翻转:
DestBitmap->Width = SrcBitmap->Height;
DestBitmap->Height = SrcBitmap->Width;
变换例程基于原始 width/height 将图像居中。我们要调整x/y的位置,将起点推到left/top for BitBlt
int offset = (SrcBitmap->Width - SrcBitmap->Height) / 2;
BitBlt(DestBitmap->Canvas->Handle, offset, offset, SrcBitmap->Width, SrcBitmap->Height,
SrcBitmap->Canvas->Handle, 0, 0, SRCCOPY);
我构建此示例是为了快速将图像旋转 90 度,但我总是在图像的侧面进行切割。经过多次测试,不幸的是我仍然不明白问题的原因。
void rotate()
{
Graphics::TBitmap *SrcBitmap = new Graphics::TBitmap;
Graphics::TBitmap *DestBitmap = new Graphics::TBitmap;
SrcBitmap->LoadFromFile("Crayon.bmp");
DestBitmap->Width=SrcBitmap->Width;
DestBitmap->Height=SrcBitmap->Height;
SetGraphicsMode(DestBitmap->Canvas->Handle, GM_ADVANCED);
double myangle = (double)(90.0 / 180.0) * 3.1415926;
int x0=SrcBitmap->Width/2;
int y0=SrcBitmap->Height/2;
double cx=x0 - cos(myangle)*x0 + sin(myangle)*y0;
double cy=y0 - cos(myangle)*y0 - sin(myangle)*x0;
xForm.eM11 = (FLOAT) cos(myangle);
xForm.eM12 = (FLOAT) sin(myangle);
xForm.eM21 = (FLOAT) -sin(myangle);
xForm.eM22 = (FLOAT) cos(myangle);
xForm.eDx = (FLOAT) cx;
xForm.eDy = (FLOAT) cy;
SetWorldTransform(DestBitmap->Canvas->Handle, &xForm);
BitBlt(DestBitmap->Canvas->Handle,
0,
0,
SrcBitmap->Width,
SrcBitmap->Height,
SrcBitmap->Canvas->Handle,
0,
0,
SRCCOPY);
DestBitmap->SaveToFile("Crayon2.bmp");
delete DestBitmap;
delete SrcBitmap;
}
曾经遇到过类似的问题。 我想围绕一个公共旋转点旋转两个图像。但是我不能用标准函数来做,因为它不允许旋转点分散到中心。 不过当时我已经对标准函数做了笔记。也许他们可以帮助你。 我记得目标图像的大小正确很重要!如果纵向图像变成横向图像,图像变宽,因此 BitBlt 函数还必须指定目标图像的大小。
这是我对标准功能的说明。 填充 xForm 参数对我来说与您的代码片段不太一样。
这就是我用来绕任何中心旋转的函数。
如果旋转整个图像,目标图像的宽度和高度应该翻转:
DestBitmap->Width = SrcBitmap->Height;
DestBitmap->Height = SrcBitmap->Width;
变换例程基于原始 width/height 将图像居中。我们要调整x/y的位置,将起点推到left/top for BitBlt
int offset = (SrcBitmap->Width - SrcBitmap->Height) / 2;
BitBlt(DestBitmap->Canvas->Handle, offset, offset, SrcBitmap->Width, SrcBitmap->Height,
SrcBitmap->Canvas->Handle, 0, 0, SRCCOPY);