主题:[原创]16色BMP位图 之 TC篇
飞鸟12
[专家分:2830] 发布于 2006-03-21 13:10:00
运行环境 TurboC 2.0
先在tc目录下新建一个16色位图 test.bmp (这里假定大小是 320*240)
并将 bmp16.h 文件也保存在该文件夹下
然后运行下面程序
/*
loadbmp.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <graphics.h>
#include "bmp16.h"
#define PATH "d:\\turboc2"
void main()
{
FILE *fp;
int VedioMode=VGA;
int VedioDriver=VGAHI;
initgraph(&VedioMode,&VedioDriver,PATH);
if((fp=fopen("test.bmp","rb"))==NULL){
closegraph();
printf("file cannot open\n");
exit(0);
}
ShowBMP16(fp,10,10,320,240,16);
ShowBMP16Ex(fp,300,300,50,50,200,100,16);
fclose(fp);
getch();
closegraph();
}
两个显示图像的函数 暂时都还存在一些问题
1.显示区域的宽度为奇数时,实际并是按偶数显示 少显示了一列
2.截取区域的起始列为奇数时,实际并是按起始列偶数显示 显示区域向左移了一列
沙发
飞鸟12 [专家分:2830] 发布于 2006-03-21 10:48:00
/*
BMP16.h
2006/3/23
*/
typedef struct tagBITMAPFILEHEADER {
unsigned int bfType;
unsigned long bfSize;
unsigned int bfReserved1;
unsigned int bfReserved2;
unsigned long bfOffBits;
}BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER {
unsigned long biSize;
long biWidth;
long biHeight;
unsigned int biPanes;
unsigned int biBitCount;
unsigned long biCompression;
unsigned long biSizeImage;
long biXPelsPerMeter;
long biYPelsPerMeter;
unsigned long biClrUsed;
unsigned long biClrImportant;
}BITMAPINFOHEADER;
typedef struct tagRGBQUAD {
unsigned char rgbBlue;
unsigned char rgbGreen;
unsigned char rgbRed;
unsigned char rgbReserved;
}RGBQUAD;
/*
windows画图 中选色框各个颜色所对应的 颜色索引号如下:
0 7 1 3 2 6 4 5
F 8 9 B A E C D
*/
void SetVGAPalette(FILE *fp)
{
/*tc 中颜色索引号0~15 所对应的 调色板号*/
int i, palIndex[16]={0,1,2,3,4,5,20,7,56,57,58,59,60,61,62,63};
RGBQUAD quad[16];
/*tc VGA的调色板 设置为.BMP的调色板*/
fseek(fp,54L,SEEK_SET);
fread(quad,sizeof(RGBQUAD),16,fp);
for(i=0; i<16; i++){
setrgbpalette(palIndex[i], quad[i].rgbRed/4, quad[i].rgbGreen/4, quad[i].rgbBlue/4);
}
}
/*恢复到原始调色板*/
void ResumeVGAPalette()
{
/*tc 中颜色索引号0~15 所对应的 调色板号*/
int i, palIndex[16]={0,1,2,3,4,5,20,7,56,57,58,59,60,61,62,63};
RGBQUAD quad;
for(i=0; i<8; i++){
quad.rgbRed=42*(i&0x04?1:0);
quad.rgbGreen=42*(i&0x02?1:0);
quad.rgbBlue=42*(i&0x01?1:0);
setrgbpalette(palIndex[i], quad.rgbRed, quad.rgbGreen, quad.rgbBlue);
setrgbpalette(palIndex[15-i], 63-quad.rgbRed, 63-quad.rgbGreen, 63-quad.rgbBlue);
}
}
/*
ShowBMP16()说明:
FILE *fp bmp文件头指针
int winLeft, int winTop 显示区左上角位置
int winWidth, int winHeight 显示区范围 超出范围的图像不会被显示
unsigned char TranColor 图像透明色 (正常值为0~15) 图像中该种颜色的区域 不于显示;
设置为16 或者大于16 时,显示全部颜色 此处通常设置为16
*/
int ShowBMP16(FILE *fp, int winLeft, int winTop, int winWidth, int winHeight, unsigned char TranColor)
{
long x,y;
long Height,Width;
long WBytes,DataOffset;
unsigned char SrcData,data;
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
/*读取文件头信息*/
fseek(fp,0L,SEEK_SET);
fread(&bfh,sizeof(BITMAPFILEHEADER),1,fp);
fread(&bih,sizeof(BITMAPINFOHEADER),1,fp);
/*测试文件是否是16色BMP图像文件*/
if(bfh.bfType!='M'*256+'B' || bih.biBitCount!=4){
return 1;
}
/*图像宽度 对4 向上取整*/
WBytes=(bih.biWidth*bih.biBitCount+31)/8;
WBytes=WBytes/4*4;
/*显示的图像 限制在显示区内部*/
Width=bih.biWidth<winWidth ? bih.biWidth : winWidth;
Height=bih.biHeight<winHeight ? bih.biHeight : winHeight;
/*设置数据段起始地址*/
DataOffset=118;
if(bih.biHeight > winHeight) {
DataOffset+=(bih.biHeight-winHeight)*WBytes;
}
/*显示图像 预先设置调色板*/
SetVGAPalette(fp);
for(y=0; y<Height; y++) {
fseek(fp, DataOffset+y*WBytes, SEEK_SET);
for(x=0; x<Width; x+=2) {
fread(&SrcData,1,1,fp);
/*ScrData的低4位 高4位 分别存储一个象素点的颜色值
TranColor 为透明色 0~15 大于等于十六 无作用
*/
if( (data=SrcData/16) != TranColor) {
putpixel(winLeft+x,winTop+Height-y-1,data);
}
if( (data=SrcData%16) != TranColor) {
putpixel(winLeft+x+1,winTop+Height-y-1,data);
}
}
}
return 0;
}
/*
ShowBMP16Ex()说明:
FILE *fp bmp文件头指针
int winLeft, int winTop 显示区左上角位置
int bmpLeft, int bmpTop bmp图像截取区域左上角位置
int bmpWidth, int bmpHeight bmp图像截取区域范围
unsigned char TranColor 图像透明色 (正常值为0~15) 图像中该种颜色的区域 不于显示;
设置为16 或者大于16 时,显示全部颜色 此处通常设置为16
*/
int ShowBMP16Ex(FILE *fp, int winLeft, int winTop, int bmpLeft, int bmpTop, int bmpWidth, int bmpHeight, unsigned char TranColor)
{
long x,y;
long WBytes,DataOffset;
unsigned char SrcData,data;
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
/*指向文件头*/
fseek(fp,0L,SEEK_SET);
fread(&bfh,sizeof(BITMAPFILEHEADER),1,fp);
fread(&bih,sizeof(BITMAPINFOHEADER),1,fp);
/*测试文件是否是16色BMP图像文件*/
if(bfh.bfType!='M'*256+'B' || bih.biBitCount!=4){
return 1;
}
/*图像宽度 对4 向上取整*/
WBytes=(bih.biWidth*bih.biBitCount+31)/8;
WBytes=WBytes/4*4;
/*设置数据段起始地址*/
DataOffset=54+16*sizeof(RGBQUAD)+bmpLeft/2;
DataOffset+=(bih.biHeight-bmpHeight-bmpTop)*WBytes;
/*显示图像 预先设置调色板*/
SetVGAPalette(fp);
for(y=0; y<bmpHeight; y++) {
fseek(fp, DataOffset+y*WBytes, SEEK_SET);
for(x=0; x<bmpWidth; x+=2) {
fread(&SrcData,1,1,fp);
/*ScrData的低4位 高4位 分别存储一个象素点的颜色值
TranColor 为透明色 0~15 大于等于十六 无作用
*/
if( (data=SrcData/16) != TranColor) {
putpixel(winLeft+x,winTop+bmpHeight-y-1,data);
}
if( (data=SrcData%16) != TranColor) {
putpixel(winLeft+x+1,winTop+bmpHeight-y-1,data);
}
}
}
return 0;
}