查看: 3227|回复: 1

[原创] 野火i.MX RT1052 MINI试用-10 修正bug--bmp格式图像保存

[复制链接]
  • TA的每日心情
    开心
    2019-6-20 14:08
  • 签到天数: 43 天

    连续签到: 1 天

    [LV.5]常住居民I

    发表于 2018-8-8 23:01:17 | 显示全部楼层 |阅读模式
    分享到:
             今天抽空又拿起之前RT1052的工程分析了一下(上周带孩子出去旅游,所以休整了一周时间),将之前工程里含有的bug给kill掉了(参看前一贴https://www.cirmall.com/bbs/thread-100854-1-1.html),现在能完整的将ov5640拍摄的图像保存到sd中,而且写sd卡的速度也很快。接下来的工作就是看能否给lcd添加触摸功能的按键以及设计菜单了,这些工作量挺大的,还得等等原子/野火的资料。废话少说,直接上图。       此次试验,我连续进行了3次拍摄工作,以验证程序,当然更多次应该更合适些,但还是偷懒了。
           说明:    (1)图1 -   图3  为手机拍摄的LCD显示的图片。
                         (2)图4 -   图6  为SD卡中保存的摄像头拍摄的图片。
                         (3)图7    串口输出截图
                         (4)图8   SD中内容的截图
                                            a.jpg
                                                            图1      LCD上显示魔方
                                            b.jpg
                                                          图2    LCD上显示保证盒
                                            c.jpg
                                                         图3      LCD上显示9V电池
                                            PIC_1913946.jpg
                                                         图4     对应图1的SD卡中保存的图片
                                            PIC_1913947.jpg
                                                         图5    对应图2的SD卡中保存的图片
                                            PIC_1913948.jpg
                                                        图6     对应图3的SD卡中保存的图片

                                            1.png
                                                         图7     串口输出信息截图
                                            2.png

                                                           图8     SD中内容的截图
             实验分析:
             (1)   因为光线的问题,SD卡中保存的图片(图4~图6),相对于手机拍摄LCD显示的图片(图1~图3)亮度较暗,但是色彩还是比较分明的(此次LCD采用的RGB565模式)。如图1~图3所示,LCD显示的左边有bug,这个应该是显存刷新时产生的(也就是显存驱动的问题,如果按下reset,那么有时会显示完整的图像,这个bug有待进一步解决),但是保存的图像完整无缺。
              (2) 如图7所示,第二次串口输出差为2MB,这个应该也是个bug,因为每张图片(摄像头设定APP_CAMERA_HEIGHT= 480和APP_CAMERA_WIDTH=800,即图片大小为800*480,每个像素点为24bit-RGB三色构成)实际800*480*24/8=1152000(1.09MB)。
               (3)如图8所示,橙色圈画显示的是sd卡中保存的bmp格式的文件,因为爱板网不允许上传bmp文件,所以我又倒了一下文件格式。
               (4) 修改的地方,刚看了下前一贴,才发现截屏算法代码没有贴全(不知道为什么,当初是全贴了的),现在补充完整。
    1. /**
    2. * @brief  设置截取BMP图片
    3. * @param  x :截取区域的起点x坐标
    4. * @param  y :截取区域的起点y坐标
    5. * @param  Width :区域宽度
    6. * @param  Height :区域高度
    7. * @retval ÎÞ
    8.   *   该参数为以下值之一:
    9.   *     @arg 0 : 截图成功
    10.   *     @arg -1 :截图失败
    11. */
    12. int Screen_Shot( uint16_t x, uint16_t y, uint16_t Width, uint16_t Height, char * filename)
    13. {
    14.         /* bmp  文件头54个字节 */
    15.         unsigned char header[54] =
    16.         {
    17.                 0x42, 0x4d, 0, 0, 0, 0,
    18.                 0, 0, 0, 0, 54, 0,
    19.                 0, 0, 40,0, 0, 0,
    20.                 0, 0, 0, 0, 0, 0,
    21.                 0, 0, 1, 0, 24, 0,
    22.                 0, 0, 0, 0, 0, 0,
    23.                 0, 0, 0, 0, 0,
    24.                 0, 0, 0, 0, 0,
    25.                 0, 0, 0, 0, 0,
    26.                 0, 0, 0
    27.         };
    28.        
    29.         int i;
    30.         int j;
    31.         long file_size;     
    32.         long width;
    33.         long height;
    34.         unsigned char r,g,b;       
    35.         unsigned int mybw;
    36.         unsigned int read_data;
    37.         char kk[4]={0,0,0,0};
    38.        
    39.         uint8_t ucAlign;//
    40.        
    41.         /* 宽*高 + 补充的字节 + 头部信息 */
    42.         file_size = (long)Width * (long)Height * 3 + Height*(Width%4) + 54;               

    43.         /* 文件大小 4个字节 */
    44.         header[2] = (unsigned char)(file_size &0x000000ff);
    45.         header[3] = (file_size >> 8) & 0x000000ff;
    46.         header[4] = (file_size >> 16) & 0x000000ff;
    47.         header[5] = (file_size >> 24) & 0x000000ff;
    48.        
    49.         /* 位图宽4个字节 */
    50.         width=Width;       
    51.         header[18] = width & 0x000000ff;
    52.         header[19] = (width >> 8) &0x000000ff;
    53.         header[20] = (width >> 16) &0x000000ff;
    54.         header[21] = (width >> 24) &0x000000ff;
    55.        
    56.         /* 位图高 4个字节 */
    57.         height = Height;
    58.         header[22] = height &0x000000ff;
    59.         header[23] = (height >> 8) &0x000000ff;
    60.         header[24] = (height >> 16) &0x000000ff;
    61.         header[25] = (height >> 24) &0x000000ff;
    62.                
    63.         /* 新建一个文件 */
    64.         bmpres = f_open( &bmpfsrc , (char*)filename, FA_CREATE_ALWAYS | FA_WRITE );
    65.        
    66.         /* 新建一个文件之后要先关闭再打开才能写入 */
    67.         f_close(&bmpfsrc);
    68.                
    69.         bmpres = f_open( &bmpfsrc , (char*)filename,  FA_OPEN_EXISTING | FA_WRITE);

    70.         if ( bmpres == FR_OK )
    71.         {   
    72.                 /* 将预先定义好的bmp头部信息写进文件里面 */
    73.                 bmpres = f_write(&bmpfsrc, header,sizeof(unsigned char)*54, &mybw);               
    74.                        
    75.                 ucAlign = Width % 4;
    76.                
    77.                 for(i=0; i<Height; i++)                                       
    78.                 {
    79.                         for(j=0; j<Width; j++)  
    80.                         {       
    81.                
    82.                                 //read_data = ILI9341_GetPointPixel ( x + j, y + Height - 1 - i );                                       
    83.                                 //read_data = *(__IO uint32_t*) (activeFrameAddr + (APP_BPP*((x + j ) + LCD_PIXEL_WIDTH *(y + Height - 1 - i)))) ;               // 前一个帖子中bmp图片的bug的处理公式,当然可以用它来一幅图重复显示多个对象
    84.                                 read_data = *(__IO uint32_t*) (activeFrameAddr + (APP_BPP*((x + j )/2 + LCD_PIXEL_WIDTH *(y + Height - 1 - i)/2))) ;                               // 修改后的公式

    85.                                 r =  GETR_FROM_RGB16(read_data);
    86.                                 g =  GETG_FROM_RGB16(read_data);
    87.                                 b =  GETB_FROM_RGB16(read_data);

    88.                                 bmpres = f_write(&bmpfsrc, &b,sizeof(unsigned char), &mybw);
    89.                                 bmpres = f_write(&bmpfsrc, &g,sizeof(unsigned char), &mybw);
    90.                                 bmpres = f_write(&bmpfsrc, &r,sizeof(unsigned char), &mybw);
    91.                         }
    92.                                
    93. if( ucAlign )                                /* 如果不是4字节对齐 */
    94.     bmpres = f_write ( & bmpfsrc, kk, sizeof(unsigned char) * ( ucAlign ), & mybw );

    95.                 }/*截屏完毕 */

    96.                 f_close(&bmpfsrc);
    97.                
    98.                 return 0;
    99.                
    100.         }       
    101.         else/* 截屏失败 */
    102.   return -1;

    103. }
    复制代码



    回复

    使用道具 举报

  • TA的每日心情
    难过
    2021-2-27 22:16
  • 签到天数: 1568 天

    连续签到: 1 天

    [LV.Master]伴坛终老

    发表于 2018-8-24 22:56:32 | 显示全部楼层
    写的不错,看看了
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-4-19 19:44 , Processed in 0.129580 second(s), 17 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.