Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1584383
  • 博文数量: 239
  • 博客积分: 1760
  • 博客等级: 上尉
  • 技术积分: 1595
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-08 23:53
文章分类

全部博文(239)

文章存档

2016年(1)

2015年(28)

2014年(53)

2013年(42)

2012年(50)

2011年(65)

分类: C/C++

2011-02-26 21:10:55

// bmptest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"

#pragma pack(push)
#pragma pack(1)
typedef struct tagBITMAPFILEHEADER {
 unsigned short bfType;// 位图文件的类型,必须为BM
 unsigned long bfSize; // 位图文件的大小,以字节为单位
 unsigned short bfReserved1; // 位图文件保留字,必须为0
 unsigned short bfReserved2; // 位图文件保留字,必须为0
 unsigned long bfOffBits;// 位图数据的起始位置,以相对于位图
// 文件头的偏移量表示,以字节为单位
} BITMAPFILEHEADER;

typedef struct tagBITMAPINFOHEADER{
 unsigned long biSize; // 本结构所占用字节数
 unsigned long biWidth; // 位图的宽度,以像素为单位
 unsigned long biHeight; // 位图的高度,以像素为单位
 unsigned short biPlanes; // 目标设备的级别,必须为1
 unsigned short biBitCount;// 每个像素所需的位数,必须是1(双色),
 // 4(16色),8(256色)或24(真彩色)之一
 unsigned long biCompression; // 位图压缩类型,必须是 0(不压缩),
 // 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
 unsigned long biSizeImage; // 位图的大小,以字节为单位
 unsigned long biXPelsPerMeter; // 位图水平分辨率,每米像素数
 unsigned long biYPelsPerMeter; // 位图垂直分辨率,每米像素数
 unsigned long biClrUsed;// 位图实际使用的颜色表中的颜色数
 unsigned long biClrImportant;// 位图显示过程中重要的颜色数
} BITMAPINFOHEADER;
#pragma pack(pop)

typedef struct tagRGB24PIX{
 unsigned char R;
 unsigned char G;
 unsigned char B;
} RGB24PIX;

int readBMP(char * fileName, BITMAPFILEHEADER * bmpFileHeader, BITMAPINFOHEADER * bmpInfoHeader, unsigned char ** bmpData)
{
    FILE *fp;
    if (!(fp = fopen(fileName, "rb")))
 {
        return -1;
 }

 fread((void *)bmpFileHeader, sizeof(unsigned char), sizeof(BITMAPFILEHEADER), fp);
 fread((void *)bmpInfoHeader, sizeof(unsigned char), sizeof(BITMAPINFOHEADER), fp);

 if(NULL != *bmpData)
 {
  free(*bmpData);
 }
 *bmpData = (unsigned char *)malloc(bmpFileHeader->bfSize - bmpFileHeader->bfOffBits);
 fread((void *)*bmpData, sizeof(unsigned char), bmpFileHeader->bfSize - bmpFileHeader->bfOffBits, fp);

 fclose(fp);
    return 0;
}

int writeBMP(char * fileName, BITMAPFILEHEADER bmpFileHeader, BITMAPINFOHEADER bmpInfoHeader, unsigned char * bmpData)
{
 FILE *fp;
    if (!(fp = fopen(fileName, "wb")))
 {
        return -1;
 }
     
    fwrite((void *)&bmpFileHeader, sizeof(unsigned char), sizeof(BITMAPFILEHEADER), fp);
 fwrite((void *)&bmpInfoHeader, sizeof(unsigned char), sizeof(BITMAPINFOHEADER), fp);
    fwrite((void *)bmpData, sizeof(unsigned char), bmpFileHeader.bfSize - bmpFileHeader.bfOffBits, fp);
   
    fclose(fp);
    return 0;
}

unsigned long conv24to16(unsigned char * src, unsigned char ** dst, unsigned long width, unsigned long height)
{
 unsigned short * convedData = NULL;
 unsigned long y = 0;
 unsigned long x = 0;
 RGB24PIX tempPix = {0};

 if(NULL != *dst)
 {
  free(*dst);
 }
 *dst = (unsigned char *)malloc(width * height * 2);

 convedData = (unsigned short *) *dst;

 for(y=0; y {
  for(x=0; x  {
   tempPix.R = *(src + 3 * (width * y + x));
   tempPix.G = *(src + 3 * (width * y + x) + 1);
   tempPix.B = *(src + 3 * (width * y + x) + 2);
   *convedData = ((((unsigned long)tempPix.R)>>3)&0x001F)|((((unsigned long)tempPix.G)<<2)&0x03E0)|((((unsigned long)tempPix.B)<<7)&0xFC00);

   convedData++;
  }
 }

 return width * height * 2;
}

int main(int argc, char* argv[])
{
 BITMAPFILEHEADER srcBH = {0};
 BITMAPINFOHEADER srcBI = {0};
 unsigned char * srcBmpData = NULL;
 unsigned char * dstBmpData = NULL;

 readBMP("c:\\src.bmp", &srcBH, &srcBI, &srcBmpData);

 srcBH.bfSize = conv24to16(srcBmpData, &dstBmpData, srcBI.biWidth, srcBI.biHeight);
 srcBH.bfSize += srcBH.bfOffBits;

 srcBI.biBitCount = 16;

 writeBMP("c:\\dst.bmp", srcBH, srcBI, dstBmpData);

 if(NULL != srcBmpData)
 {
  free(srcBmpData);
 }
 if(NULL != dstBmpData)
 {
  free(dstBmpData);
 }
 return 0;
}


转载自: http://blog.csdn.net/AmonYoung/archive/2010/01/20/5210830.aspx

阅读(1809) | 评论(0) | 转发(0) |
0

上一篇:JpgToBmp

下一篇:视频与图像RGB/YUV格式详解

给主人留下些什么吧!~~