• 全部
  • Windows SDK/API
  • 基础类
  • ActiveX
  • 数据库及相关技术
  • 网络及通讯开发
  • VCL组件使用和开发
  • 问答

请问如何 旋转一个位图?

whitecell 2002-07-17 10:55:55
请问如何 旋转一个位图?
...全文
98 点赞 收藏 11
写回复
11 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
hansonhx 2002-07-17
@_@
回复
钛哥 2002-07-17
看看direct-x库吧,如果你对这方面有兴趣的话,
BCB封装Direct-x是相当成功的,功能比VB将,使用复杂程度相当
回复
xdspower 2002-07-17
你的用户系统是什么?如果在win2000/nt上有一个专门的api来完成,函数是PlgBlt,不过这个函数在win9x和win3x下无效。
具体调用你参考下面
The PlgBlt function performs a bit-block transfer of the bits of color data from the specified rectangle in the source device context to the specified parallelogram in the destination device context. If the given bitmask handle identifies a valid monochrome bitmap, the function uses this bitmap to mask the bits of color data from the source rectangle.

BOOL PlgBlt(

HDC hdcDest, // handle to destination device context
CONST POINT *lpPoint, // vertices of destination parallelogram
HDC hdcSrc, // handle to source device context
int nXSrc, // x-coord. of upper-left corner of source rect.
int nYSrc, // y-coord. of upper-left corner of source rect.
int nWidth, // width of source rectangle
int nHeight, // height of source rectangle
HBITMAP hbmMask, // handle to bitmask
int xMask, // x-coord. of upper-left corner of bitmask rect.
int yMask // y-coord. of upper-left corner of bitmask rect.
);


Parameters

hdcDest

Identifies the destination device context.

lpPoint

Points to an array of three points in logical space that identify three corners of the destination parallelogram. The upper-left corner of the source rectangle is mapped to the first point in this array, the upper-right corner to the second point in this array, and the lower-left corner to the third point. The lower-right corner of the source rectangle is mapped to the implicit fourth point in the parallelogram.

hdcSrc

Identifies the source device context.

nXSrc

Specifies the x-coordinate, in logical units, of the upper-left corner of the source rectangle.

nYSrc

Specifies the y-coordinate, in logical units, of the upper-left corner of the source rectangle.

nWidth

Specifies the width, in logical units, of the source rectangle.

nHeight

Specifies the height, in logical units, of the source rectangle.

hbmMask

Identifies an optional monochrome bitmap that is used to mask the colors of the source rectangle.

xMask

Specifies the x-coordinate of the upper-left corner of the the monochrome bitmap.

yMask

Specifies the y-coordinate of the upper-left corner of the the monochrome bitmap.



Return Values

If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The fourth vertex of the parallelogram (D) is defined by treating the first three points (A, B, and C) as vectors and computing D = B + C - A.
If the bitmask exists, a value of 1 in the mask indicates that the source pixel color should be copied to the destination. A value of 0 in the mask indicates that the destination pixel color is not to be changed.
If the mask rectangle is smaller than the source and destination rectangles, the function replicates the mask pattern.

Scaling, translation, and reflection transformations are allowed in the source device context; however, rotation and shear transformations are not.
If the mask bitmap is not a monochrome bitmap, an error occurs.
The stretching mode for the destination device context is used to determine how to stretch or compress the pixels, if that is necessary.
When an enhanced metafile is being recorded, an error occurs if the source device context identifies an enhanced-metafile device context.

The destination coordinates are transformed according to the destination device context; the source coordinates are transformed according to the source device context. If the source transformation has a rotation or shear, an error is returned.
If the destination and source rectangles do not have the same color format, PlgBlt converts the source rectangle to match the destination rectangle.
Not all devices support the PlgBlt function. For more information, see the description of the RC_BITBLT raster capability in the GetDeviceCaps function.

If the source and destination device contexts represent incompatible devices, PlgBlt returns an error.

