实现图像格式的转换代码 C语言实现 RGB565转BMP图像

这是我从网上看到的宝贵资料,可以直接实现RGB565 转BMP图像的实现。我是用的开发板mini2440的开发板,和配套的摄像头CAM130,实际上CAM130用的是OV9650的一款摄像头;拍出的照片为RGB565的格式,因为这种格式直接可以送到 TFT屏幕上直接显示;

转自:

http://www.360doc.com/content/14/0324/11/16450474_363247832.shtml#

非常好的资料,真实可用;

//主函数
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "rgb2bmp.h"
int  main()
{    FILE* p;
/***************  input data  ***********
    filename      :RGB数据文件名称
    nWidth        :所生成文件的水平像素
    nHeight       :所生成文件的垂直像素
    newFile       :最终生成文件的名称
***********************************************/
    char* filename = "rgb565_800_480_woman";
    int nWidth = 800;
    int nHeight = 480;
    char* newFile = "rgb565_800_480_woman_0x7f.bmp";
    p = fopen(filename,"rb");
    if (p == NULL)
    {
        printf("!!!file %s open failed.n", filename);
        return 0;
    }
    printf("file %s open success.n",filename);
/***********  read Image Data  **************/    
    long nData = nWidth*nHeight;
    unsigned short* rgb_buffer = malloc(nData*sizeof(short));   
    fread(rgb_buffer,2,nData,p);
    long total = nWidth*nHeight*3;
    unsigned char* pVisit =  malloc(total*sizeof(char));
    unsigned char* tmp = pVisit;
    long i =0;
    unsigned char R,G,B;
    while(i<nData)
    {
       R = *rgb_buffer&0x1f;
    G = (*rgb_buffer>>5)&0x3f;
    B = (*rgb_buffer>>11)&0x1f;
    B = B<<3;
    G = G<<2;
    R = R<<3;
      *pVisit=R;pVisit++;
      *pVisit=G;pVisit++;
      *pVisit=B;pVisit++;
      rgb_buffer++;
      i++; 
     }
    printf("read file over.nData%ldn",nData);
/*****************************************************/
/***********  write file *******************/
    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;
}
   
//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(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;
     m_BMPInfoHeader.bitColor=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;
}



  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言可以通过读取BMP图片的像素数据,并将其转换为NV12格式。下面是一个简单的示例代码: ```c #include <stdio.h> #include <stdlib.h> typedef struct { unsigned char blue; unsigned char green; unsigned char red; } RGBPixel; void bmpToNV12(const char* bmpFile, const char* nv12File) { FILE* bmp = fopen(bmpFile, "rb"); if (!bmp) { printf("Failed to open BMP file.\n"); return; } // 读取BMP文件头 fseek(bmp, 0, SEEK_SET); unsigned char header[54]; fread(header, sizeof(unsigned char), 54, bmp); // 获取图像宽度、高度和像素数据偏移量 int width = *(int*)&header[18]; int height = *(int*)&header[22]; int dataOffset = *(int*)&header[10]; // 计算每行像素数据所占字节数(包括填充字节) int rowSize = ((width * 3 + 3) / 4) * 4; // 分配内存保存像素数据 RGBPixel* pixels = (RGBPixel*)malloc(rowSize * height); if (!pixels) { printf("Failed to allocate memory.\n"); fclose(bmp); return; } // 读取像素数据 fseek(bmp, dataOffset, SEEK_SET); fread(pixels, sizeof(RGBPixel), width * height, bmp); // 创建NV12文件 FILE* nv12 = fopen(nv12File, "wb"); if (!nv12) { printf("Failed to create NV12 file.\n"); free(pixels); fclose(bmp); return; } // 写入NV12文件头 fwrite(header, sizeof(unsigned char), 54, nv12); // 将RGB像素数据转换为YUV420(NV12)格式 unsigned char* yuvData = (unsigned char*)malloc(rowSize * height * 3 / 2); if (!yuvData) { printf("Failed to allocate memory.\n"); free(pixels); fclose(bmp); fclose(nv12); return; } int yIndex = 0; int uvIndex = width * height; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { RGBPixel pixel = pixels[i * width + j]; // 计算Y分量值 yuvData[yIndex++] = (unsigned char)(0.299 * pixel.red + 0.587 * pixel.green + 0.114 * pixel.blue); // 每隔2个像素计算一次UV分量值 if (i % 2 == 0 && j % 2 == 0) { // 计算U分量值 yuvData[uvIndex++] = (unsigned char)(-0.169 * pixel.red - 0.331 * pixel.green + 0.5 * pixel.blue + 128); // 计算V分量值 yuvData[uvIndex++] = (unsigned char)(0.5 * pixel.red - 0.419 * pixel.green - 0.081 * pixel.blue + 128); } } } // 写入NV12像素数据 fwrite(yuvData, sizeof(unsigned char), rowSize * height * 3 / 2, nv12); // 释放内存并关闭文件 free(pixels); free(yuvData); fclose(bmp); fclose(nv12); printf("BMP to NV12 conversion completed.\n"); } int main() { const char* bmpFile = "input.bmp"; const char* nv12File = "output.nv12"; bmpToNV12(bmpFile, nv12File); return 0; } ``` 上述代码中,`bmpToNV12`函数用于将BMP图片转换为NV12格式。它首先读取BMP文件头,获取图像的宽度、高度和像素数据偏移量。然后根据每行像素数据所占字节数计算出行大小,并分配内存保存像素数据。接下来,它读取像素数据,并创建NV12文件。最后,它将RGB像素数据转换为YUV420(NV12)格式,并写入NV12文件。 你可以将需要转换BMP图片路径传递给`bmpToNV12`函数的`bmpFile`参数,将转换后的NV12文件路径传递给`nv12File`参数。运行程序后,它将会将BMP图片转换为NV12格式并保存到指定路径的文件中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值