在其中心旋转方形TBitmap [英] Rotating a square TBitmap on its center
问题描述
我试图找到最简单的旋转方式,并在其中心以任意所需角度显示 TBitmap
。 TBitmap
是正方形的,只要旋转的位图的中心点保持恒定,可能发生的任何裁剪都不重要。图片非常小,只有50 x 50像素左右,因此速度不是问题。这是我到目前为止的代码,它可以将 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->画布->像素[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->画布->像素[x1] [y1] =
bitmap1->画布->像素[x] [y];
}
}
Form1-> Canvas-> Draw(500,200,bitmap2.get());
查看修改后的代码...这样可以旋转,但是副本会产生模糊的图像和旋转点在左上方。
您正以另一种方式进行此操作,因此在生成的图像中可能存在孔洞,因为您正在循环源像素用1像素的步长....来纠正此循环,改为目标像素...
- 通过
bitmap2
像素(x2,y2)
-
bitmap1
中的旋转后退
(x1,y1)
位置 复制像素值,如果( x1,y1
)在 bitmap1
>然后使用 clBlack
这样的背景色代替。 要提高速度,请使用 TBitmap-> ScanLine [y]
属性,如果使用的话,速度至少提高了 1000x
倍,请参见:
-
左边是
bmp1
,右边是bmp2
I am trying to find the simplest way to rotate and display a
TBitmap
on its center by any given angle needed. TheTBitmap
is square and any clipping that might occur is not important so long as the rotated bitmap's center point remains constant. The image is very small, only around 50 x 50 pixels so speed isn't an issue. Here is the code I have so far which rotates aTBitmap
to 90 degrees, which is simple, the any angle thing less so.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());
See revised code... This allows for rotation but the copy creates a hazy image and the rotation point is at the top left.
解决方案you are doing this the other way around so there may be present holes in the resulting image because you are looping the source pixels with 1 pixel step .... to remedy this loop the target pixels instead...
- loop through
bitmap2
pixels(x2,y2)
- for each compute rotated-back
(x1,y1)
position inbitmap1
- copy pixel value
if (
x1,y1
) is outsidebitmap1
then use backgroun color likeclBlack
instead.
To improve speed use
TBitmap->ScanLine[y]
property that will improve speed at least1000x
times if used right see:After I put all this together I got this:
#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; }
usage:
// 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;
Here example output:
On the left is
bmp1
and on the right rotatedbmp2
这篇关于在其中心旋转方形TBitmap的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- loop through