中文的
函数功能:该函数对源设备环境中指定的矩形区域中的颜色数据位进行位块转换,并转换到目标设备环境中指定的平行四边形里。如果给定的位掩码句柄表示为有效的单色位图,那么函数使用该位图来对源矩形中的颜色数据进行掩码(屏蔽)操作。

函数原型:BOOL PlgBlt(HDC hdcDest, CONST POINT *lpPoint, HDC hdcSrc,int nXSrc, int nYSrc, int nWidth, int nHeight, HBITMAP hbmMask, int xMask, int yMask);

参数:

hdcDest:指向目标设备环境的句柄。

lpPoint:指向代表目标平行四边形3个角的3个顶点的数组指针。源矩形的左上角映射到该数组的第1个顶点,右上角映射为数组中的第2个顶点,左下角映射成第3个顶点。而右下角则映射成平行四边形中隐含的第4个点。

hdcSrc:指向源设备环境的句柄。

nXSrc:指定源矩形左上角的X轴坐标,按逻辑单位。

nYSrc:指定源矩形左上角的Y轴坐标,按逻辑单位。

nWidth:指字源矩形的宽度,按逻辑单位。

nheight:指定源矩形的高度,按逻辑单位。

hbMask:指向可选的单色位图的句柄。该位图是用来对源矩形的颜色进行屏蔽用的。

xMask:指定单色位图左上角的X轴坐标。

yMask:指定单色位图左上角的Y轴坐标。

返回值:如果函数成功,那么返回值非零;如果函数失败,则返回值为零。

Windows NT:若想获得更多错误信息,请调用GetLastError函数。

备注:平行四边形的第4个顶点(D)是通过把头3个顶点(A、B、C)当作矢量,并按D=B+C+A计算来定义的。如果存在位掩码,那么掩码中的数值1表示应该将源像素的颜色拷贝到目标像素点上。掩码中的数值0表示不改变目标像素颜色。如果掩码矩形比源和目标矩形要小,那么该函数重复掩码模式。

在源设备环境中,允许有伸缩、平移和反射变换,然而禁止有旋转和剪切变换。如果掩码位图不是单色位图,那将会出现错误。在需要时,目标设备环境用的伸展模式是用来定义如何拉伸或压缩像素的。

当正在对一个增强型图元文件进行记录时,如果源设备环境标识为增强型图元文件设备环境,那么将出现错误。目标坐标根据目标设备环境进行变换,源坐标是根据源设备环境进行变换。如果源变换有旋转或剪切,那么会返回一个错误。如果目标和源矩形颜色格式不相同,那么Plgblt对源矩形进行转换,以与目标矩形匹配。不是所有设备都支持PlgBlt函数,若想了解更多信息,那么GetDeviceCaps函数中有关RC_BITBLT光栅特性的描述。如果源和目标设备环境代表不兼容设备,那么PlgBlt返回一个错误。

速查:Windows NT:3.1及以上版本;Windows:不支持;Windows CE:不支持;头文件:wingdi.h;库文件:gdi32.lib。

回复
hbxtx 2002-07-17
你看看这篇文章:

本文将介绍如何将一张位图旋转90度。向工程添加一个TImage控件,取名为Image1。

  工作原理是:创建一个位图缓冲区用于存储中间量,将原位图的每一行的像素转换为每一列然后存放在我们创建的位图缓冲区中。最后,将旋转后的位图从缓冲区存回原位图。

//定义缓冲位图并剪切图形区域
Graphics::TBitmap *bufferbitmap=new Graphics::TBitmap();
bufferbitmap->Width=Image1->Height;
bufferbitmap->Height=Image1->Width;
static TRect sourcepix,destpix,fullbufferimage,fulldestimage;
fullbufferimage.Left= 0;
fullbufferimage.Top= bufferbitmap->Height;
fullbufferimage.Right= bufferbitmap->Width;
fullbufferimage.Bottom= 0;
//旋转并逐像素地拷贝原位图到缓冲位图
for (int y=0; y<Image1->Height; y++)
{
 for (int x=0; x<Image1->Width; x++)
 {
  sourcepix.Left= x;
  sourcepix.Top= y+1;
  sourcepix.Right= x+1;
  sourcepix.Bottom= y;
  destpix.Left=y;
  destpix.Top=bufferbitmap->Height-x;
  destpix.Right=y+1;
  destpix.Bottom=bufferbitmap->Height-x-1;
  bufferbitmap->Canvas->CopyRect(destpix,Image1->Canvas,sourcepix);
 }
}

