| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2615 人关注过本帖
标题:800X600X256色分辨率下显示BMP文件,色深=8(256)色图片已经成功,如何显 ...
只看楼主 加入收藏
ba_wang_mao
Rank: 2
来 自:成都理工大学
等 级:论坛游民
帖 子:297
专家分:27
注 册:2006-11-7
收藏
 问题点数:0 回复次数:3 
800X600X256色分辨率下显示BMP文件,色深=8(256)色图片已经成功,如何显示色深=

#include <dos.h>
#include <stdio.h>
#include <mem.h>
#include <alloc.h>
#include <stdlib.h>
#include <conio.h>

#define VBE320X200X256 0X13
#define VBE640X480X256 0X101
#define VBE800X600X256 0X103
#define VBE1024X768X256 0X105
#define True 1
#define False 0
#define VARM_GRAPH_800(x,y) (((unsigned long)y<<9L)+((unsigned long)y<<8L)+((unsigned long)y<<5L)+((unsigned long)(x)))

typedef struct BIGIMAGE /*存图结构*/
{
char fill_name[16];
int height;
int width;
} BIGIMAGE; /*存图类型名*/

typedef struct tagRGBQUAD /*用于读取调色板信息*/
{
char r;
char g;
char b;
char reserved;
} RGBQUAD;
int g_cur_vbe_page = 0;


//-----------------------------------------------------------
// 图形模式初始化子程序
//-----------------------------------------------------------
void _Cdecl InitGraph(void)
{
_AX = 0x4f02;
_BX = VBE800X600X256;
__int__(0x10);
if(_AH != 0)
{
puts("Can't Initialize the graphics mode!");
exit(1);
}
}


//-----------------------------------------------------------
// 关闭图形模式,回到文本模式子程序
//-----------------------------------------------------------
void _Cdecl CloseGraph(void)
{
_AX = 0x4f02;
_BX = 0x03;
__int__(0x10);
}


void selectpage(register char page) /*换页函数*/
{
union REGS r;

r.x.ax=0x4f05;
r.x.bx=0;
r.x.dx=page; /*选择页面*/
int86(0x10,&r,&r);
}


/////////////////////////////////////////////////////////////////////////////////////////////////
//显存换页函数
/////////////////////////////////////////////////////////////////////////////////////////////////
void _Cdecl set_vbe_page(int page)
{
if (g_cur_vbe_page != page)
{
_BX = 0;
_DX = g_cur_vbe_page = page;
_AX = 0x4F05;
__int__(0x10);
}
}


/*******************************************BMP图显示函数**********************************/
void show_bmp_256(char *File_Name, int x, int y) /*图片显示函数,不支持透明色*/
{
unsigned char buffer[9216];
unsigned int width, height, linebytes;
int i, j;
long addr;
int page;
char far *videoptr = (char far *)0xa0000000L;
RGBQUAD bmiColors[256];
FILE *fp;

/****************************读文件,判断是否符合条件*****************************/
if ((fp=fopen(File_Name,"rb"))==NULL) /*判断打开文件是否正确*/
{
printf("Can't open file: %s",File_Name);
bioskey(0);
exit(0);
}
fseek(fp,18L,SEEK_SET); width = getw(fp);/*图片宽度*/
fseek(fp,22L,SEEK_SET); height = getw(fp);/*图片高度*/
fseek(bmp,28L,SEEK_SET); depth=getw(bmp); /* 获得图片色深 */

/********************************************************************************/
/* 设置当前图片的调色板 */
/********************************************************************************/
if (depth==8) /* 若是8位位图,开辟调色板数组 */
{
fseek(fp, 54L, SEEK_SET);
if (fread((char *)&bmiColors[0], 4, 256, fp) != 256) /* 读当前图片调色板数据 */
{
printf("Can't get palette !\n");
bioskey(0);
exit(0);
}
for (i = 0; i < 256; i++)
{
outportb(0x03C8, i);
outportb(0x03C9, bmiColors[i].b >> 2);
outportb(0x03C9, bmiColors[i].g >> 2);
outportb(0x03C9, bmiColors[i].r >> 2);
}
}


/*************************************************************************/
if(width%4 != 0)
linebytes = width+(4-width%4); /* 每行字节数--4的整数倍 */
else
linebytes = width;
fseek(fp,1078L,SEEK_SET); /* 跳到位图数据的起始位置 */
for(j = height-1; j >= 0; j--)
{
fread(buffer, linebytes, 1, fp);
for(i = 0; i < width; i++)
{
addr = VARM_GRAPH_800(i+x,j+y);
page = (int)(addr >> 16);
set_vbe_page(page);
if((i+x) > -1 && (i+x) < 800 && (j+y) > -1 && (j+y) < 600) /*在屏幕范围*/
*(videoptr+(unsigned int)(addr&0xffff))= buffer[i];
}
}
fclose(fp);
}


