现在的位置: 首页 > 综合 > 正文

一个RGB565转Bitmap的程序

2013年09月01日 ⁄ 综合 ⁄ 共 3523字 ⁄ 字号 评论关闭
/*
  All Rights Reserved
  Author:fanping.deng@gmail.com
  Function: convert RGB565 to BMP
  Build by g++
*/

#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>

#include <string.h>

typedef short WORD;
typedef int DWORD;
typedef int LONG;
typedef char BYTE;

//BITMAP  File Header info
typedef struct tagBITMAPFILEHEADER
{
    WORD bfType;
    DWORD bfSize;
    WORD bfReserved1;
    WORD bfReserved2;
    DWORD bfOffBits;
}__attribute__((packed)) BITMAPFILEHEADER;

//Bitmap info header
typedef struct tagBITMAPINFOHEADER{ // bmih
    DWORD biSize;
    LONG biWidth; //以像素为单位的图像宽度
    LONG biHeight;// 以像素为单位的图像长度
    WORD biPlanes;
    WORD biBitCount;// 每个像素的位数
    DWORD biCompression;
    DWORD biSizeImage;
    LONG biXPelsPerMeter;
    LONG biYPelsPerMeter;
    DWORD biClrUsed;
    DWORD biClrImportant;
}__attribute__((packed)) BITMAPINFOHEADER;

typedef struct tagPaletteRGB
{
    BYTE b;
    BYTE g;
    BYTE r;
    BYTE reserved;
}__attribute__((packed)) paletteRGB;

int g_len = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);//+sizeof(paletteRGB);
void initBMPHeader(BITMAPFILEHEADER* pBmpFileHeader)
{
    pBmpFileHeader->bfType = 0X4D42;  //Magic number
    pBmpFileHeader->bfSize = g_len + 320*480*3; //320*480, screen size, hardcoded. You should change it for different size
    pBmpFileHeader->bfReserved1 = 0X00;
    pBmpFileHeader->bfReserved2 = 0X00;
    pBmpFileHeader->bfOffBits = g_len;
}

void initBMPInfoHeader(BITMAPINFOHEADER* pBmpInfoHeader)
{
    pBmpInfoHeader->biSize = sizeof(BITMAPINFOHEADER);
    pBmpInfoHeader->biWidth = 320 ;//这个地方写死了,因为当时测试手机的屏幕就是这个尺寸的
    pBmpInfoHeader->biHeight= 480;
    pBmpInfoHeader->biPlanes=1;
    pBmpInfoHeader->biBitCount=24;
    pBmpInfoHeader->biCompression=0;
    pBmpInfoHeader->biSizeImage=320*480*3;
    pBmpInfoHeader->biXPelsPerMeter = pBmpInfoHeader->biYPelsPerMeter = 0;
    pBmpInfoHeader->biClrUsed = pBmpInfoHeader->biClrImportant = 0;
}
void convetBmp(int fs,int fd, short* pSrcShortBuffer,char *pDstIntBUffer);

int main(int argc,char* argv[])

{

   if(argc < 3)
   {
        printf("error use bmpgenerator,we need the source path");
        return -1;
   }

    BITMAPFILEHEADER bmpFileHeader;
    initBMPHeader(&bmpFileHeader);

    BITMAPINFOHEADER bmpInfoHeader;
    initBMPInfoHeader(&bmpInfoHeader);

    paletteRGB bmpPalette;
    memset(&bmpPalette,0,sizeof(paletteRGB));

    int fd = open(argv[1],O_CREAT|O_WRONLY);
    if(fd == -1)
    {
        printf("fail to create dst file %s\n",argv[1]);
        exit(-1);
    }
    int fs = open(argv[2],O_RDONLY);
    if(fs == -1)
    {
        printf("fail to open src file %s\n",argv[2]);
        exit(-1);
    }
    //Write head info to the destination file
    //注意:转换后BMP的数据格式是RGB888,所以不需要palette信息。关于BMP的信息可以搜索一下
    write(fd,&bmpFileHeader,sizeof(BITMAPFILEHEADER));
    write(fd,&bmpInfoHeader,sizeof(BITMAPINFOHEADER));
    //write(fd,&bmpPalette,sizeof(paletteRGB));

//320*480
//按行来算
    char* pDstIntBUffer = new char[3*320];
    memset(pDstIntBUffer,0,sizeof(char)*320);
    short* pSrcShortBuffer = new short[320];
    memset(pSrcShortBuffer,0,sizeof(short)*320);


    convetBmp(fs,fd,pSrcShortBuffer,pDstIntBUffer);

    close(fd);
    close(fs);
    delete[] pSrcShortBuffer;
    delete[] pDstIntBUffer;

    printf("bmp generated\n");
    return 0;

}
void convetBmp(int fs,int fd, short* pSrcShortBuffer,char *pDstIntBUffer)
{
    int height = 480;
    int srcLineLength = sizeof(short)*320;
    int dstLienLength = sizeof(char)*3*320;

    while(height > 0)
    {

        lseek(fs,(height-1)*srcLineLength,SEEK_SET);
        read(fs,(char*)pSrcShortBuffer,srcLineLength);
        for(int x = 0; x < 320; x++)
        {
            short srcPixel = *(pSrcShortBuffer+x); //first change RGB565 to RGB888
            char srcR = (srcPixel&0xF800)>>11;
            char srcG = (srcPixel&0x07E0)>>5;
            char srcB = srcPixel&0x001F;

            pDstIntBUffer[x*3 + 0] = srcB;
            pDstIntBUffer[x*3 + 1] = srcG;
            pDstIntBUffer[x*3 + 2] = srcR;


            pDstIntBUffer[x*3 + 0] <<= 3;
            pDstIntBUffer[x*3 + 1] <<= 2;
            pDstIntBUffer[x*3 + 2] <<= 3;

           // pDstIntBUffer[x*3 + 0] |= (srcB&0X07);
           // pDstIntBUffer[x*3 + 1] |= (srcG&0X03);
          //  pDstIntBUffer[x*3 + 2] |= (srcR&0X07);
        }
        write(fd,(char*)pDstIntBUffer,dstLienLength);
        --height;
    }
}














抱歉!评论已关闭.