IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 基于C语言实现的单片机传输的VGA图像数据生成bmp文件 -> 正文阅读

[C++知识库]基于C语言实现的单片机传输的VGA图像数据生成bmp文件

基于C语言实现的单片机传输的VGA图像数据生成bmp文件

参考硬件:stm32(但其实是个能带动ov7725有串口的单片机就行)、ov7725,上位机(电脑)
实现原理:ov7725通常输出QVGA/VGA的240*320图像,一个像素点由RBG565(16bits)表示,但常用的电脑bmp像素由BGR888构成(又称bmp24),这需要小小的进行一下像素点的数据处理,然后就是编写电脑串口和bmp文件头实现串口数据接收以及自动生成bmp
建议搜索查阅:因为有点想偷懒,把编写时涉及到的知识点罗列一下(当初在csdn一个个查的,都可以查到很好的解说昂),不再详细解说,见谅

  1. c语言实现rgb565转bmp24(实现像素点的格式变化)
  2. c语言调用windows自带库编写串口(实现串口在c语言里的调用,可以存到想存的数组里,不然你把数据用串口助手传到txt里面还真不好弄,他那个是utf8格式)
  3. c语言生成bmp文件(教你打造bmp文件头,bmp24的文件头最简单了,所以建议先做好数据处理)
  4. 其他

下面是程序代码,需要更改的地方我用中文表达出来了

#include <stdio.h>  
#include <windows.h>
#include   <stdlib.h>
#include <string.h>  
#include <conio.h>  
#include <winnt.h>  
#include "rgb2bmp.h"
int main()
{
int cnt;
//char* txtfile="C:\\Users\\17001\\Desktop\\compare2.txt" ;
DWORD dwLength;//unsigned long 
unsigned short recvBuf[76800];//定义一个x个16位的数组 
DWORD dwactlen;//unsigned long 
char psendbuf[32] = "test\n";//定义字符串数组 
char ch;//定义字符型变量ch 
DCB myDCB;//结构体数组,常用来定义串口 
HANDLE m_hComm;//定义一个句柄 
m_hComm = CreateFile(
"COM3:",//要打开的文件的名字 (修改为com3) 
GENERIC_READ | GENERIC_WRITE,   //对设备允许读和写  
0,                          //独占方式(非共享模式)  
NULL,
OPEN_EXISTING,              //打开而不是创建(创建方式),要求文件必须已存在  
0,
NULL
);
if (m_hComm == (HANDLE)-1)                          //打开串口失败返回  
{
printf("打开串口失败");
return 0;
}
//得到打开串口的当前属性参数,修改后再重新设置串口。  


if (!GetCommState(m_hComm, &myDCB))
{
printf("GetCommState error");
return FALSE;
}


//设置串口参数  
myDCB.BaudRate = CBR_115200;   // 设置波特率115200  
myDCB.fBinary = TRUE; // 设置二进制模式,此处必须设置TRUE  
myDCB.fParity = NOPARITY; // 修改为无奇偶校验 
myDCB.fOutxCtsFlow = FALSE;  // No CTS output flow control  
myDCB.fOutxDsrFlow = FALSE;  // No DSR output flow control  
myDCB.fDtrControl = DTR_CONTROL_DISABLE; // No DTR flow control  
myDCB.fDsrSensitivity = FALSE; // DSR sensitivity  
myDCB.fTXContinueOnXoff = TRUE; // XOFF continues Tx  
myDCB.fOutX = FALSE;     // No XON/XOFF out flow control  
myDCB.fInX = FALSE;        // No XON/XOFF in flow control  
myDCB.fErrorChar = FALSE;    // Disable error replacement  
myDCB.fNull = FALSE;  // Disable null stripping  
myDCB.fRtsControl = RTS_CONTROL_DISABLE;   //No RTS flow control  
myDCB.fAbortOnError = FALSE;  // 当串口发生错误,并不终止串口读写  
myDCB.ByteSize = 8;   // 数据位,范围:4-8  
myDCB.Parity = NOPARITY; // 无校验模式  
myDCB.StopBits = ONESTOPBIT;   // 1位停止位  
//设置串口参数  
if (!SetCommState(m_hComm, &myDCB))
{
printf("SetCommState error");
return FALSE;
}
SetupComm(m_hComm, 1024, 1024);//设置串口的输入/输出缓冲区大小
PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR);
COMMTIMEOUTS TimeOuts;
//设定读超时
TimeOuts.ReadIntervalTimeout = 1000;
TimeOuts.ReadTotalTimeoutMultiplier = 500;
TimeOuts.ReadTotalTimeoutConstant = 5000;
//设定写超时
TimeOuts.WriteTotalTimeoutMultiplier = 500;
TimeOuts.WriteTotalTimeoutConstant = 2000;
SetCommTimeouts(m_hComm, &TimeOuts); //设置超时 !mportant




/*FILE *p = fopen(txtfile,"w") ;
if (p == NULL)
	   {
       printf("open new file failed.n");
       return -1;
    	}*/ 
 
ReadFile(m_hComm, recvBuf, 76800*2, &dwLength, NULL);
/*for(cnt=0;cnt<76800;cnt++)
{
	fprintf(p,"%d\t",recvBuf[cnt]);  
}
fclose(p); */ 
PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR);//清除输出输入缓冲区 



CloseHandle(m_hComm); //m_hComm是CreateFile函数返回的串口句柄。 
 
/*convert阶段*/
int nWidth=320;
int nHeight=240;
char* newFile="C:\\Users\\17001\\Desktop\\rgb_new8.bmp";//改成你的路径名和想生成的文件名.bmp 
long nData=nWidth*nHeight;//320*240个像素点,long-32bits
long total =nWidth*nHeight*3;//320*240*2字节数 
unsigned char* pVisit=(unsigned char*)malloc(total*sizeof(char));//放入新的8位数组里 ,开辟新的数组空间
unsigned char* tmp=pVisit;//记录这个未被修改的指针
unsigned short* rgb_buffer=(unsigned short*)recvBuf;//定义一个可变指针赋值数组地址 

long i=0;//32bits 
unsigned char R,G,B;
while(i<nData)
	{

		 B = *rgb_buffer&0x1f;//取5位 
    G = (*rgb_buffer>>5)&0x3f;//取6位 
    R = (*rgb_buffer>>11)&0x1f;//取5位 
    B = B<<3;//*8
    G = G<<2;//*4
    R = R<<3;//*8
      *pVisit=B;pVisit++;
      *pVisit=G;pVisit++;
      *pVisit=R;pVisit++;
      rgb_buffer++;
      i++; 

	//	printf("%d\n",i);
	 } 	  
printf("read over.nData%ldn",nData);  
/*写阶段*/ 
FILE *result = fopen(newFile,"wb") ;
if (result == NULL)
	   {
       printf("open new file failed.n");
       return -1;
    	}
RGB2BMP(tmp,nWidth,nHeight,result); 
fclose(result);




return 0;
}

以下是头文件,负责生成bmp

//rgb2bmp.h文件
#include <stdio.h>
typedef unsigned char  BYTE;
typedef unsigned short WORD;
// BMP图像各部分说明如下
/***********
    第一部分    位图文件头
该结构的长度是固定的,为14个字节,各个域的依次如下:
    2byte   :文件类型,必须是0x4d42,即字符串"BM"。
    4byte   :整个文件大小
    4byte   :保留字,为0
    4byte   :从文件头到实际的位图图像数据的偏移字节数。
*************/
typedef struct
{    long imageSize;
    long blank;
    long startPosition;
}BmpHead;
/*********************
/*********************
第二部分    位图信息头
该结构的长度也是固定的,为40个字节,各个域的依次说明如下:
    4byte   :本结构的长度,值为40
    4byte   :图像的宽度是多少象素。
    4byte   :图像的高度是多少象素。
    2Byte   :必须是1。
    2Byte   :表示颜色时用到的位数,常用的值为1(黑白二色图)、4(16色图)、8(256色图)、24(真彩色图)。
    4byte   :指定位图是否压缩,有效值为BI_RGB,BI_RLE8,BI_RLE4,BI_BITFIELDS。Windows位图可采用RLE4和RLE8的压缩格式,BI_RGB表示不压缩。
    4byte   :指定实际的位图图像数据占用的字节数,可用以下的公式计算出来:
     图像数据 = Width' * Height * 表示每个象素颜色占用的byte数(即颜色位数/8,24bit图为3,256色为1)
     要注意的是:上述公式中的biWidth'必须是4的整数倍(不是biWidth,而是大于或等于biWidth的最小4的整数倍)。
     如果biCompression为BI_RGB,则该项可能为0。
    4byte   :目标设备的水平分辨率。
    4byte   :目标设备的垂直分辨率。
    4byte   :本图像实际用到的颜色数,如果该值为0,则用到的颜色数为2的(颜色位数)次幂,如颜色位数为8,2^8=256,即256色的位图
    4byte   :指定本图像中重要的颜色数,如果该值为0,则认为所有的颜色都是重要的。
***********************************/
typedef struct
  