void main(void)
{
InitGraph();
show_bmp_256("d:\\jig.bmp",0,0);
getch();
CloseGraph();
}

搜索更多相关主题的帖子: BMP 分辨率 define include unsigned 
2007-01-17 11:49
ba_wang_mao
Rank: 2
来 自:成都理工大学
等 级:论坛游民
帖 子:297
专家分:27
注 册:2006-11-7
收藏
得分:0 
谁能邦我解决24K BMP图片显示

多年以来还在MSDOS、单片机下搞嵌入式编程,对WINDOWS编程一窍不通,很想了解WINDOWS下病毒编程技术。
2007-01-18 17:07
一笔苍穹
Rank: 1
等 级:新手上路
帖 子:640
专家分:0
注 册:2006-5-25
收藏
得分:0 

有一个比较简单的方法,也是TC256中的方法,我在NEO的后期版本也引入了这个方法,思路如下:
由于16位、24位图片中的像素颜色信息是以R\G\B分量直接存储的,这和256色的调色板机制不一样(256色是通过颜色号找颜色),所以直接的显示是不行的。但我们可以想一个办法,就是重设调色板以将调色板的颜色索引号也与R\G\B关联起来,256色深即8位色,每个颜色号的长度的8位,我们可以分为3:3:2三个域段,分别来表示R:G:B三原色,我们有时称之为伪真彩调色板。这样,16位色和24位色通过移位操作将多余的位去掉,这其实是一种最简单的有损压缩,虽然会缺失许多颜色细节,但总体图像是没问题的,你可以用xnview工具里的抖动到256色看看实际效果,因为它就是基于这个算法的。
先给你一个建立伪真彩调色板的函数:
void make_332_palette(PALETTE pal)
{
int r, g, b, k = 0;

for(r = 0; r < 64; r += 9)
{
for(g = 0; g < 64; g += 9)
{
for(b = 0; b < 64; b += 21)
{
pal[k].r = r;
pal[k].g = g;
pal[k].b = b;
k++;
}
}
}
}
这是NEO中的一个函数,运算很简单,只需要将你自己的调色板设置函数替换进去就可以了。
然后是一个在此调色板中查找颜色的宏:
#define SRGB332(r, g, b) ((((r) / 9) << 5) + (((g) / 9)<<2) + (b) / 21)
这个也是NEO中的,你可以将24位位图中的每个像素颜色拆分出r、g、b往里面真就行了。
你也可以用我写好的拆分宏:
#define getr16(c) (((c)&0xf800)>>11)
#define getg16(c) (((c)&0x7e0) >>5)
#define getb16(c) ((c)&0x1f)
#define getr24(c) (((c)&0xff0000)>>16)
#define getg24(c) (((c)&0xff00)>>8)
#define getb24(c) (c&0xff)
前三个用来拆分16位颜色值,后三个拆分24位的。
这样,先设置调色板为伪真彩色板,再读取位图中的像素颜色,拆分颜色,送入查找宏查找,结果就是256色的颜色值,往显存中填吧!

另外还有一个方法,就是最佳色匹配,即将位图像素颜色值中的R、G、B与256颜色值对应的R\G\B进行比较,取最近值即可。这样不需要重设置调色板,但涉及到读颜色号对应的RGB值,所以性能就不太好了,但效果一般情况下都比前一个方法要好,当然如果你的调色板中的颜色与图片中的颜色差的太大就不好看了:
/* bestfit_color:
* 从指定调色板pal中搜索与给出颜色分量r,g,b最匹配的颜色号并将其返回
参数r,g,b范围为0~63;
*/
Uint8 bestfit_color(PALETTE pal, int r, int g, int b)
{
int mind;
int newd;
int color;
int i;

/*如果使用了332伪真彩调色板*/
if (common_flags & 0x1)
{
return ARGB332(r, g, b);
}
else
{
color = 0;
mind = abs(pal[0].r - r) + abs(pal[0].g - g) + abs(pal[0].b - b);

for (i=1; i<256; i++)
{
/*通过比较色差总和选择最佳匹配色*/
newd = abs(pal[i].r - r) + abs(pal[i].g - g) + abs(pal[i].b - b);
if (newd<mind)
{
mind = newd;
color = i;
}
}
}

return color;
}

2007-01-18 18:05
RockCarry
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:13
帖 子:662
专家分:58
注 册:2005-8-5
收藏
得分:0 

三楼董兄正解
使用332的像素格式是最方便的,色彩效果也算理想,最大的优势是所有的图片都使用一个调色板的话,处理起来很方便。
其实无论怎么所有的图片都要统一的匹配到一个调色板,这可以借助图片工具实现。当然也可以不对图片进行处理,而在使用332的调色板,然后再现实的时候将真彩色的像素格式转换为8bit 332的像素格式。

2007-01-18 19:55
快速回复:800X600X256色分辨率下显示BMP文件,色深=8(256)色图片已经成功,如 ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.088180 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved