内存中的数据排列高位在左,低位在右

RGB888->RGB666

      高 -------低

        B[3]         B[2]          B[1]         B[0]            B[3]             B[2]

RGB888  RRRRRRRR GGGGGGGG BBBBBBB RRRRRRRR  GGGGGGGG BBBBBBBB

        A[2]           A[1]               A[0]                   A[2]              A[1]

RGB666 RRRRRRGG     GGGGBBBB     BBRRRRRR           GGGGGGBB    BBBB

RGB888->RGB565

高-----------低

        B[2]          B[1]            B[0]

RGB888   RRRRRRRR GGGGGGGG  BBBBBBBB

        A[1]          A[0]

RGB565  RRRRRGGG   GGGBBBBB

代码

#include "stdafx.h"
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <list>
using namespace std; #define WIDTHBYTES(bits) (((bits)+31)/32*4)
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef long LONG; //位图文件头信息结构定义
//其中不包含文件类型信息(由于结构体的内存结构决定,要是加了的话将不能正确读取文件信息)
typedef struct HS_tagBITMAPFILEHEADER{
WORD bfType;//固定为0x4d42
DWORD bfSize; //文件大小
WORD bfReserved1; //保留字,不考虑
WORD bfReserved2; //保留字,同上
DWORD bfOffBits;//实际位图数据的偏移字节数,即前三个部分长度之和
}HS_BITMAPFILEHEADER; //信息头BITMAPINFOHEADER,也是一个定义,其定义如下:
typedef struct HS_tagBITMAPINFOHEADER{
DWORD biSize; //指定此结构体的长度,为40
LONG biWidth; //位图宽
LONG biHeight; //位图高
WORD biPlanes; //平面数,为1
WORD biBitCount; //采用颜色位数,可以是1,2,4,8,16,24,新的可以是32
DWORD biCompression; //压缩方式,可以是0,1,2,其中0表示不压缩
DWORD biSizeImage; //实际位图数据占用的字节数
LONG biXPelsPerMeter; //X方向分辨率
LONG biYPelsPerMeter; //Y方向分辨率
DWORD biClrUsed; //使用的颜色数,如果为0,则表示默认值(2^颜色位数)
DWORD biClrImportant; //重要颜色数,如果为0,则表示所有颜色都是重要的
}HS_BITMAPINFOHEADER; //调色板Palette,当然,这里是对那些需要调色板的位图文件而言的。24位和32位是不需要调色板的。
//(似乎是调色板结构体个数等于使用的颜色数。) typedef struct HS_tagRGBQUAD {
//public:
BYTE rgbBlue; //该颜色的蓝色分量
BYTE rgbGreen; //该颜色的绿色分量
BYTE rgbRed; //该颜色的红色分量
BYTE rgbReserved; //保留值
} HS_RGBQUAD; void showBmpHead(HS_BITMAPFILEHEADER* pBmpHead)
{
printf("位图文件头:\n");
printf("bmp格式标志bftype:0x%x\n", pBmpHead->bfType);
printf("文件大小:%d\n", pBmpHead->bfSize);
printf("保留字1:%d\n", pBmpHead->bfReserved1);
printf("保留字2:%d\n",pBmpHead->bfReserved2);
printf("实际位图数据的偏移字节数:%d\n",pBmpHead->bfOffBits);
} void showBmpInfoHead(HS_tagBITMAPINFOHEADER* pBmpInfoHead)
{
printf("位图信息头:\n");
printf("此结构体的长度:%d\n",pBmpInfoHead->biSize);
printf("位图宽:%d\n",pBmpInfoHead->biWidth);
printf("位图高:%d\n",pBmpInfoHead->biHeight);
printf("biPlanes平面数:%d\n",pBmpInfoHead->biPlanes);
printf("biBitCount采用颜色位数:%d\n",pBmpInfoHead->biBitCount);
printf("压缩方式:%d\n",pBmpInfoHead->biCompression);
printf("biSizeImage实际位图数据占用的字节数:%d\n",pBmpInfoHead->biSizeImage);
printf("X方向分辨率:%d\n",pBmpInfoHead->biXPelsPerMeter);
printf("Y方向分辨率:%d\n",pBmpInfoHead->biYPelsPerMeter);
printf("使用的颜色数:%d\n",pBmpInfoHead->biClrUsed);
printf("重要颜色数:%d\n",pBmpInfoHead->biClrImportant);
} void showRgbQuan(HS_tagRGBQUAD* pRGB)
{
printf("(%-3d,%-3d,%-3d) ",pRGB->rgbRed,pRGB->rgbGreen,pRGB->rgbBlue); } FILE *fp_write; void writeRgb18Head(HS_tagBITMAPFILEHEADER* pBmpHead){
fwrite(&pBmpHead->bfType, , , fp_write);
fwrite(&pBmpHead->bfSize, , , fp_write);
fwrite(&pBmpHead->bfReserved1, , , fp_write);
fwrite(&pBmpHead->bfReserved2, , , fp_write);
fwrite(&pBmpHead->bfOffBits, , , fp_write);
// fwrite(pBmpHead, 1, 14, fp_write);
} void writeRgb18InfoHead(HS_tagBITMAPINFOHEADER* pBmpInfoHead)
{
fwrite(pBmpInfoHead, , , fp_write);
} void rgb24_to_rgb565(BYTE* rgb24,BYTE* rgb16, int width, int height){
int i = ;
int j = ;
for(i = ; i < width*height; i += )
{
rgb16[j] = ( rgb24[i] & 0xF1 ) >> ;
rgb16[j] |= ( rgb24[i+] & 0x1C ) << ;
rgb16[j + ] = rgb24[i+] & 0xF8;
rgb16[j + ] |= (rgb24[i+] & 0xF0) >> ;
j += ;
} } WORD rgb_24_2_565(int r, int g, int b)
{
return (WORD)(((unsigned(r) << ) & 0xF800) |
((unsigned(g) << ) & 0x7E0) |
((unsigned(b) >> )));
} void rgb24_to_rgb666(BYTE* rgb24,BYTE* rgb18, int width, int height){ int i = ;
int j = ;
for(i = ; i < width*height; i += )
{ rgb18[j] = rgb24[i] >> ;
rgb18[j] = rgb18[j] | ( ( rgb24[i+] & 0x0C ) << ); rgb18[j+] = ( rgb24[i+] & 0xF0 ) >> ;
rgb18[j+] = rgb18[j+] | ( ( rgb24[i+] & 0x3C) << ); rgb18[j+] = ( rgb24[i+] & 0xC0 ) >> ;
rgb18[j+] = rgb18[j+] | rgb24[i+] & 0xFC;
j += ;
}
} int find_all_files(const char * lpPath, list<string> *picturePath)
{
char filePath[] ;
char szFind[MAX_PATH];
WIN32_FIND_DATA FindFileData;
strcpy(szFind,lpPath);
strcat(szFind,"\\*.*");
HANDLE hFind=::FindFirstFile(szFind,&FindFileData);
if(INVALID_HANDLE_VALUE == hFind)
return -; do
{
if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if(strcmp(FindFileData.cFileName,".")!= && strcmp(FindFileData.cFileName, "..")!=)
{
//发现子目录,递归之
char szFile[MAX_PATH] = {};
strcpy(szFile,lpPath);
strcat(szFile,"\\");
strcat(szFile,FindFileData.cFileName);
find_all_files(szFile, picturePath);
}
}
else
{
//找到文件,处理之
string strPicturePath = lpPath;
strPicturePath += "\\" ;
strPicturePath += FindFileData.cFileName;
picturePath->push_back(strPicturePath);
}
}while(::FindNextFile(hFind,&FindFileData)); ::FindClose(hFind); return ;
} void main()
{
HS_BITMAPFILEHEADER bitHead;
HS_BITMAPINFOHEADER bitInfoHead;
FILE* pfile;
char filePath[];
char *BmpFileHeader;
WORD *temp_WORD;
DWORD *temp_DWORD;
string strPicturePath;
string strPictureName; printf("please input the file path:\n");
scanf("%s",filePath); list<string> picturesPath;
find_all_files(filePath, &picturesPath); BmpFileHeader=(char *)calloc(,sizeof(char)); for(list<string>::iterator it = picturesPath.begin(); it != picturesPath.end(); ++it){
strPicturePath = *it;
pfile = fopen(strPicturePath.c_str(),"rb");//打开文件 if(pfile!=NULL)
{
memset(BmpFileHeader, , );
fread(BmpFileHeader,,,pfile);
temp_WORD=(WORD* )(BmpFileHeader);
bitHead.bfType=*temp_WORD;
if(bitHead.bfType != 0x4d42)
{
printf("file is not .bmp file!");
continue;
}
temp_DWORD=(DWORD *)(BmpFileHeader+sizeof(bitHead.bfType));
bitHead.bfSize=*temp_DWORD;
temp_WORD=(WORD*)(BmpFileHeader+sizeof(bitHead.bfType)+sizeof(bitHead.bfSize));
bitHead.bfReserved1=*temp_WORD;
temp_WORD=(WORD*)(BmpFileHeader+sizeof(bitHead.bfType)+sizeof(bitHead.bfSize)+
sizeof(bitHead.bfReserved1));
bitHead.bfReserved2=*temp_WORD;
temp_DWORD=(DWORD*)(BmpFileHeader+sizeof(bitHead.bfType)+sizeof(bitHead.bfSize)+sizeof(bitHead.bfReserved1)+sizeof(bitHead.bfReserved2));
bitHead.bfOffBits=*temp_DWORD;
//showBmpHead(&bitHead);
//printf("\n\n"); //写头文
int indexName = strPicturePath.find_last_of("\\");
strPictureName = strPicturePath.substr(indexName + );
fp_write = fopen(strPictureName.c_str(), "wb");
//fp_write = fopen("NC_001_16.bmp", "wb");
//fp_write = fopen("NC_001_24.bmp", "wb"); //读取位图信息头信息
fread(&bitInfoHead,,sizeof(HS_BITMAPINFOHEADER),pfile);
bitHead.bfSize = WIDTHBYTES(bitInfoHead.biWidth*) * bitInfoHead.biHeight + ;
//bitHead.bfSize = WIDTHBYTES(bitInfoHead.biWidth*16) * bitInfoHead.biHeight + 54;
//bitHead.bfSize = WIDTHBYTES(bitInfoHead.biWidth*24) * bitInfoHead.biHeight + 54;
writeRgb18Head(&bitHead); //showBmpInfoHead(&bitInfoHead);
//printf("\n");
bitInfoHead.biBitCount = ;
//bitInfoHead.biBitCount = 16;
//bitInfoHead.biBitCount = 24;
bitInfoHead.biCompression = ;
bitInfoHead.biSizeImage = ;
bitInfoHead.biXPelsPerMeter = ;
bitInfoHead.biYPelsPerMeter = ;
bitInfoHead.biClrUsed = ;
bitInfoHead.biClrImportant = ;
writeRgb18InfoHead(&bitInfoHead); int width = bitInfoHead.biWidth;
int height = bitInfoHead.biHeight;
int l_width = WIDTHBYTES(width* );//计算位图的实际宽度并确保它为32的倍数
BYTE *pColorData=(BYTE *)malloc(height*l_width);
memset(pColorData,,height*l_width);
long nData = height*l_width; //把位图数据信息读到数组里
fread(pColorData,,nData,pfile); int width16 = WIDTHBYTES(width* bitInfoHead.biBitCount);
BYTE* rgb16 = (BYTE*)malloc (width16* height);
//rgb24_to_rgb565(pColorData,rgb16, l_width,height);
rgb24_to_rgb666(pColorData,rgb16, l_width,height);
fwrite(rgb16, , width16 * height, fp_write); fclose(pfile);
fclose(fp_write);
free(pColorData);
free(rgb16);
}
else
{
printf("file open fail!\n");
}
} free(BmpFileHeader); printf("successed!");
}

RGB888转RGB666的更多相关文章

  1. ZA7783:MIPI转LVDS/MIPI转RGB888/RGB转LVDS

    在消费类电子越来越白热化阶段.好多设计project师已经開始慢慢关注到成本控制,小金在这里就给大家带来一颗转接IC.希望能帮助贵公司控制成本.当然性能也是可靠的,已经好多产品设计了. 多多不吝赐教 ...

  2. bmp文件格式中rgb555与rgb888之间的转换,24位与16位位图的转换

    今日,有同事问我.rgb555模式下的位图文件的格式问题,于是花了一下午的时间通过推測与測试,分析出了例如以下bmp文件在rgb555模式下的文件存储规律: 1:bmp文件的文件信息头中的biBitC ...

  3. 【安富莱专题教程第1期】基于STM32的硬件RGB888接口实现emWin的快速刷新方案,32位色或24

    说明:1. 首先感谢ST终于推出了ARGB格式的emWin库,可谓千呼万唤始出来,使用STM32的硬件RGB888接口刷新图片慢的问题终于得到解决.2. 这个问题由来已久,是之前为我们的STM32-V ...

  4. AM335X用RGB888连接LCD如何以16位色彩模式显示图片

    在AM335x中,在连接显示屏的时候,存在一个问题.这个在am335x Sillicon Errata已经提到过 在RGB888模式中   而对于RGB565模式的硬件连接 不难看出,这个RGB是反的 ...

  5. BMP RGB888转RGB565 +上下翻转+缩放

      典型的BMP图像文件由四部分组成: (1) 位图头文件数据结构,它包含BMP图像文件的类型.文件大小和位图起始位置等信息: typedef struct tagBITMAPFILEHEADER { ...

  6. 使用NEON指令加速RGB888和RGB565的相互转换

    最近在做一个项目需要将RGB888转换为RGB565,用C语言转换的代码很简单,这是从ffmpeg中摘抄的代码 static inline void rgb24to16_c(const uint8_t ...

  7. imx6 uboot lcd

    本文记录imx6 uboot中关于lcd初始化的过程. uboot中相关的文件: cpu/arm_cortexa8/start.S lib_arm/board.c board/freescale/mx ...

  8. DBI接口和DPI接口的区别

    1)DBI接口 A,也就是通常所讲的MCU借口,俗称80 system接口.The lcd interface between host processor and LCM device list a ...

  9. Davinci DM6446开发攻略——linux-2.6.18移植

     TI DAVINCI 使用最新的内核是montavista linux-2.6.18,之前说过,国内很多公司,包括开发板的软件包,一直在使用montavista linux-2.6.10,这个版本准 ...

随机推荐

  1. 在Pythonanywhere上部署Django

    1 在github上创建一个仓库blog 2 克隆到本地,添加Django项目,再推送到github 3 克隆到pythonanywhere,以后每次更新用git pull即可 4 在pythonan ...

  2. 辽宁OI2016夏令营模拟T1-dis

    数值距离(dis.pas/c/cpp)题目大意我们可以对一个数 x 进行两种操作:1. 选择一个质数 y,将 x 变为 x*y2. 选择一个 x 的质因数 y,将 x 变为 x/y定义两个数 a,b ...

  3. 《Windows编程循序渐进》——MFC封装机制详解

    单文档

  4. 3、File类之创建、删除、重命名、判断方法

    一般我们调用内置类的方法,都是指调用其成员方法,故而以下几种方法都是File类的成员方法,常用的有以下3种, 分别是 //创建 public boolean createNewFile() publi ...

  5. 免费数据库(SQLite、Berkeley DB、PostgreSQL、MySQL、Firebird、mSQL、MSDE、DB2 Express-C、Oracle XE)

    SQLite数据库是中小站点CMS的最佳选择 SQLite 是一个类似Access的轻量级数据库系统,但是更小.更快.容量更大,并发更高.为什么说 SQLite 最适合做 CMS (内容管理系统)呢? ...

  6. HTML5 中的新特性:

    一,用于绘画的 canvas 元素,<canvas>标签替代Flash Flash给很多Web开发者带来了麻烦,要在网页上播放Flash需要一堆代码和插件.<canvas>标签 ...

  7. Sass与Compress实战:第六章

    概要:介绍Compass如何让你从本地开发原型轻松转移到正产环境的网址或Web应用中. 本章内容: ● CSS精灵的历史和基本原则 ● Compass混合器让精灵自动化 ● 自定义精灵图片和CSS输出 ...

  8. POJ 3259 Wormholes(SPFA+邻接表)

    ( ̄▽ ̄)" #include<iostream> #include<cstdio> #include<queue> #include<vector ...

  9. 12.hibernate命名查询

    1.创建如下javaweb项目结构 2.在项目的src下创建hibernate.cfg.xml主配置文件 <?xml version="1.0" encoding=" ...

  10. 触动精灵远程Log模块

    一.功能 lua log方法能够自动发现同一网段下面的log服务器 lua log方法能够主动将log发给服务器 lua 客户端进程重启服务端不存在影响 二.实现 服务器使用python编写: 启动一 ...