{
    long    Length;
    long    width;
    long    height;
    WORD    colorPlane;
    WORD    bitColor;
    long    zipFormat;
    long    realSize;
    long    xPels;
    long    yPels;
    long    colorUse;
    long    colorImportant;
  /*  void show()
  
    {    
        printf("infoHead Length:%dn",Length);
        printf("width&height:%d*%dn",width,height);
        printf("colorPlane:%dn",colorPlane);
        printf("bitColor:%dn",bitColor);
        printf("Compression Format:%dn",zipFormat);
        printf("Image Real Size:%dn",realSize);
        printf("Pels(X,Y):(%d,%d)n",xPels,yPels);
        printf("colorUse:%dn",colorUse);    
        printf("Important Color:%dn",colorImportant);
    }*/
}InfoHead;
/***************************
/***************************
    第三部分    调色盘结构  颜色表
    对于256色BMP位图,颜色位数为8,需要2^8 = 256个调色盘;
    对于24bitBMP位图,各象素RGB值直接保存在图像数据区,不需要调色盘,不存在调色盘区
    rgbBlue:   该颜色的蓝色分量。
    rgbGreen:  该颜色的绿色分量。
    rgbRed:    该颜色的红色分量。
    rgbReserved:保留值。
************************/
typedef struct
{         BYTE   rgbBlue;
         BYTE   rgbGreen;
         BYTE   rgbRed;
         BYTE   rgbReserved;
      /*   void show(void)
         {
            printf("Mix Plate B,G,R:%d %d %dn",rgbBlue,rgbGreen,rgbRed);
         }*/
}RGBMixPlate;
/****************************
      RGB加上头部信息转换成BMP
      参数說明:
      rgb_buffer        :RGB数据文件中的信息
      nData             :RGB数据的长度
      nWidth            :图像宽度的像素数
      nHeight           :图像高度的像素数
      fp1               :所存放的文件
*****************************/
int RGB2BMP(unsigned char *rgb_buffer,int nWidth,int nHeight,FILE*fp1)
{
     BmpHead m_BMPHeader;      
     char bfType[2]={'B','M'};//保留 
     m_BMPHeader.imageSize=3*nWidth*nHeight+54;//文件字节数,修改 
     m_BMPHeader.blank=0;//保留 
     m_BMPHeader.startPosition=54;//位图数据开始位置,修改 
  
     fwrite(bfType,1,sizeof(bfType),fp1);
     fwrite(&m_BMPHeader.imageSize,1,sizeof(m_BMPHeader.imageSize),fp1);
     fwrite(&m_BMPHeader.blank,1,sizeof(m_BMPHeader.blank),fp1);
     fwrite(&m_BMPHeader.startPosition,1,sizeof(m_BMPHeader.startPosition),fp1);
         
     InfoHead  m_BMPInfoHeader;
     m_BMPInfoHeader.Length=40;//本结构长度,保留 
     m_BMPInfoHeader.width=nWidth;//宽度有多少像素,修改 
     m_BMPInfoHeader.height=nHeight;//高度有多少像素 ,修改 
     m_BMPInfoHeader.colorPlane=1;//必须是1,保留 
     m_BMPInfoHeader.bitColor=24;//表示颜色时用到的位数 ,修改为(24) 
     m_BMPInfoHeader.zipFormat=0;// 压缩类型,不压缩,保留 
     m_BMPInfoHeader.realSize=3*nWidth*nHeight;//图像大小,字节为单位 
     m_BMPInfoHeader.xPels=0;//保留 
     m_BMPInfoHeader.yPels=0;//保留 
     m_BMPInfoHeader.colorUse=0;//保留 
     m_BMPInfoHeader.colorImportant=0;//保留 
  
     fwrite(&m_BMPInfoHeader.Length,1,sizeof(m_BMPInfoHeader.Length),fp1);
     fwrite(&m_BMPInfoHeader.width,1,sizeof(m_BMPInfoHeader.width),fp1);
     fwrite(&m_BMPInfoHeader.height,1,sizeof(m_BMPInfoHeader.height),fp1);
     fwrite(&m_BMPInfoHeader.colorPlane,1,sizeof(m_BMPInfoHeader.colorPlane),fp1);
     fwrite(&m_BMPInfoHeader.bitColor,1,sizeof(m_BMPInfoHeader.bitColor),fp1);
     fwrite(&m_BMPInfoHeader.zipFormat,1,sizeof(m_BMPInfoHeader.zipFormat),fp1);
     fwrite(&m_BMPInfoHeader.realSize,1,sizeof(m_BMPInfoHeader.realSize),fp1);
     fwrite(&m_BMPInfoHeader.xPels,1,sizeof(m_BMPInfoHeader.xPels),fp1);
     fwrite(&m_BMPInfoHeader.yPels,1,sizeof(m_BMPInfoHeader.yPels),fp1);
     fwrite(&m_BMPInfoHeader.colorUse,1,sizeof(m_BMPInfoHeader.colorUse),fp1);
     fwrite(&m_BMPInfoHeader.colorImportant,1,sizeof(m_BMPInfoHeader.colorImportant),fp1);
     fwrite(rgb_buffer,3*nWidth*nHeight,1,fp1);
     return 0;
}

注意:按道理来说满足我的硬件条件的相似情况,头文件不用改,c文件大部分不需要改动
有时生成的图片会出现色差,经过串口对比,可能是传输过程中少了一个字节导致像素点错位,解决方法是exe窗口跳出后,单片机稍微等待几秒再发送数据

实验现象:在这里插入图片描述

结语:书写不够正确之处敬请指正,希望学习之路相互交流

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-23 10:32:07  更:2021-07-23 10:34:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/28 1:20:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码