我试图找到最简单的方式旋转和显示一个TBitmap的中心,以任何给定的角度需要。TBitmap是正方形的,只要旋转位图的中心点保持不变,任何可能发生的裁剪都不重要。图像非常小,只有大约50x50像素,所以速度不是问题。这是我到目前为止的代码,它将一个TBitmap旋转到90度,这很简单,任何角度的东西都不那么简单。
std::auto_ptr<Graphics::TBitmap> bitmap1(new Graphics::TBitmap);
std::auto_ptr<Graphics::TBitmap> bitmap2(new Graphics::TBitmap);
bitmap1->LoadFromFile("c:/myimage.bmp");
bitmap1->Transparent = true;
bitmap1->TransparentColor = bitmap1->Canvas->Pixels[50][50];
bitmap2->Width=bitmap1->Height;
bitmap2->Height=bitmap1->Width;
double x1 = 0.0;
double y1 = 0.0;
for (int x = 0;x < bitmap1->Width; x++)
{
for(int y = 0;y < bitmap1->Height;y++)
{
x1 = std::cos(45.0) * x - std::sin(45.0) * y;
y1 = sin(45.0) * x + cos(45.0) * y;
bitmap2->Canvas->Pixels[x1][y1] =
bitmap1->Canvas->Pixels[x][y];
}
}
Form1->Canvas->Draw( 500, 200, bitmap2.get()); 参见修改后的代码..。这允许旋转,但是复制会创建一个模糊的图像,旋转点在左上角。
发布于 2017-06-01 06:22:39
你这样做是相反的,所以可能会出现洞的结果图像,因为你是循环源像素1像素步骤.为了弥补这个循环目标像素..。
bitmap2 (x2,y2)的像素的循环(x1,y1) bitmap1中,每个计算的为旋转的位置。x1,y1)在bitmap1之外,然后使用像clBlack这样的背景颜色。若要提高速度,请使用TBitmap->ScanLine[y]属性,如果使用正确,该属性将至少提高速度1000x次数,请参见:
在我把所有这些都放在一起之后,我得到了这个:
#include <math.h> // just for cos,sin
// rotate src around x0,y0 [pixels] by angle [rad] and store result in dst
void rotate(Graphics::TBitmap *dst,Graphics::TBitmap *src,double x0,double y0,double angle)
{
int x,y,xx,yy,xs,ys;
double s,c,fx,fy;
// resize dst to the same size as src
xs=src->Width;
ys=src->Height;
dst->SetSize(xs,ys);
// allow direct pixel access for src
src->HandleType=bmDIB;
src->PixelFormat=pf32bit;
DWORD **psrc=new DWORD*[ys];
for (y=0;y<ys;y++) psrc[y]=(DWORD*)src->ScanLine[y];
// allow direct pixel access for dst
dst->HandleType=bmDIB;
dst->PixelFormat=pf32bit;
DWORD **pdst=new DWORD*[ys];
for (y=0;y<ys;y++) pdst[y]=(DWORD*)dst->ScanLine[y];
// precompute variables
c=cos(angle);
s=sin(angle);
// loop all dst pixels
for (y=0;y<ys;y++)
for (x=0;x<xs;x++)
{
// compute position in src
fx=x; // convert to double
fy=y;
fx-=x0; // translate to center of rotation
fy-=y0;
xx=double(+(fx*c)+(fy*s)+x0); // rotate and translate back
yy=double(-(fx*s)+(fy*c)+y0);
// copy pixels
if ((xx>=0)&&(xx<xs)&&(yy>=0)&&(yy<ys)) pdst[y][x]=psrc[yy][xx];
else pdst[y][x]=0; // black
}
// free memory
delete[] psrc;
delete[] pdst;
}用法:
// init
Graphics::TBitmap *bmp1,*bmp2;
bmp1=new Graphics::TBitmap;
bmp1->LoadFromFile("image.bmp");
bmp1->HandleType=bmDIB;
bmp1->PixelFormat=pf32bit;
bmp2=new Graphics::TBitmap;
bmp2->HandleType=bmDIB;
bmp2->PixelFormat=pf32bit;
// rotate
rotate(bmp2,bmp1,bmp1->Width/2,bmp1->Height/2,25.0*M_PI/180.0);
// here render bmp2 or whatever
// exit
delete bmp1;
delete bmp2;这里的示例输出:

左边是bmp1,右边是旋转的bmp2
https://stackoverflow.com/questions/44213349
复制相似问题