请问GDI+中如何将一个图片按给定任意角度旋转?

时间:2022-05-10 23:27:29
请问GDI+中如何将一个图片按任意给定的角度旋转?

谢谢!!!

18 个解决方案

#1


GZ...

#2


至少有2种方法:一种用graphic类,一种用matrix,后者可以实现更强大的非线性旋转

VOID Example_RotateTransform(HDC hdc)
{
   Graphics graphics(hdc);
   Pen pen(Color(255, 255, 0, 0));

   graphics.TranslateTransform(100.0f, 0.0f);           // first translate
   graphics.RotateTransform(30.0f, MatrixOrderAppend);  // then rotate
   graphics.DrawImage(&image, 0, 0, 200, 80);
}


VOID Example_Rotate(HDC hdc)
{
   Graphics graphics(hdc);
   Pen pen(Color(255, 0, 0, 255));

   Matrix matrix;
   matrix.Translate(40.0f, 0.0f);            // first a translation
   matrix.Rotate(30.0f, MatrixOrderAppend);  // then a rotation

   graphics.SetTransform(&matrix);
   graphics.DrawImage(&image, 0, 0, 200, 80);
}

#3


这种方法只能用于打印图片呀!
我想要直接将图片进行旋转处理,然后保存图片。
Image类有个RotateFlip方法,但只能对图片进行以90度为单位的旋转。
另外:在DrawImage方法中对图片或者其它东西进行旋转时都是以原点为中心进行旋转的。
画椭圆等都是以矩形为参数,真不知道微软是怎么想的,用起来真不方便!

有没有办法解决之,急求答案,谢谢!!!

#4


Grahics对象是一个容器,你改改上面的代码,让它包含一个Image,旋转完毕以后用Image的save方法就可以保存图片为文件

#5


问题是,Image类没有可以按任意角度旋转的方法呀。

#6


up

#7


GDI+中没有对图象几何形状缩放、平移、旋转变形的函数,只能自己写。
微软这点太过于保守。 -_-
你用 LockBits()得到图像矩阵,用matrix去旋转,再保存新图象就ok了

#8


GDI+好像是直接使用DrawImage来实现任何角度的旋转的,以下是gdi+的一个帮助,楼主有吗?

Rotating, Reflecting, and Skewing Images 

--------------------------------------------------------------------------------

You can rotate, reflect, and skew an image by specifying destination points for the upper-left, upper-right, and lower-left corners of the original image. The three destination points determine an affine transformation that maps the original rectangular image to a parallelogram. (The lower-right corner of the original image is mapped to the fourth corner of the parallelogram, which is calculated from the three specified destination points.)

For example, suppose the original image is a rectangle with upper-left corner at (0, 0), upper-right corner at (100, 0), and lower-left corner at (0, 50). Now suppose we map those three points to destination points as follows.

Original point Destination point 
Upper-left (0, 0) (200, 20) 
Upper-right (100, 0) (110, 100) 
Lower-left (0, 50) (250, 30) 

The following illustration shows the original image and the image mapped to the parallelogram. The original image has been skewed, reflected, rotated, and translated. The x-axis along the top edge of the original image is mapped to the line that runs through (200, 20) and (110, 100). The y-axis along the left edge of the original image is mapped to the line that runs through (200, 20) and (250, 30).



The following example produces the images shown in the preceding illustration.

Point destinationPoints[] = {
   Point(200, 20),   // destination for upper-left point of original
   Point(110, 100),  // destination for upper-right point of original
   Point(250, 30)};  // destination for lower-left point of original
Image image(L"Stripes.bmp");
// Draw the image unaltered with its upper-left corner at (0, 0).
graphics.DrawImage(&image, 0, 0);
// Draw the image mapped to the parallelogram.
graphics.DrawImage(&image, destinationPoints, 3); 
The following illustration shows a similar transformation applied to a photographic image.

#9


我现在在做一个批量缩放图像以及加批注的小程序,不知道怎么新建一个指定大小的image来供Graphics.DrawImage

#10


回microyzy(毛毛叉) :
是不是新建一个Bitmap对象?
以下方法可以:
Bitmap* tempBitmap=new Bitmap(283,212,PixelFormat32bppARGB );

#11


哈唉,看来只能自己创建一个空的Graphics对象,然后再这上边写旋转图片的代码啦!

#12


asett1(asett1) 兄所说的方法,能否给个例子呀?

#13


不是,Graphics好像不能容那Bitmap对象,我是想新建一个Image图像

#14


Graphics可以选择Bitmap的。

