jdzjk06 发表于 2016-3-21 12:08:17

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]
查看完整版本: rgb888的bmp图片任意位置截图后保存为24位BMP图片