//调整原位图的尺寸并拷贝旋转后的缓冲位图到原位图
Image1->Width=bufferbitmap->Width;
Image1->Height=bufferbitmap->Height;
Image1->Picture->Bitmap->Width=bufferbitmap->Width;
Image1->Picture->Bitmap->Height=bufferbitmap->Height;
Image1->Canvas->CopyRect(fullbufferimage,bufferbitmap->Canvas,fullbufferimage);
回复
hbxtx 2002-07-17
你看看这篇文章:

本文将介绍如何将一张位图旋转90度。向工程添加一个TImage控件,取名为Image1。

  工作原理是:创建一个位图缓冲区用于存储中间量,将原位图的每一行的像素转换为每一列然后存放在我们创建的位图缓冲区中。最后,将旋转后的位图从缓冲区存回原位图。

//定义缓冲位图并剪切图形区域
Graphics::TBitmap *bufferbitmap=new Graphics::TBitmap();
bufferbitmap->Width=Image1->Height;
bufferbitmap->Height=Image1->Width;
static TRect sourcepix,destpix,fullbufferimage,fulldestimage;
fullbufferimage.Left= 0;
fullbufferimage.Top= bufferbitmap->Height;
fullbufferimage.Right= bufferbitmap->Width;
fullbufferimage.Bottom= 0;
//旋转并逐像素地拷贝原位图到缓冲位图
for (int y=0; y<Image1->Height; y++)
{
 for (int x=0; x<Image1->Width; x++)
 {
  sourcepix.Left= x;
  sourcepix.Top= y+1;
  sourcepix.Right= x+1;
  sourcepix.Bottom= y;
  destpix.Left=y;
  destpix.Top=bufferbitmap->Height-x;
  destpix.Right=y+1;
  destpix.Bottom=bufferbitmap->Height-x-1;
  bufferbitmap->Canvas->CopyRect(destpix,Image1->Canvas,sourcepix);
 }
}

//调整原位图的尺寸并拷贝旋转后的缓冲位图到原位图
Image1->Width=bufferbitmap->Width;
Image1->Height=bufferbitmap->Height;
Image1->Picture->Bitmap->Width=bufferbitmap->Width;
Image1->Picture->Bitmap->Height=bufferbitmap->Height;
Image1->Canvas->CopyRect(fullbufferimage,bufferbitmap->Canvas,fullbufferimage);
回复
hbxtx 2002-07-17
你看看这篇文章:

本文将介绍如何将一张位图旋转90度。向工程添加一个TImage控件,取名为Image1。

  工作原理是:创建一个位图缓冲区用于存储中间量,将原位图的每一行的像素转换为每一列然后存放在我们创建的位图缓冲区中。最后,将旋转后的位图从缓冲区存回原位图。

//定义缓冲位图并剪切图形区域
Graphics::TBitmap *bufferbitmap=new Graphics::TBitmap();
bufferbitmap->Width=Image1->Height;
bufferbitmap->Height=Image1->Width;
static TRect sourcepix,destpix,fullbufferimage,fulldestimage;
fullbufferimage.Left= 0;
fullbufferimage.Top= bufferbitmap->Height;
fullbufferimage.Right= bufferbitmap->Width;
fullbufferimage.Bottom= 0;
//旋转并逐像素地拷贝原位图到缓冲位图
for (int y=0; y<Image1->Height; y++)
{
 for (int x=0; x<Image1->Width; x++)
 {
  sourcepix.Left= x;
  sourcepix.Top= y+1;
  sourcepix.Right= x+1;
  sourcepix.Bottom= y;
  destpix.Left=y;
  destpix.Top=bufferbitmap->Height-x;
  destpix.Right=y+1;
  destpix.Bottom=bufferbitmap->Height-x-1;
  bufferbitmap->Canvas->CopyRect(destpix,Image1->Canvas,sourcepix);
 }
}

