分类: GDI2012-09-14 22:52 243人阅读 收藏 举报 bmpTest.h :介绍BMP文件的格式及结构定义 bmpTest.cpp : 24bitBMP颜色数据到256色位图颜色数据的转换函数实现,具体算法可参考以 前的一个帖子 bmpTransfer.cpp : 读入一个24bitBMP文件,转换成一个256色BMP文件的程序 编译完成后得到的程序,如bmpTransfer.exe 执行 bmpTransfer file1 file2 file1是24bit的BMP位图源文件名,file2是新生成的256色位图文件名 可以用windows画板程序查看结果,似乎比直接用画板程序将24bitBMP存成256色BMP文件的转换效果要好哦。
bmpTest.h
-
-
-
- #ifndef __BMPTEST_H_
- #define __BMPTEST_H_
-
- #include <stdio.h>
-
- typedef unsigned char BYTE;
- typedef unsigned short WORD;
-
-
-
-
-
-
-
-
-
-
-
-
-
- typedef struct
- {
- long imageSize;
- long blank;
- long startPosition;
- void show(void)
- {
- printf("BMP Head:\n");
- printf("Image Size:%d\n",imageSize);
- printf("Image Data Start Position : %d\n",startPosition);
- }
- }BmpHead;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 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(void)
- {
- printf("infoHead Length:%d\n",Length);
- printf("width&height:%d*%d\n",width,height);
- printf("colorPlane:%d\n",colorPlane);
- printf("bitColor:%d\n",bitColor);
- printf("Compression Format:%d\n",zipFormat);
- printf("Image Real Size:%d\n",realSize);
- printf("Pels(X,Y):(%d,%d)\n",xPels,yPels);
- printf("colorUse:%d\n",colorUse);
- printf("Important Color:%d\n",colorImportant);
- }
- }InfoHead;
-
-
-
-
-
-
-
-
-
-
- typedef struct
- {
- BYTE rgbBlue;
- BYTE rgbGreen;
- BYTE rgbRed;
- BYTE rgbReserved;
- void show(void)
- {
- printf("Mix Plate B,G,R:%d %d %d\n",rgbBlue,rgbGreen,rgbRed);
- }
- }RGBMixPlate;
-
-
-
-
-
-
-
-
-
-
-
-
-
- int Transfer(WORD *color24bit, int len, BYTE *Index, RGBMixPlate *mainColor);
-
- #endif
bmpTest.cpp
-
-
-
- #include "bmpTest.h"
- #include <string.h>
- #include <assert.h>
-
-
- int PFC(int color1, int color2)
- {
- int x,y,z;
- x = (color1 & 0xf) - (color2 & 0xf);
- y = ((color1>>4) & 0xf) - ((color2>>4) & 0xf);
- z = ((color1>>8) & 0xf) - ((color2>>8) & 0xf);
- return (x*x + y*y + z*z);
- };
-
-
- int Sort1(int *src, int *attach, int n)
- {
- int cur, cur1;
- int i,j,k=0;
- for (i = 1; i < n; i++)
- {
- cur = src[i];
- cur1 = attach[i];
- for (j = i - 1; j >= 0; j--)
- {
- if (cur > src[j])
- {
- src[j+1] = src[j];
- attach[j+1] = attach[j];
- }
- else
- break;
- }
- src[j+1] = cur;
- attach[j+1] = cur1;
- }
- return 0;
- }
-
-
- int Sort2(int *src, int *attach, int n)
- {
- if (n <= 12)
- return Sort1(src, attach, n);
- int low = 1, high = n - 1;
- int tmp;
- while (low <= high)
- {
- while (src[low] >= src[0])
- {
- if (++low > n - 1)
- break;
- }
- while (src[high] < src[0])
- {
- if (--high < 1)
- break;
- }
- if (low > high)
- break;
- {
- tmp = src[low];
- src[low] = src[high];
- src[high] = tmp;
- tmp = attach[low];
- attach[low] = attach[high];
- attach[high] = tmp;
- }
- low++;
- high--;
- }
-
-
- {
- tmp = src[low - 1];
- src[low - 1] = src[0];
- src[0] = tmp;
- tmp = attach[low - 1];
- attach[low - 1] = attach[0];
- attach[0] = tmp;
- }
- if (low > 1)
- Sort2(src, attach, low - 1);
- if (low < n)
- Sort2(&src[low], &attach[low], n - low);
- return 0;
- }
-
-
- int Transfer(WORD *color24bit, int len, BYTE *Index, RGBMixPlate *mainColor)
- {
- int usedTimes[4096] = {0};
- int miniColor[4096];
- for (int i = 0; i < 4096; i++)
- miniColor[i] = i;
- i = 0;
- for (i = 0; i < len; i++)
- {
- assert(color24bit[i] < 4096);
- usedTimes[color24bit[i]]++;
- }
-
- int numberOfColors = 0;
- for (i = 0; i < 4096; i++)
- {
- if (usedTimes[i] > 0)
- numberOfColors++;
- }
-
-
-
- Sort2(usedTimes, miniColor, 4096);
-
-
-
-
- for (i = 0; i < 256; i++)
- {
- mainColor[i].rgbBlue = (BYTE)((miniColor[i]>>8)<<4);
- mainColor[i].rgbGreen = (BYTE)(((miniColor[i]>>4) & 0xf)<<4);
- mainColor[i].rgbRed = (BYTE)((miniColor[i] & 0xf)<<4);
- mainColor[i].rgbReserved = 0;
- }
-
- int *colorIndex = usedTimes;
- memset(colorIndex, 0, sizeof(int) * 4096);
-
- if (numberOfColors <= 256)
- {
- for (i = 0; i < numberOfColors; i++)
- colorIndex[miniColor[i]] = i;
- }
- else
- {
- for (i = 0; i < 256; i++)
- colorIndex[miniColor[i]] = i;
-
- int index, tmp, tmp1;
- for (i = 256; i < numberOfColors; i++)
- {
- tmp = PFC(miniColor[0], miniColor[i]);
- index = 0;
- for (int j = 1; j < 256; j++)
- {
- tmp1 = PFC(miniColor[j], miniColor[i]);
- if (tmp > tmp1)
- {
- tmp = tmp1;
- index = j;
- }
- }
- colorIndex[miniColor[i]] = index;
- }
- }
-
- for (i = 0; i < len; i++)
- {
- assert(colorIndex[color24bit[i]] < 256);
- Index[i] = colorIndex[color24bit[i]];
- }
-
- return 1;
- }
bmpTransfer.cpp -
-
-
- #include "bmpTest.h"
- #include <string.h>
-
- int __cdecl main(int argc,char* argv[])
- {
- if (argc < 3)
- {
- printf("Usage:\n");
- printf(" %s filename1 filename2\n", argv[0]);
- printf(" filename1 : source 24bit BMP filename like: xxx.bmp\n");
- printf(" filename2 : new 256 color BMP filename\n");
- return -1;
- }
- BmpHead headBMP;
- InfoHead infoHead;
- FILE* p;
- char* filename = argv[1];
- p = fopen(filename,"rb");
- if (p == NULL)
- {
- printf("!!!file %s open failed.\n", filename);
- }
-
- printf("file %s open success.\n",filename);
-
- fseek(p,2,SEEK_CUR);
- fread(&headBMP,1,12,p);
- headBMP.show();
- fread(&infoHead,1,40,p);
- infoHead.show();
- if (infoHead.bitColor != 24)
- {
- fclose(p);
- printf("This is not a 24bit BMP file.\n");
- return -1;
- }
-
- long nData = infoHead.realSize;
- BYTE* pColorData = new BYTE[nData];
- fread(pColorData,1,nData,p);
- printf("last 4 byte of color Data:%x %x %x %x\n",\
- pColorData[nData-4],pColorData[nData-3],\
- pColorData[nData-2],pColorData[nData-1]);
-
-
- int leftData = 0;
- char ch = 0;
- while (!feof(p))
- {
- fread(&ch,1,1,p);
- leftData++;
- }
- if (leftData)
- printf("%d bytes not read in file.\n", leftData);
- printf("read file over.\n");
- if(!fclose(p))
- {
- printf("file close.\n");
- }
-
-
-
- BYTE* Index = new BYTE[nData/3];
- RGBMixPlate mainColor[256];
- memset(mainColor, 0, sizeof(mainColor));
- WORD* shortColor = new WORD[nData/3];
- int iRed, iGreen, iBlue;
- for (int i = 0; i < nData/3; i++)
- {
- iRed = pColorData[i*3]>>4;
- iGreen = pColorData[i*3+1]>>4;
- iBlue = pColorData[i*3+2]>>4;
- shortColor[i] = (iRed<<8) + (iGreen<<4) + iBlue;
- }
- delete []pColorData;
-
- Transfer(shortColor, nData/3, Index, mainColor);
-
- delete []shortColor;
-
-
-
-
-
- headBMP.imageSize = 14 + 40 + 4*256 + nData/3;
-
- headBMP.startPosition += 4*256;
- infoHead.bitColor = 8;
- infoHead.realSize = nData/3;
-
-
- char* newFile = argv[2];
- FILE *p1 = fopen(newFile,"wb");
- if (NULL == p1)
- {
- printf("open new file failed.\n");
- return -1;
- }
- char hh[2] = {0x42, 0x4D};
- fwrite(hh,1,2,p1);
- fwrite(&headBMP, 1, 12, p1);
- fwrite(&infoHead, 1, 40, p1);
- fwrite(mainColor, 1, sizeof(mainColor), p1);
- fwrite(Index, 1, nData/3, p1);
- fclose(p1);
-
-
- delete []Index;
- return 0;
- }
|