怎样将1位的图片旋转90度后以另一个文件名保存

userzh 2010-05-19 09:18:45
格式:1位的BMP文件.将它旋转90度后以另一个文件名保存,
要写成动态链接库的形式.

(急)
...全文
339 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
userzh 2010-05-21
  • 打赏
  • 举报
回复
谢谢各位,问题已初步解决,只是速度还有问题,先结贴.

都给分 ^.^
Normandie007 2010-05-20
  • 打赏
  • 举报
回复
看下这个帖子
http://topic.csdn.net/u/20100518/10/c0083771-f5db-45ab-8249-10c1053905c2.html
xiuxianshen 2010-05-20
  • 打赏
  • 举报
回复
行读取,列保存
Normandie007 2010-05-20
  • 打赏
  • 举报
回复
不是的。
biSizelmage是该BMP 内图像数据占用的空间大小。若图像文件描述BI—RGB位图,则该字段的值必须设置为0。

bfOffBits 它以字节为单位,指示图像数据在文件内的起始地址,即图像数据针对文件头的偏移量。

具体,你看下这个
http://blog.csdn.net/orangeman1982112/archive/2009/02/13/3887427.aspx
userzh 2010-05-20
  • 打赏
  • 举报
回复
谢谢各位,有了一点头绪,但有一个地方有些疑问:

1位的bmp,bfOffBits 怎么计算,
可以直接 bfOffBits = BITMAPINFOHEADER.bisizeimage
laviewpbt 2010-05-19
  • 打赏
  • 举报
回复
1位色的图像 只能旋转90度的整数倍,所以上面贴的那些什么旋转算法都是无用的。
如果自己写算法,90度的旋转就是一个简单的行变列的过程,但是1位色不那么简单,原因就是这个字节对齐的东西,你需要特别处理原始行的最后几个字节。
简单那的方法就是利用GDI+的GdipImageRotateFlip函数以及几个保存图像的函数。
BloodFighter 2010-05-19
  • 打赏
  • 举报
回复
GDI+ DrawImage 有一个坐标系变换的
尹成 2010-05-19
  • 打赏
  • 举报
回复
/**   
* 快速旋转指定的Dib对象
* @param pDib 待旋转的Dib对象
* @param nAngle 旋转角度(角度制)
*/
void DIB_RotateFast(CDib *pDib, int nAngle) {
int i, j;
CDib *pTmp;
nAngle %= 360;
BYTE **scanLines = new BYTE*[pDib->m_nHeight];
BYTE *pScanLine = pDib->m_pBits;
for (i = 0; i < pDib->m_nHeight; i++) {
*(scanLines+i) = pScanLine;
pScanLine += pDib->m_nPitch;
}
switch (nAngle) {
case 0:
delete scanLines;
return;
case 90:
pTmp = new CDib(pDib->m_nHeight, pDib->m_nWidth, COLOR_BLACK);
DIB_Filter(pTmp, dib_Rotate90Filter, scanLines);
*pDib = *pTmp;
delete scanLines;
delete pTmp;
return;
case 180:
DIB_Flip(pDib, FLIP_HORIZONTAL | FLIP_VERTICAL);
return;
case 270:
pTmp = new CDib(pDib->m_nHeight, pDib->m_nWidth, COLOR_BLACK);
DIB_Filter(pTmp, dib_Rotate270Filter, scanLines);
*pDib = *pTmp;
delete scanLines;
delete pTmp;
return;
default:
break;
}
double dAngle = nAngle/180.0 * PI;
int nSin = (int)(sin(dAngle)*65536.0+0.5);
int nCos = (int)(cos(dAngle)*65536.0+0.5);
POINT vertex[] = {
{0, 0},
{(pDib->m_nWidth*nCos) >> 16, (pDib->m_nWidth*nSin) >> 16},
{(pDib->m_nWidth*nCos + pDib->m_nHeight*nSin) >> 16, (pDib->m_nWidth*nSin - pDib->m_nHeight*nCos) >> 16},
{(pDib->m_nHeight*nSin) >> 16, (-pDib->m_nHeight*nCos) >> 16}
};
POINT newVertex[4];
if (nAngle > 0 && nAngle < 90) {
newVertex[0] = vertex[0];
newVertex[1] = vertex[1];
newVertex[2] = vertex[2];
newVertex[3] = vertex[3];
} else if (nAngle > 90 && nAngle < 180) {
newVertex[0] = vertex[1];
newVertex[1] = vertex[2];
newVertex[2] = vertex[3];
newVertex[3] = vertex[0];
} else if (nAngle > 180 && nAngle < 270) {
newVertex[0] = vertex[2];
newVertex[1] = vertex[3];
newVertex[2] = vertex[0];
newVertex[3] = vertex[1];
} else {
newVertex[0] = vertex[3];
newVertex[1] = vertex[0];
newVertex[2] = vertex[1];
newVertex[3] = vertex[2];
}
SIZE newSize;
int edgeSlope[4];
int edgeConst[4];
int deltaX = nCos*newVertex[0].x+nSin*newVertex[1].y;
int deltaY = nCos*newVertex[1].y-nSin*newVertex[0].x;
dib_GetEdgeFormulas(newVertex, &newSize, edgeSlope, edgeConst);
pTmp = new CDib(newSize.cx, newSize.cy, g_colorKey);
int ox, oy;
int boundLeft, boundRight;
BYTE *pVInc = pTmp->m_pBits; // 初始化为第一个扫描行的首地址(也就是整个图像数据的首址)
// 水平方向的增量指针。每操作完一个像素,它就被指向下一个像素
BYTE *pHInc = NULL; // 它将在每次对一个扫描行开始处理之前被赋值
int actualY = -pTmp->m_nHeight;
for (i = 0; i > actualY; i--) {
if (i > newVertex[0].y) {
boundLeft = (edgeSlope[0]*i + edgeConst[0]) >> 16;
} else {
boundLeft = (edgeSlope[1]*i + edgeConst[1]) >> 16;
}
if (i > newVertex[2].y) {
boundRight = (edgeSlope[2]*i + edgeConst[2]) >> 16;
} else {
boundRight = (edgeSlope[3]*i + edgeConst[3]) >> 16;
}
pHInc = pVInc+boundLeft+boundLeft+boundLeft; // 把水平增量指针初始化为当前扫描行的首址
for (j = boundLeft; j < boundRight; j++) {
ox = (nCos*j+nSin*i+deltaX) >> 16;
oy = -((nCos*i-nSin*j+deltaY) >> 16);
ox = ox < 0 ? 0 : ox;
ox = ox >= pDib->m_nWidth ? pDib->m_nWidth-1 : ox;
oy = oy < 0 ? 0 : oy;
oy = oy >= pDib->m_nHeight ? pDib->m_nHeight-1 : oy;
dib_SetColor(pHInc, dib_GetColor(*(scanLines+oy)+ox+ox+ox));
pHInc += PIXELSIZE; // 一个像素数据过滤完成,指针指向下一个
}
pVInc += pTmp->m_nPitch; // 一个扫描行处理完,指针指向下一行
}
*pDib = *pTmp;
delete scanLines;
delete pTmp;
}
kaynezhang 2010-05-19
  • 打赏
  • 举报
