rgb888的bmp图片任意位置截图后保存为24位BMP图片
求各位大侠帮忙分析一下小弟的程序问题出现在哪里。我现在是摄像头模组采集到的数据是YUV数据,我先将yuv数据转成rgb888的数据,再再rgb888的数据上截取我要的数据,最后保存成bmp图片。现在整帧图片的YUV数据转RGB888是没有问题的,小弟已经试过。但在整副bmp图片的某一位置截取一小块图片出来就总也不成,图片是乱码。下边是小弟的程序,请大家帮忙分析一下:
#defineIMAGEWIDTH320
#defineIMAGEHEIGHT 240
u8* pbuf11;
u8 *RGBbuff11=0;
u8 *RGBbuff12=0;
//返回值:0,成功
// 其他,错误代码
u8 GC2145_jpg_photo(u8 *pname,u16 x,u16 y,u16 width,u16 high)
{
FIL* f_jpg;
u8 res=0;
u32 bwr;
u32 i,j;
u32* RGBbuff;
u32 t=0;
int size=320*240*3;//每个像素点3个字节
long count ;
u16 headsize; //bmp头大小
u16 bi4width; //水平像素字节数
int Y1, U1, V1, Y2, alpha1, alpha2, R1, G1, B1, R2, G2, B2;
int C1, D1, E1, C2;
BITMAPINFO hbmp; //bmp头
//位图第二部分,数据信息
hbmp.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
hbmp.bmiHeader.biWidth=width;
hbmp.bmiHeader.biHeight=high;//bmp 图片从最后一个点开始扫描,显示时图片是倒着的,所以用-height,这样图片就正了
hbmp.bmiHeader.biPlanes=1;//为1,不用改
hbmp.bmiHeader.biBitCount=24;
hbmp.bmiHeader.biCompression=0;//不压缩
hbmp.bmiHeader.biSizeImage=hbmp.bmiHeader.biHeight*hbmp.bmiHeader.biWidth*hbmp.bmiHeader.biBitCount/8;//bmp数据区大小
hbmp.bmiHeader.biXPelsPerMeter=0;//像素每米
hbmp.bmiHeader.biYPelsPerMeter=0;
hbmp.bmiHeader.biClrUsed=0;//已用过的颜色,24位的为0
hbmp.bmiHeader.biClrImportant=0;//每个像素都重要
headsize=sizeof(BITMAPINFOHEADER)+sizeof(BITMAPFILEHEADER);
//位图第一部分,文件信息
hbmp.bmfHeader.bfType=((u16)'M'<<8)+'B';//BM格式标志//(WORD)0x4d42;//bm
hbmp.bmfHeader.bfSize=(hbmp.bmiHeader.biHeight*hbmp.bmiHeader.biWidth*hbmp.bmiHeader.biBitCount/8)+headsize;// data size first section size second section size
hbmp.bmfHeader.bfReserved1=0;//reserved
hbmp.bmfHeader.bfReserved2=0;
hbmp.bmfHeader.bfOffBits=headsize;//真正的数据的位置
f_jpg=(FIL *)mymalloc(SRAMIN,sizeof(FIL)); //开辟FIL字节的内存区域
if(f_jpg==NULL)return 0XFF; //内存申请失败.
ov2640_mode=1;
sw_ov2640_mode(); //切换为OV2640模式
dcmi_rx_callback=jpeg_dcmi_rx_callback;//回调函数
DCMI_DMA_Init((u32)jpeg_buf0,(u32)jpeg_buf1,jpeg_dma_bufsize,DMA_MemoryDataSize_Word,DMA_MemoryInc_Enable);//DCMI DMA配置(双缓冲模式)
DCMI_Start(); //启动传输
jpeg_data_len=0;
while(jpeg_data_ok!=1); //等待第一帧图片采集完
jpeg_data_ok=2; //忽略本帧图片,启动下一帧采集
while(jpeg_data_ok!=1); //等待第二帧图片采集完
jpeg_data_ok=2; //忽略本帧图片,启动下一帧采集
while(jpeg_data_ok!=1); //等待第三帧图片采集完,第三帧,才保存到SD卡去.
DCMI_Stop(); //停止DMA搬运
ov2640_mode=0;
sw_sdcard_mode(); //切换为SD卡模式
res=f_open(f_jpg,(const TCHAR*)pname,FA_WRITE|FA_CREATE_NEW);//模式0,或者尝试打开失败,则创建新文件
if((hbmp.bmiHeader.biWidth*2)%4)//水平像素(字节)不为4的倍数
{
bi4width=((hbmp.bmiHeader.biWidth*2)/4+1)*4;//实际要写入的宽度像素,必须为4的倍数.
}else bi4width=hbmp.bmiHeader.biWidth*2; //刚好为4的倍数
if(res==0)
{
res=f_write(f_jpg,(u8*)&hbmp,headsize,&bw);//写入BMP首部
printf("jpeg data size:%d\r\n",jpeg_data_len*4);//串口打印JPEG文件大小
pbuf11=(u8*)jpeg_data_buf+32;
//////////////////////////////////整张YUV转RGB888///////////////////////////////////////////////////////////////////
for ( i=0; i<IMAGEHEIGHT; ++i)
{
for (j=0; j<IMAGEWIDTH/2; ++j)
{
Y1 = *(pbuf11+i*IMAGEWIDTH*2+j*4);
U1 = *(pbuf11+i*IMAGEWIDTH*2+j*4+1);
Y2 = *(pbuf11+i*IMAGEWIDTH*2+j*4+2);
V1 = *(pbuf11+i*IMAGEWIDTH*2+j*4+3);
C1 = Y1-16;
C2 = Y2-16;
D1 = U1-128;
E1 = V1-128;
R1 = ((298*C1 + 409*E1 + 128)>>8>255 ? 255 : (298*C1 + 409*E1 + 128)>>8);
G1 = ((298*C1 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C1 - 100*D1 - 208*E1 + 128)>>8);
B1 = ((298*C1+516*D1 +128)>>8>255 ? 255 : (298*C1+516*D1 +128)>>8);
R2 = ((298*C2 + 409*E1 + 128)>>8>255 ? 255 : (298*C2 + 409*E1 + 128)>>8);
G2 = ((298*C2 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C2 - 100*D1 - 208*E1 + 128)>>8);
B2 = ((298*C2 + 516*D1 +128)>>8>255 ? 255 : (298*C2 + 516*D1 +128)>>8);
*(RGBbuff11+(IMAGEHEIGHT-i-1)*IMAGEWIDTH*3+j*6+2) = R1<0 ? 0 : R1;
*(RGBbuff11+(IMAGEHEIGHT-i-1)*IMAGEWIDTH*3+j*6+1) = G1<0 ? 0 : G1;
*(RGBbuff11+(IMAGEHEIGHT-i-1)*IMAGEWIDTH*3+j*6) = B1<0 ? 0 : B1;
*(RGBbuff11+(IMAGEHEIGHT-i-1)*IMAGEWIDTH*3+j*6+5) = R2<0 ? 0 : R2;
*(RGBbuff11+(IMAGEHEIGHT-i-1)*IMAGEWIDTH*3+j*6+4) = G2<0 ? 0 : G2;
*(RGBbuff11+(IMAGEHEIGHT-i-1)*IMAGEWIDTH*3+j*6+3) = B2<0 ? 0 : B2;
}
// res=f_write(f_jpg,RGBbuff11+(IMAGEHEIGHT-i-1)*IMAGEWIDTH*3,IMAGEWIDTH*3,&bwr);
}
//////////////////////////////////////截取图片///////////////////////////////////////////////////////////
for(i=(y+high);i>y;i--)
// for(i=y;i<(y+high);i++)
{
t=0;
for(j=x*3;j<(x+width)*3;j++)
{
if(t<width*3)
{
*(RGBbuff12+t) =*(RGBbuff11+i*240*3+j);
// *(RGBbuff12+t*3+2) =*(RGBbuff11+i*240*3+j+2);
// *(RGBbuff12+t*3+1) =*(RGBbuff11+i*240*3+j+1);
// *(RGBbuff12+t*3) =*(RGBbuff11+i*240*3+j);
}
t++;
// *(RGBbuff12+t*6+1) =*(RGBbuff11+t*6+1);
// *(RGBbuff12+t*6) = *(RGBbuff11+t*6);
// *(RGBbuff12+t*6+5) =*(RGBbuff11+t*6+5);
// *(RGBbuff12+t*6+4) = *(RGBbuff11+t*6+4);
// *(RGBbuff12+t*6+3) = *(RGBbuff11+t*6+3);
}
res=f_write(f_jpg,(u8*)RGBbuff12,width*3,&bwr);
}
//res=f_write(f_jpg,(u8*)RGBbuff12,high*width*3,&bwr);
}
f_close(f_jpg);
DCMI_DMA_Init((u32)&LCD->LCD_RAM,0,1,DMA_MemoryDataSize_HalfWord,DMA_MemoryInc_Disable);//DCMI DMA配置
myfree(SRAMIN,f_jpg);
// myfree(SRAMIN,f_jpg1);
myfree(SRAMEX,RGBbuff11);
myfree(SRAMEX,RGBbuff12);
return res;
}
页:
[1]