5472|19

57

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

WinCE 对位图旋转的问题 [复制链接]

现在相对摄像头保存下来的bmp图像文件做旋转处理,借鉴桌面版Windows的图像处理例程(编译运行通过),关键部分如下:

  1. int i,j,i0,j0,width1,height1;
  2.                 float rotateangle,fsin,fcos;
  3.                 float srcx1,srcx2,srcx3,srcx4,srcy1,srcy2,srcy3,srcy4;
  4.                 float dstx1,dstx2,dstx3,dstx4,dsty1,dsty2,dsty3,dsty4;
  5.                 //int tempvalue=Dialog1.m_value;
  6.                
  7.                 i=j=i0=j0=0;
  8.                 //计算旋转弧度
  9.     rotateangle=(float)((180)*PI/180); //rotateangle=(float)((tempvalue)*PI/180);

  10.                 fsin=(float)sin((double)rotateangle);
  11.                 fcos=(float)cos((double)rotateangle);
  12.                
  13.                 BYTE * dibdata1;
  14.                 dibdata1 = DIBdata;        //dibdata1=tempdib->GetDibData();
  15.                 RETAILMSG(1,(TEXT("OnRotate:Get DIBdata.\r\n")));
  16.                 //原图宽和高
  17.                 width1=width;        //width1=tempdib->GetWidth();
  18.                 height1=height;        //height1=tempdib->GetHeight();
  19.                
  20.                 //位图文件信息头指针
  21.                 //LPBITMAPINFOHEADER m_bitmapinfoheader;
  22.                 //LPBITMAPINFO m_bitmapinfo;

  23.                 //m_bitmapinfoheader=tempdib->Getmapinfoheader();
  24.                 //m_bitmapinfo=tempdib->Getmapinfo();
  25.                 BYTE * buffer=new BYTE[3*width1*height1];
  26.                                
  27.                 for(i=0;i
  28.                   for(j=0;j
  29.                         {  
  30.                                 *(buffer+3*(i*width1+j))=*(dibdata1+3*(i*width1+j));
  31.                                 *(buffer+3*(i*width1+j)+1)=*(dibdata1+3*(i*width1+j)+1);
  32.                                 *(buffer+3*(i*width1+j)+2)=*(dibdata1+3*(i*width1+j)+2);
  33.                         }
  34.                        
  35.                         //平移一次后源图像四角坐标
  36.                 srcx1=(float)(-(width1-1)/2);
  37.                 srcy1=(float)((height1-1)/2);

  38.                 srcx2=(float)((width1-1)/2);
  39.                 srcy2=(float)((height1-1)/2);

  40.                 srcx3=(float)((width1-1)/2);
  41.                 srcy3=(float)(-(height1-1)/2);

  42.                 srcx4=(float)(-(width1-1)/2);
  43.                 srcy4=(float)(-(height1-1)/2);

  44.                 //计算旋转后四角坐标

  45.                 dstx1=srcx1*fcos+srcy1*fsin;
  46.                 dsty1=-srcx1*fsin+srcy1*fcos;

  47.                 dstx2=srcx2*fcos+srcy2*fsin;
  48.                 dsty2=-srcx2*fsin+srcy2*fcos;

  49.                 dstx3=srcx3*fcos+srcy3*fsin;
  50.                 dsty3=-srcx3*fsin+srcy3*fcos;

  51.                 dstx4=srcx4*fcos+srcy4*fsin;
  52.                 dsty4=-srcx4*fsin+srcy4*fcos;


  53.                 int lnewwidth,lnewheight;
  54.                 //矩形区域宽(为4的倍数)
  55.                    lnewwidth=(int)(max(fabs(dstx1-dstx3),fabs(dstx2-dstx4))+0.5);
  56.                
  57.                 while(lnewwidth%4!=0)
  58.                 {
  59.                     lnewwidth++;
  60.                 }
  61.                
  62.                 //矩形区域长
  63.                 lnewheight=(int)(max(fabs(dsty1-dsty3),fabs(dsty2-dsty4))+0.5);

  64.                 while(lnewheight%4!=0)
  65.                 {
  66.                     lnewheight++;
  67.                 }

  68.                 float a,b,c,d;
  69.                 a=(float)(width1-1)/2;
  70.                 b=(float)(height1-1)/2;
  71.                 c=(float)(lnewwidth-1)/2;
  72.                 d=(float)(lnewheight-1)/2;

  73.                 BYTE * buffermemory=new BYTE[3*lnewwidth*lnewheight];
  74.                 if(buffermemory == NULL) AfxMessageBox(_T("内存分配错误!"));

  75.                 for(i=0;i
  76.                         for(j=0;j
  77.                         {
  78.                                 i0=(int)(-(float)(j) * fsin +(float)(i) * fcos + c*fsin - d*fcos + b +0.5);
  79.                                 j0=(int)((float)(j) * fcos +(float)(i) * fsin - c*fcos - d*fsin + a +0.5);

  80.                                 if((i0>=0)&&(i0<=height1-1)&&(j0>=0)&&(j0<=width1-1))
  81.                                 {
  82.                                         //(j0,i0)对应的点在未经平移和旋转的源像所在的矩形区域
  83.                                         *(buffermemory+3*(i*lnewwidth+j))=*(buffer+3*(i0*width1+j0));
  84.                                         *(buffermemory+3*(i*lnewwidth+j)+1)=*(buffer+3*(i0*width1+j0)+1);
  85.                                         *(buffermemory+3*(i*lnewwidth+j)+2)=*(buffer+3*(i0*width1+j0)+2);
  86.                                 }
  87.                                 else
  88.                                 {
  89.                                         *(buffermemory+3*(i*lnewwidth+j))=(BYTE)255;
  90.                                         *(buffermemory+3*(i*lnewwidth+j)+1)=(BYTE)255;
  91.                                         *(buffermemory+3*(i*lnewwidth+j)+2)=(BYTE)255;
  92.                                 }
  93.                         }//end for(i=0;i
  94.        
  95.         //改变源图像的一些属性值,如宽/高和图像大小(即整个数据区包含的字节数)
  96.         bih.biWidth = lnewwidth;        //m_bitmapinfoheader->biWidth=lnewwidth;
  97.         bih.biHeight = lnewheight;        //m_bitmapinfoheader->biHeight=lnewheight;
  98.         bih.biSizeImage = lnewwidth*lnewheight*3;        //m_bitmapinfoheader->biSizeImage=lnewwidth*lnewheight*3;
  99.   
  100.         //将源图像的数据区指针指向新的区域(即新的矩形区域)
  101.         //tempdib->SetData(buffermemory);
  102.         //Invalidate();
  103.         delete[]buffer;

复制代码


以上代码移植到WinCE上,编译通过,但是实际运行时(要旋转的图像大小为320×240),在
for(i=0;i   for(j=0;j 循环运行到i=162,j=320时,出现Data Abort错误,软件崩溃!

求解!!!
此帖出自WindowsCE论坛

最新回复

换一个极小的图试试~10X10的~  详情 回复 发表于 2009-5-19 01:30
点赞 关注
 

回复
举报

76

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
关注
先弄个小点的图试试怎么样 比如320*160
此帖出自WindowsCE论坛
 
 
 

回复

66

帖子

1

TA的资源

一粒金砂(初级)

板凳
 
出现这样的错误的原因,一般是内存越界面


LZ可以按LS所说试试
此帖出自WindowsCE论坛
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

4
 
引用 2 楼 91program 的回复:
出现这样的错误的原因,一般是内存越界面


LZ可以按LS所说试试

那如果我确实需要这么大的图像转换,那这个buffer[]数组该怎样定义大小呢?
此帖出自WindowsCE论坛
 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

5
 
把内存分配到堆上试试
此帖出自WindowsCE论坛
 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

6
 
引用 4 楼 xajhuang 的回复:
把内存分配到堆上试试


大哥,小弟不才,能否具体说说怎样“把buffer[]数组分配到堆上”?
此帖出自WindowsCE论坛
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

7
 
引用 4 楼 xajhuang 的回复:
把内存分配到堆上试试


用new分配的內存本來就是在堆上的.

樓主運行時跟一下, 看是否越界了.
此帖出自WindowsCE论坛
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

8
 
引用 6 楼 zhanzongru 的回复:
...
用new分配的內存本來就是在堆上的.

樓主運行時跟一下, 看是否越界了.


我把以上代码移植到WinCE上,编译通过,但是实际运行时(要旋转的图像大小为320×240),在
for(i=0;i   for(j=0;j 循环运行到i=162,j=320时,出现Data Abort错误,软件崩溃!
那怎么看越界呢?
此帖出自WindowsCE论坛
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

9
 
new 分配多点试试
此帖出自WindowsCE论坛
 
 
 

回复

56

帖子

0

TA的资源

一粒金砂(初级)

10
 
不知道你后面释放资源了没有,这段程序里面buffermemory没有释放
此帖出自WindowsCE论坛
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

11
 
引用 9 楼 happypay 的回复:
不知道你后面释放资源了没有,这段程序里面buffermemory没有释放


在最后一行有释放资源的语句啊:
delete[]buffer;

看来问题还是buffer[]空间不足
此帖出自WindowsCE论坛
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

12
 
你new了两个啊
BYTE * buffer=new BYTE[3*width1*height1];

BYTE * buffermemory=new BYTE[3*lnewwidth*lnewheight];

BYTE * dibdata1;
dibdata1 = DIBdata; 这两句好像也是伪初始化
此帖出自WindowsCE论坛
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

13
 
个人感觉空间分配倒没问题,因为有           
if(buffermemory == NULL) AfxMessageBox(_T("内存分配错误!"));

可能是处理过程中访问到了buffer或buffermemory之外的非法地址
此帖出自WindowsCE论坛
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

14
 

  1. BYTE * buffer=new BYTE[3*width1*height1];

  2. BYTE * buffermemory=new BYTE[3*lnewwidth*lnewheight];
  3. [code]
  4. 这两处分配可能有问题
  5. 你确定你的位图是24 bits每像素吗?我用的都是32位
  6. 而且扫描行是4字节对齐的,分配内存也得考虑

  7. BITMAPINFOHEADER的定义如下:
  8. [code]
  9. typedef struct tagBITMAPINFOHEADER {
  10.   DWORD biSize;
  11.   LONG biWidth; //宽,单位像素
  12.   LONG biHeight; //高,小于0表示从上到下位图
  13.   WORD biPlanes;
  14.   WORD biBitCount; //每像素bit数
  15.   DWORD biCompression;
  16.   DWORD biSizeImage;
  17.   LONG biXPelsPerMeter;
  18.   LONG biYPelsPerMeter;
  19.   DWORD biClrUsed;
  20.   DWORD biClrImportant;
  21. } BITMAPINFOHEADER;

复制代码


你应该分配:

  1. DWORD dwRowLen = (BITMAPINFOHEADER.biWidth * BITMAPINFOHEADER.biBitCount + 31) / 32 * 4; //扫描行是4字节对齐的
  2. BYTE * buffer=new BYTE[abs(BITMAPINFOHEADER.biHeight)* dwRowLen];
复制代码
此帖出自WindowsCE论坛
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

15
 
引用 13 楼 xdkui 的回复:

BYTE * buffer=new BYTE[3*width1*height1];

BYTE * buffermemory=new BYTE[3*lnewwidth*lnewheight];

这两处分配可能有问题
你确定你的位图是24 bits每像素吗?我用的都是32位
而且扫描行是4字节对齐的,分配内存也得考虑

BITMAPINFOHEADER的定义如下:

C/C++ code
typedef struct tagBITMAPINFOHEADER {
  DWORD biSize;
  LONG biWidth; //宽,单位像素
  LONG biHeight; //高,小于0表示从上到下位…

支持一下

循环运行到i=162,j=320时 ---j居然能到320,看得莫名其妙

旋转代码网上有现成的!
此帖出自WindowsCE论坛
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

16
 
引用 14 楼 constantine 的回复:

旋转代码网上有现成的!



我这个也是从网上copy来的啊。

我的bmp文件是16位色深的,看来13楼xdkui大哥的指点,我得好好看看。

现在手头还在忙一个小项目,有机会在看看了,希望经过大家的指点,我的小问题OK咯!
此帖出自WindowsCE论坛
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

17
 
debug看看
此帖出自WindowsCE论坛
 
 
 

回复

65

帖子

0

TA的资源

一粒金砂(初级)

18
 
应该是越界了~~
因为旋转后的图片会比原图大~~
LZ应该以最长对角线的长度为基础来分配合适内存!
此帖出自WindowsCE论坛
 
 
 

回复

84

帖子

0

TA的资源

一粒金砂(初级)

19
 
不懂,帮顶一下
此帖出自WindowsCE论坛
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

20
 
换一个极小的图试试~10X10的~
此帖出自WindowsCE论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表