初级会员

- 积分
- 124
- 金钱
- 124
- 注册时间
- 2015-4-21
- 在线时间
- 23 小时
|
5金钱
本帖最后由 易星 于 2016-1-6 12:19 编辑
[size=10.5000pt]本人想要直接用摄像头的数据,进行bmp编码,不过最后保存的图片有问题

[size=10.5000pt]图片上方显示的不对,显示的是下方的一部分,而且还分成两块,搞不清楚什么情况,求大神指教。
但是我用屏幕截屏的方法没有问题。
用的是OV7725,对比度没调好,只有英文的数据手册,没敢调,用的别人的配置,照片显示的不好。
部分程序如下:
int main(void)
{
u8 buf = 0;
u8 *p = &buf;
u8 i = 0;
u8 res, key;
u8 *pname; //带路径的文件名
u16 *p_show;
u8 sd_ok = 1; //0,sd卡不正常;1,SD卡正常
u32 j;
u16 color;
hardware_init(); //初始化
LCD_Scan_Dir(DIR_DULR); //从下到上,从左到右,横屏显示
LCD_Clear(BLUE2);
LCD_SetColors(WHITE, GREEN);
// while(font_init()) //检查字库
// Show_StringChar(60, 50, (u8 *)"Font Error!", 2, 1);
Show_StringChar(30, 0, (u8 *)"Camera Test", 2, 1);
res = f_mkdir("0:/PHOTO"); //创建PHOTO文件夹
if((res != FR_EXIST) && (res != FR_OK)) //发生了错误
{
Show_StringChar(30, 40, (u8 *)"SD_Card Error", 2, 1);
delay_ms(200);
Show_StringChar(30, 60, (u8 *)"Camera Error", 2, 1);
sd_ok = 0;
}
else
{
Show_StringChar(30, 40, (u8 *)"SD_Card OK", 2, 1);
delay_ms(200);
Show_StringChar(30, 60, (u8 *)"USER hotograph", 2, 1);
sd_ok = 1;
}
pname = mymalloc(SRAMIN, 30); //为带路径的文件名分配30个字节的内存
while(pname == NULL) //内存分配出错
{
Show_StringChar(30, 80, (u8 *)"Malloc Error!", 2, 1);
delay_ms(200);
}
buf = OV7725_Init();
while(buf) //初始化OV7725
{
Show_StringChar(30, 80, (u8 *)"OV7725 Error!!", 2, 1);
i = buf;
sprintf((char*)p, "Error Code:%d", i);
Show_StringChar(30, 100, p, 2, 1);
delay_ms(200);
}
Show_StringChar(30, 80, (u8 *)"OV7725 OK", 2, 1);
delay_ms(1000);
LCD_Clear(BLACK);
EXTI_Config(GPIO_C, 3, RISING); //任意边沿触发
NVIC_Init(2, 0, 0, EXTI3_IRQn); //抢占0,子优先级0,组2
LCD_Set_Window(0, 0, 320, 240);
while(1)
{
key = Get_KeyState();
if(key == Key_User)
{
p_show = (u16*)mymalloc(SRAMEX, 190000);
while(p_show == NULL) //内存分配出错
{
Show_StringChar(30, 0, (u8 *)"Malloc Error!", 2, 1);
delay_ms(200);
}
LCD_SetCursor(0x00, 0x0000); //设置光标位置
LCD_WriteRAM_Prepare(); //开始写入GRAM
if(ov_sta == 2)
{
FIFO_RRST_L(); //开始复位读指针
FIFO_RCLK_L();
FIFO_RCLK_H();
FIFO_RCLK_L();
FIFO_RRST_H(); //复位读指针结束
FIFO_RCLK_H();
for(j = 0; j < 76800; j ++) //320*240
{
FIFO_RCLK_L();
color = GPIOC->IDR & 0XFF00; //读数据
FIFO_RCLK_H();
FIFO_RCLK_L();
color |= (GPIOC->IDR >> 8) & 0X00FF; //读数据
FIFO_RCLK_H();
LCD->LCD_RAM = color; //从这里显示的图片是正常的
p_show[j] = color;
}
EXTI-> R = 1 << 8; //清除LINE8上的中断标志位
ov_sta = 0; //开始下一次采集
ov_frame ++;
}
delay_ms(1800);
delay_ms(1800);
LCD_Clear(BLACK);
if(sd_ok)
{
camera_new_pathname(pname); //得到文件名
res = bmp_encode_direct(pname, p_show, 0, 0, 320, 240, 0);
if(res) //拍照有误
{
Show_StringChar(30, 20, (u8 *)"Write File Error", 2, 1);
sprintf((char*)p, "Error Code:0X%x", res);
Show_StringChar(30, 100, p, 2, 1);
}
else
{
Show_StringChar(30, 20, (u8 *)"photograph succeed", 2, 1);
sprintf((char*)p, "Save:%s", pname);
Show_StringChar(30, 40, p, 2, 1);
delay_ms(100);
}
}
else //提示SD卡错误
{
Show_StringChar(30, 40, (u8 *)"SD_Card Error", 2, 1);
Show_StringChar(30, 60, (u8 *)"Camera Error", 2, 1);
}
myfree(SRAMEX, p_show);
}
else
delay_ms(10);
i ++;
if(i >= 50)
{
i = 0;
led1_negation();
}
}
}
u8 bmp_encode_direct(u8 *filename, u16 *buf, u16 x, u16 y, u16 width, u16 height, u8 mode)
{
FIL* f_bmp;
u16 bmpheadsize; //bmp头大小
BITMAPINFO hbmp; //bmp头
u8 res = 0;
u16 tx, ty; //图像尺寸
u16 *databuf; //数据缓存区地址
u16 pixcnt; //像素计数器
u16 bi4width; //水平像素字节数
if((width == 0) || (height == 0))
return PIC_WINDOW_ERR; //区域错误
if((x + width - 1) > lcddev.width)
return PIC_WINDOW_ERR; //区域错误
if((y + height - 1) > lcddev.height)
return PIC_WINDOW_ERR; //区域错误
#if BMP_USE_MALLOC == 1 //使用malloc
databuf = (u16*)mymalloc(SRAMIN, 1024); //开辟至少bi4width大小的字节的内存区域 ,对240宽的屏,480个字节就够了
if(databuf == NULL)
return PIC_MEM_ERR; //内存申请失败.
f_bmp = (FIL *)mymalloc(SRAMIN, sizeof(FIL)); //开辟FIL字节的内存区域
if(f_bmp == NULL) //内存申请失败
{
myfree(SRAMIN, databuf);
return PIC_MEM_ERR;
}
#else
databuf = (u16*)bmpreadbuf;
f_bmp = &f_bfile;
#endif
bmpheadsize = sizeof(hbmp); //得到bmp文件头的大小
mymemset((u8*)&hbmp, 0, sizeof(hbmp)); //置零空申请到的内存
hbmp.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); //信息头大小
hbmp.bmiHeader.biWidth = width; //bmp的宽度
hbmp.bmiHeader.biHeight = height; //bmp的高度
hbmp.bmiHeader.biPlanes = 1; //恒为1
hbmp.bmiHeader.biBitCount = 16; //bmp为16位色bmp
hbmp.bmiHeader.biCompression = BI_BITFIELDS; //每个象素的比特由指定的掩码决定
hbmp.bmiHeader.biSizeImage = ((hbmp.bmiHeader.biHeight * hbmp.bmiHeader.biWidth) * hbmp.bmiHeader.biBitCount) / 8; //bmp数据区大小
hbmp.bmfHeader.bfType = ((u16)'M' << 8)+ 'B'; //BM格式标志
hbmp.bmfHeader.bfSize = bmpheadsize + hbmp.bmiHeader.biSizeImage; //整个bmp的大小
hbmp.bmfHeader.bfOffBits = bmpheadsize; //到数据区的偏移
hbmp.RGB_MASK[0] = 0X00F800; //红色掩码
hbmp.RGB_MASK[1] = 0X0007E0; //绿色掩码
hbmp.RGB_MASK[2] = 0X00001F; //蓝色掩码
if(mode == 1)
res = f_open(f_bmp, (const TCHAR*)filename, FA_READ | FA_WRITE); //尝试打开之前的文件
if((mode == 0) || (res == 0x04))
res = f_open(f_bmp, (const TCHAR*)filename, 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 == FR_OK) //创建成功
{
res = f_write(f_bmp, (u8*)&hbmp, bmpheadsize, &bw); //写入BMP首部
for(ty = y + height - 1; hbmp.bmiHeader.biHeight; ty--)
{
pixcnt = 0;
for(tx = x; pixcnt != (bi4width / 2);)
{
if(pixcnt < hbmp.bmiHeader.biWidth)
{
LCD_Fast_DrawPoint(tx, ty, buf[ty * 320 + tx]); //这里显示的图片不正常,就是图片上显示的那种
databuf[pixcnt] = buf[ty * 320 + tx];
}
else
databuf[pixcnt] = 0Xffff; //补充白色的像素
pixcnt ++;
tx ++;
}
LCD_ShowNum(0, 0, pixcnt, 2, 1);
hbmp.bmiHeader.biHeight --;
res = f_write(f_bmp, (u8*)databuf, bi4width, &bw); //写入数据
}
f_close(f_bmp);
}
#if BMP_USE_MALLOC == 1 //使用malloc
myfree(SRAMIN, databuf);
myfree(SRAMIN, f_bmp);
#endif
return res;
}
其余的程序与原子哥的差不多
|
-
|