24to16

// 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<height ; y++)
 {
  for(x=0; x<width ; 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;
}

 

發佈了12 篇原創文章 · 獲贊 1 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章