请z_sky():看一下程序代码(该程序从http://www.zhanjiang.gd.lu/home/jinyt/qd/xz/vc下载)为何颜色显示不对,请一试。谢谢!!!

lonet_cw 2001-07-10 06:15:03
/*
*BMP图像显示源程序
*/
#include <conio.h>
#include <stdlib.h>
#include <alloc.h>
#include <stdio.h>
#include <graphics.h>

typedef unsigned char BYTE;
typedef unsigned WORD;
typedef unsigned long DWORD;

typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfoffBits;
} BITMAPFILEHEADER;

typedef struct tagBITMAPINFOHEADER {
DWORD biSize;
DWORD biWidth;
DWORD biHeight;
WORD biPlanes;
WORD biBitCount;

DWORD biCompress;

DWORD biSizeImage;
DWORD biXPeIsPerMeter;
DWORD biYPeIsPerMeter;
DWORD biCIrUsed;
DWORD biClrImprotant;
} BITMAPINFOHEADER;

typedef struct tagRGBQUAD {
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;

BYTE bit[8]={128, 64, 32, 16, 8, 4, 2, 1};

BITMAPFILEHEADER bmfHeader;
BITMAPINFOHEADER bmiHeader;
RGBQUAD *bmiColor;

/* 计算一行所需字节数*/
int Bytes_Line(void)
{
int n;

n=bmiHeader.biWidth*bmiHeader.biBitCount;
n=((n+31)/32)*4;
return n;
}

/* 分别处理几种格式*/
void Out_Line(char far *ptr, int x, int y)
{
int i, j;

switch(bmiHeader.biBitCount) {
case 1:
for(j=0,i=0; j<8,i<bmiHeader.biWidth; j++,i++)
if(ptr[i/8]&bit[j]) putpixel(x++, y, 1);
break;
case 4:
for(i=0; i<bmiHeader.biWidth; i+=2) {
putpixel(x++, y, ptr[i/2]>>4);
putpixel(x++, y, ptr[(i+1)/2]&0x0f);
}
break;
case 8:
for(i=0; i<bmiHeader.biWidth; i++)
putpixel(x++,y,ptr[i]);
/* 显示256色图像需要相应的画点函数*/
break;
case 24:
for(i=0; i<3*bmiHeader.biWidth; i+=3)
putpixel(x++, y, ptr[i]);
/* 显示真彩色图像需要专门的画点函数*/
break;
}
}

/* 解码BI_RLE8压缩格式*/
void Process_BI_RLE8(FILE *fp, int start_x, int start_y)
{
int ch0, ch1, x=start_x, y=start_y, n;

while(!feof(fp)) {
ch0=fgetc(fp);
ch1=fgetc(fp);

if(ch0)while(ch0>0) {
putpixel(x++, y, ch1);
ch0--;
}
else
switch(ch1) {
case 0:
x=start_x;
y--;
break;
case 1: return;
case 2:
x+=fgetc(fp);
y-=fgetc(fp);
break;
default:
n=0;
while(ch1>0) {
putpixel(x++, y, fgetc(fp));
ch1--;
n++;
}
while(n%4) {
fgetc(fp);
n++;
};
break;
}
}
}

/* 解码BI_RLE4 压缩格式*/
void Process_BI_RLE4(FILE *fp, int start_x, int start_y)
{
int ch0, ch1, x=start_x, y=start_y;

while(!feof(fp)) {
ch0=(BYTE)fgetc(fp);
ch1=(BYTE)fgetc(fp);

if(ch0)while(ch0>0) {
putpixel(x++, y, ch1>>4);
putpixel(x++, y, ch1&0x0f);
ch0--;
}
else
switch(ch1) {
case 0:
x=start_x;
y--;
break;
case 1: return;
case 2:
x+=(BYTE)fgetc(fp);
y-=(BYTE)fgetc(fp);
break;
default:
while(ch1>0) {
ch0=fgetc(fp);
putpixel(x++, y, ch0>>4);
putpixel(x++, y, ch0&0x0f);
ch1--;
}
break;
}
}
}

#define Minx ( getmaxx()-bmiHeader.biWidth )/2
#define Maxy ( getmaxy()+bmiHeader.biHeight )/2

void main(int argc, char *argv[])
{
FILE *fp;
int gd=VGA, gm=VGAHI;
int nColors=1, bytes_line, i;
char far *ptr;

if(argc<2)
{
printf("Usage: SHOWBMP *.bmp\n");
exit(0);
}
fp=fopen(argv[1], "rb");
fread(&bmfHeader, sizeof(bmfHeader), 1, fp);
fread(&bmiHeader, sizeof(bmiHeader), 1, fp);
initgraph(&gd, &gm, "");

nColors<<=bmiHeader.biBitCount;
bmiColor=malloc(nColors * sizeof(RGBQUAD));
fread(bmiColor, sizeof(RGBQUAD), nColors, fp);
for(i=0; i<nColors; i++)
setrgbpalette(i,bmiColor[i].rgbRed>>2,
bmiColor[i].rgbGreen>>2,bmiColor[i].rgbBlue>>2);
bytes_line=Bytes_Line();
ptr=malloc(bytes_line);

fseek(fp, bmfHeader.bfoffBits, SEEK_SET);
switch(bmiHeader.biCompress) {
case 0:
for(i=0; i<bmiHeader.biHeight; i++) {
fread(ptr, bytes_line, 1, fp);
Out_Line(ptr, Minx, Maxy-i);
}
/* outtextxy(0, 0, "0"); */
break;
case 1:
Process_BI_RLE8(fp, Minx, Maxy);
/* outtextxy(0, 0, "BI_RLE8");*/
break;
case 2:
Process_BI_RLE4(fp, Minx, Maxy);
/* outtextxy(0, 0, "BI_RLE4"); */
break;
}
getch();
closegraph();
}
...全文
108 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
z_sky 2001-07-11
  • 打赏
  • 举报
回复
1、你首先要根据读出的 bmiHeader.biBitCount 设定显示模式,否则256色和真彩的图像不能显示;
2、 for(j=0,i=0; j<8,i<bmiHeader.biWidth; j++,i++)
if(ptr[i/8]&bit[j]) putpixel(x++, y, 1);
这句循环是不正确的,应该分成两个循环来处理;
3、位图点位的顺序是从下到上的,可能你显示出来的得图像试倒得(可用单色位图检测);
4、setrgbpalette()不是乱用的,主要是对256色的,按不是你现在用的egavga.bgi这个ddriver;
建议你先把单色和16色的调通,这样简单点。

xmly2001 2001-07-10
  • 打赏
  • 举报
回复
在 bmp 文件中r g b 存放又专门的顺序,你试试改一下。
z_sky 2001-07-10
  • 打赏
  • 举报
回复
int gd=VGA, gm=VGAHI;
使显示模式为16色的,你看到的图像对吗?

70,037

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