Bitmap* TmpBitmap=new Bitmap(100,200,PixelFormat32bppARGB );
Graphics TmpGraphics(TmpBitmap);

我是在VC6.0上运行的,完全没问题。

#15


自己写了个图片旋转的函数。
不知道是否有更简单的方法来实现,期待...

void CImageDrawDlg::RotateImage(Bitmap * BMPImage,float angle)
{
angle = (float)((int)angle%360);
if(angle<0)angle+=360;
float fAngle = (float)(angle*rad);
float dx,dy,dx1,dx2,dy1,dy2,tL,tT;

float lx = (float)(BMPImage->GetWidth());
float ly = (float)(BMPImage->GetHeight());
dx1 = (float)(lx*cos(fAngle));
dx2 = (float)(ly*sin(fAngle));
dy1 = (float)(ly*cos(fAngle));
dy2 = (float)(lx*sin(fAngle));
if(dx1<0) dx1=-dx1;
if(dx2<0) dx2=-dx2;
if(dy1<0) dy1=-dy1;
if(dy2<0) dy2=-dy2;
dx=dx1+dx2;
dy=dy1+dy2;

if( (0<=angle) && (angle<=90) ){
tL = dx2;
tT = 0.0f;
}else if( (90<=angle) && (angle<=180) ){
tL = dx;
tT = dy1;
}else if( (180<=angle) && (angle<=270) ){
tL = dx1;
tT = dy;
}else if( (270<=angle) && (angle<=360) ){
tL = 0.0f;
tT = dy2;
}


Matrix mx;
mx.Rotate(angle);
Bitmap* TmpBitmap=new Bitmap((int)dx,(int)dy,PixelFormat32bppARGB );
Graphics TmpGraphics(TmpBitmap);
TmpGraphics.SetTransform(&mx);
TmpGraphics.TranslateTransform(tL,tT, MatrixOrderAppend);
TmpGraphics.DrawImage(BMPImage,PointF(0,0));

delete BMPImage;
BMPImage = TmpBitmap->Clone(0,0,TmpBitmap->GetWidth(),TmpBitmap->GetHeight(),PixelFormat32bppARGB);
}

#16


microyzy(毛毛叉) :
Bitmap是继承自Image的,所以理论上,Image有的方法,Bitmap也应该有。

#17


多谢,我去试试,你的帖子里解决我的问题,呵呵

#18


差不多吧,线性旋转就这样了 -_-

#1


GZ...

#2


至少有2种方法:一种用graphic类,一种用matrix,后者可以实现更强大的非线性旋转

VOID Example_RotateTransform(HDC hdc)
{
   Graphics graphics(hdc);
   Pen pen(Color(255, 255, 0, 0));

   graphics.TranslateTransform(100.0f, 0.0f);           // first translate
   graphics.RotateTransform(30.0f, MatrixOrderAppend);  // then rotate
   graphics.DrawImage(&image, 0, 0, 200, 80);
}


VOID Example_Rotate(HDC hdc)
{
   Graphics graphics(hdc);
   Pen pen(Color(255, 0, 0, 255));

   Matrix matrix;
   matrix.Translate(40.0f, 0.0f);            // first a translation
   matrix.Rotate(30.0f, MatrixOrderAppend);  // then a rotation

   graphics.SetTransform(&matrix);
   graphics.DrawImage(&image, 0, 0, 200, 80);
}

#3


这种方法只能用于打印图片呀!
我想要直接将图片进行旋转处理,然后保存图片。
Image类有个RotateFlip方法,但只能对图片进行以90度为单位的旋转。
另外:在DrawImage方法中对图片或者其它东西进行旋转时都是以原点为中心进行旋转的。
画椭圆等都是以矩形为参数,真不知道微软是怎么想的,用起来真不方便!

有没有办法解决之,急求答案,谢谢!!!

#4


Grahics对象是一个容器,你改改上面的代码,让它包含一个Image,旋转完毕以后用Image的save方法就可以保存图片为文件

#5


问题是,Image类没有可以按任意角度旋转的方法呀。

#6


up

#7


GDI+中没有对图象几何形状缩放、平移、旋转变形的函数,只能自己写。
微软这点太过于保守。 -_-
你用 LockBits()得到图像矩阵,用matrix去旋转,再保存新图象就ok了

#8


GDI+好像是直接使用DrawImage来实现任何角度的旋转的,以下是gdi+的一个帮助,楼主有吗?

Rotating, Reflecting, and Skewing Images 

--------------------------------------------------------------------------------