回复
你还是用CxImage实在。
baby393 2010-05-19
  • 打赏
  • 举报
回复
利用Windows的坐标转换功能就可以了(需要在Windows2000或以上系统才可以运行)。

这里示范如何将位图旋转90度。
// hDC 屏幕或内存DC。
// hBitmap 要转换的位图句柄。

HDC hDCMem = CreateCompatibleDC(hDC);
SetGraphicsMode(hDCMem, GM_ADVANCED)
XFORM xf;
xf.em11 = (float)0.0;
xf.em12 = (float)1.0;
xf.em21 = (float)-1.0;
xf.em22 = (float)0.0;
xf.eDx = 0;
xf.eDy = 0;
SetWorldTransform(hDCMem, &xf);

BITMAP bm;
HGDIOBJ hBmpPrev = SelectObject(hDCMem, hBitmap);
GetObject(hBitmap, sizeof(bm), &bm);

BitBlt(hDC, 0, 0, bm.bmWidth, bm.bmHeight, hDCMem, 0, 0, SRCCOPY);

SelectObject(hDCMem, hBmpPrev);
DeleteDC(hDCMem);

// 将hDC中的HBITMAP分离出来并且保存成DIB就可以了。
sjdev 2010-05-19
  • 打赏
  • 举报
回复
楼主是完全没头绪如何去写还是只是想要现成的代码?

你现在需要的是一个旋转位图的算法而已。
dreamcs 2010-05-19
  • 打赏
  • 举报
回复
方法选其一
[1]找bmp文件格式资料。搞懂后,旋转图片就难了。
[2]试试GDI+,找找没有没对应的函数
[3]试试开源的CxImage
迷你图片批量处理工具,她能够帮您迅速大批量处理您的图片。您只需要将一张或多张图片甚至一个文件夹拖放到添加窗口,即可完成图片的添加,方便好用。 功能概述:批量更改大小、批量图片压缩、批量添加水印、批量更改格式、批量增加特效等。 修订概述: 新增水印图片旋转功能。 新增图片旋转、灰色、反色、模糊、锐化、棕色、红色、绿色、蓝色、青色、品红、黄色等特效处理。 新增图片色相、饱和度、亮度、对比度、阀值等调整功能。 新增以文件名、拍摄时间、当前时间为水印文字的设置。 新增水印文字与水印图片的同时支持。 新增图片裁剪的自定义裁剪置。 新增添加水印时对小尺寸图片的过滤功能。 新增设置保存功能。 新增水印图片输入框拖拽功能,您可以直接将水印图片拖拽至水印图片文本框。 修正了多文件夹拖拽到添加图片窗体后出现的程序崩溃问题。 修订了图片修改后EXIF信息丢失的问题。 新增图片列表Delete快捷键移除图片功能。 提示:如果您不能正常使用该软件,请安装.NET Framework 2.0, 下载地址:http://www.microsoft.com/downloads/details.aspx?familyid=0856EACB-4362-4B0D-8EDD-AAB15C5E04F5&displaylang=zh-cn 迷你软件系列工具: 迷你图片批量处理工具 迷你文件校验工具 迷你定时提醒工具 迷你词典(MiniDict) Excel数据导出工具 迷你网站检测工具 迷你批量更改文件编码工具 ... 、

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