//调整原位图的尺寸并拷贝旋转后的缓冲位图到原位图
Image1->Width=bufferbitmap->Width;
Image1->Height=bufferbitmap->Height;
Image1->Picture->Bitmap->Width=bufferbitmap->Width;
Image1->Picture->Bitmap->Height=bufferbitmap->Height;
Image1->Canvas->CopyRect(fullbufferimage,bufferbitmap->Canvas,fullbufferimage);
回复
孩皮妞野 2002-07-17
//---------------------------------------------------------------------------
// 旋转bmp
//---------------------------------------------------------------------------
void __fastcall TXXXX::DoRotate(Graphics::TBitmap * bmp)
{
TPixelFormat org_fmt;//Original pixel format;
int r, c; //row , col
int org_w = bmp->Width; //original width and height of the bmp
int org_h = bmp->Height;
//#define __USE_ALGORITHM1__
#ifdef __USE_ALGORITHM1__
bool org_w_gt_h ; //width is great than height originally
int n; //dimension of the matrix, = max(org_w,org_h)
int hold; //hold a pixel value;

org_w_gt_h=org_w > org_h;
org_fmt=bmp->PixelFormat;
bmp->PixelFormat=pf32bit;

//Make it a quare matrix
if(org_w_gt_h)
bmp->Height = n = org_w;
else
bmp->Width = n = org_h;
//Transpose
for(r=0;r<(n+1)/2;r++){
int * p=(int *)bmp->ScanLine[r];
for(c=0;c<n/2;c++){
hold=*(p+c); //hold it;
int r_from,c_from, r_to, c_to;
r_to=r; c_to=c;
for(int i=0; i<4; i++){
r_from=c_to; c_from=n-r_to-1;
*((int *)bmp->ScanLine[r_to]+c_to) =
(i==3) ? hold :
*((int *)bmp->ScanLine[r_from]+c_from);
r_to=r_from, c_to=c_from;
}
}
}
if(org_w_gt_h)
bmp->Width=org_h;
else
bmp->Height=org_w;
#else //算法2
Graphics::TBitmap *tmp =new Graphics::TBitmap();
org_fmt = bmp->PixelFormat;
bmp->PixelFormat = pf32bit;
tmp->Assign(bmp); //make a copy
bmp->Width = org_h;
bmp->Height = org_w;
//scan and transpose
for(r=0; r<org_h; r++)
for(c=0; c<org_w; c++)
*((int *)bmp->ScanLine[c]+org_h-r-1) =
*((int *)tmp->ScanLine[r]+c);
delete tmp;
#endif
#undef __USING_ALGORITHM1__

// 从我的机上来看,算法2似乎更快些。
// 原来的算法有缺陷,如果bmp不是24bits per pixel的,会乱套
// ALNG 注 2001-5-2
bmp->PixelFormat=org_fmt; //restore stored pixelformat
}
回复
whitelion 2002-07-17
逐点计算新位置,逐点显示
回复
wudi_1982 2002-07-17
用一个Image组件,然后把BMP图象LOAD,调整大小,接着你就只需要改变Image组件的位置就可以了,你可以先获得Image左上脚的坐标,然后按圆的方式改变就可以了.

具体的我记不清楚了,你可以查一下帮助,F1,然后看一下,RECT的帮助.
回复
孩皮妞野 2002-07-17
把位图看成一个矩阵,旋转矩阵。
回复
whitecell 2002-07-17
UP
回复
相关推荐
发帖
C++ Builder
创建于2007-08-02

1.3w+

社区成员

C++ Builder相关内容讨论区
申请成为版主
帖子事件
创建了帖子
2002-07-17 10:55
社区公告
暂无公告