You can rotate, reflect, and skew an image by specifying destination points for the upper-left, upper-right, and lower-left corners of the original image. The three destination points determine an affine transformation that maps the original rectangular image to a parallelogram. (The lower-right corner of the original image is mapped to the fourth corner of the parallelogram, which is calculated from the three specified destination points.)

For example, suppose the original image is a rectangle with upper-left corner at (0, 0), upper-right corner at (100, 0), and lower-left corner at (0, 50). Now suppose we map those three points to destination points as follows.

Original point Destination point 
Upper-left (0, 0) (200, 20) 
Upper-right (100, 0) (110, 100) 
Lower-left (0, 50) (250, 30) 

The following illustration shows the original image and the image mapped to the parallelogram. The original image has been skewed, reflected, rotated, and translated. The x-axis along the top edge of the original image is mapped to the line that runs through (200, 20) and (110, 100). The y-axis along the left edge of the original image is mapped to the line that runs through (200, 20) and (250, 30).



The following example produces the images shown in the preceding illustration.

Point destinationPoints[] = {
   Point(200, 20),   // destination for upper-left point of original
   Point(110, 100),  // destination for upper-right point of original
   Point(250, 30)};  // destination for lower-left point of original
Image image(L"Stripes.bmp");
// Draw the image unaltered with its upper-left corner at (0, 0).
graphics.DrawImage(&image, 0, 0);
// Draw the image mapped to the parallelogram.
graphics.DrawImage(&image, destinationPoints, 3); 
The following illustration shows a similar transformation applied to a photographic image.

#9


我现在在做一个批量缩放图像以及加批注的小程序,不知道怎么新建一个指定大小的image来供Graphics.DrawImage

#10


回microyzy(毛毛叉) :
是不是新建一个Bitmap对象?
以下方法可以:
Bitmap* tempBitmap=new Bitmap(283,212,PixelFormat32bppARGB );

#11


哈唉,看来只能自己创建一个空的Graphics对象,然后再这上边写旋转图片的代码啦!

#12


asett1(asett1) 兄所说的方法,能否给个例子呀?

#13


不是,Graphics好像不能容那Bitmap对象,我是想新建一个Image图像

#14


Graphics可以选择Bitmap的。

Bitmap* TmpBitmap=new Bitmap(100,200,PixelFormat32bppARGB );
Graphics TmpGraphics(TmpBitmap);

我是在VC6.0上运行的,完全没问题。

#15


自己写了个图片旋转的函数。
不知道是否有更简单的方法来实现,期待...

void CImageDrawDlg::RotateImage(Bitmap * BMPImage,float angle)
{
angle = (float)((int)angle%360);
if(angle<0)angle+=360;
float fAngle = (float)(angle*rad);
float dx,dy,dx1,dx2,dy1,dy2,tL,tT;

float lx = (float)(BMPImage->GetWidth());
float ly = (float)(BMPImage->GetHeight());
dx1 = (float)(lx*cos(fAngle));
dx2 = (float)(ly*sin(fAngle));
dy1 = (float)(ly*cos(fAngle));
dy2 = (float)(lx*sin(fAngle));
if(dx1<0) dx1=-dx1;
if(dx2<0) dx2=-dx2;
if(dy1<0) dy1=-dy1;
if(dy2<0) dy2=-dy2;
dx=dx1+dx2;
dy=dy1+dy2;

if( (0<=angle) && (angle<=90) ){
tL = dx2;
tT = 0.0f;
}else if( (90<=angle) && (angle<=180) ){
tL = dx;
tT = dy1;
}else if( (180<=angle) && (angle<=270) ){
tL = dx1;
tT = dy;
}else if( (270<=angle) && (angle<=360) ){
tL = 0.0f;
tT = dy2;
}


Matrix mx;
mx.Rotate(angle);
Bitmap* TmpBitmap=new Bitmap((int)dx,(int)dy,PixelFormat32bppARGB );
Graphics TmpGraphics(TmpBitmap);
TmpGraphics.SetTransform(&mx);
TmpGraphics.TranslateTransform(tL,tT, MatrixOrderAppend);
TmpGraphics.DrawImage(BMPImage,PointF(0,0));

delete BMPImage;
BMPImage = TmpBitmap->Clone(0,0,TmpBitmap->GetWidth(),TmpBitmap->GetHeight(),PixelFormat32bppARGB);
}

#16


microyzy(毛毛叉) :
Bitmap是继承自Image的,所以理论上,Image有的方法,Bitmap也应该有。

#17


多谢,我去试试,你的帖子里解决我的问题,呵呵

#18


差不多吧,线性旋转就这样了 -_-

#19