c图片问题 亟待解决 急急急!!!

BEISHUISHILAN 2008-09-13 05:37:53
这是一个BMP图片显示C程序,它要先按照BMP文件头中的调色板信息置调色板,然后再读取文件中的颜色索引号画图。但是由于每个图片中的调色板信息都不一样,每画一幅图都要置一次调色板,但是这样其他图片的显示就会因为调色板的改变而显示不正常。比如该程序中:

显示0.bmp (正常)
显示1.bmp (1.bmp显示正常,0.bmp显示异常)
再显示0.bmp (两张0.bmp显示都正常,1.bmp显示异常)

因为这个原因,编程中用到的图像都得放在同一个图片中,如果图像都一样大还比较简单,图像不一样大的时候就相当麻烦了。所以我想知道如何可以不用更改调色板就能正常显示BMP图片(比如把BMP图片中的调色板信息和颜色索引号转换成系统默认的调色板信息)或者可以置调色板后只影响该图片的显示,而屏幕其他部分不受影响。
麻烦高手给一个解决办法,谢谢啦。

还有我对JPG和GIF的显示也挺感兴趣,不过一直没有弄明白这两种文件结构,希望高手可以解释一下,重点是对显示有影响的部分,比如类似BMP中的宽度高度和调色板信息等,好像这两种文件格式比较复杂,压缩方式也比较多,我不知道自己现在能不能完全理解解压缩问题,不过还是希望老师能给出一种现在比较标准的或者说通用的JPG和GIF文件的结构、压缩方式和显示方法。



#include "graphics.h"
#include "Svga256.h"
#include "stdio.h"
#include "fcntl.h"
#include "malloc.h"
#include "io.h"

int huge Return_SVGA256(void)
{
return(SVGA640x400x256); /* 返回各种分辨率的对应编号 0~6 宏定义参见 Svga256.h */
}

int bmp_main(char*bmpname,int x0,int y0)
{
int width, height,i,j,fp;
unsigned char fix, *buffer, pix24b[4];
DacPalette256 dac256;
if((fp = open(bmpname, O_RDONLY | O_BINARY)) == -1)
{
printf("Can't find file:%s ",bmpname);
getch();
return 1;

}
lseek(fp, 18, SEEK_SET);
read(fp, &width, 4);
read(fp, &height, 4);
fix = (width % 4) ? (4 - width % 4) : 0;
lseek(fp, 54, SEEK_SET);
for(i = 0; i < 256; i++) /* 按照该图片的DAC色表设置色彩寄存器 */
{
read(fp, pix24b, 4); /* 读取DAC分量信息 */
/* 设置调色板 */
dac256[i][0] = pix24b[2] >> 2;
dac256[i][1] = pix24b[1] >> 2;
dac256[i][2] = pix24b[0] >> 2;
}
setvgapalette256(&dac256); /* 应用调色板, 定义参见 Svga256.h */
buffer = (unsigned char *)malloc(width);
for(j = height - 1; j >= 0; j--)
{
read(fp, buffer, width);
lseek(fp, fix, SEEK_CUR);
for(i = 0; i < width; i++)
putpixel(x0+i, y0+j, buffer[i]);
}
free(buffer);
close(fp);

}
main()
{
int i=DETECT, j=0;
installuserdriver("Svga256", Return_SVGA256); /* 对于svga256必需执行该函数以安装BGI驱动 */
initgraph(&i, &j, ""); /* 执行TC默认的BGI初始化函数 */

bmp_main("0.bmp",1,1);
getch();
bmp_main("1.bmp",50,50);
getch();
bmp_main("0.bmp",50,1);
getch();
closegraph();
}
...全文
168 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
ricesorry 2010-12-26
  • 打赏
  • 举报
回复
我也不知道有用没用哈。。
ricesorry 2010-12-26
  • 打赏
  • 举报
回复
BMP图像文件格式
 Bitmap(位图)的缩写,后缀名是.BMP。微软公司为Windows环境设置的标准图像文件格式,在Windows环境下运行的所有图像处理软件都支持这种格式
 Windows 3.0以前:设备相关位图(device-dependent bitmap,DDB)
 Windows 3.0以后:设备无关位图(device-independent bitmap,DIB)
 采用位映射存储格式
 图像颜色深度可选lbit、4bit、8bit及24bit
 不采用其他任何压缩(?)
 包含的图像信息较丰富
 占用磁盘空间过大,不利于网络传输
 存储数据时,图像的扫描方式是按从左到右、从下到上的顺序
BMP文件由4个部分组成
 位图文件头(bitmap-file header)
 位图信息头(bitmap-information header)
 颜色表(color table)
 图像数据阵列字节
 位图文件头
包含文件类型、文件大小、存放位置等信息
typedef struct tagBITMAPFILEHEADER {
WORD bfType; /* 说明文件的类型 */ (Why?)
DWORD bfSize; /* 说明文件的大小,用字节为单位 */ (Why?)
WORD bfReserved1; /* 保留,设置为0 */ (Why?)
WORD bfReserved2; /* 保留,设置为0 */ (Why?)
DWORD bfOffBits; /* 说明从BITMAPFILEHEADER结构
开始到实际的图像数据之间的字 节
偏移量 */(为什么需要?JPEG有类似
变量)
} BITMAPFILEHEADER;
 位图信息头
typedef struct tagBITMAPINFOHEADER {
DWORD biSize; /*说明BITMAPINFOHEADER结构所需要的字节数 */
LONG biWidth; /*说明图像的宽度,以像素为单位 */
LONG biHeight; /*说明图像的高度,以像素为单位 */
WORD biPlanes; /*为目标设备说明位面数,其值设置为1 */
WORD biBitCount; /*说明位数/像素,其值为1、4、8或者24 */
DWORD biCompression; /*说明图像数据压缩的类型。其值可以是下述值之一:BI_RGB:没有压缩;BI_RLE8:每个像素8位的RLE压缩编码,压缩格式由2字节组成(重复像素计数和颜色索引);BI_RLE4:每个像素4位的RLE压缩编码,压缩格式由2字节组成 */
DWORD biSizeImage; /*说明图像的大小,以字节为单位。当用BI_RGB格式时,可设置为0 */ (Why?)
LONG biXPelsPerMeter; /*说明水平分辨率,用像素/米表示 */
LONG biYPelsPerMeter; /*说明垂直分辨率,用像素/米表示 */
DWORD biClrUsed; /*说明位图实际使用的颜色表中的颜色索引数 */ (Why?)
DWORD biClrImportant; /*说明对图像显示有重要影响的颜色索引的数目,如果是0,表示都重要 */ (Why?)
} BITMAPINFOHEADER;
(1) 颜色表的定位
应用程序可使用存储在biSize成员中的信息来查找在BITMAPINFO结构中的颜色表,如下所示:
pColor = ((LPSTR) pBitmapInfo + (WORD) (pBitmapInfo->bmiHeader.biSize))
(2) biBitCount
biBitCount=1 表示位图最多有两种颜色,黑色和白色。图像数据阵列中的每一位表示一个像素
biBitCount=4 表示位图最多有16种颜色。每个像素用4位表示,并用这4位作为颜色表的表项来查找该像素的颜色
biBitCount=8 表示位图最多有256种颜色。每个像素用8位表示,并用这8位作为颜色表的表项来查找该像素的颜色
biBitCount=24 表示位图最多有224=16777216种颜色。bmiColors (或者bmciColors)成员就为NULL。每3个字节代表一个像素,其颜色由R、G、B字节的相对强度决定
(3) ClrUsed
BITMAPINFOHEADER结构中的成员ClrUsed指定实际使用的颜色数目。如果ClrUsed设置成0,位图使用的颜色数目就等于biBitCount成员中的数目(Why?)
(4) 图像数据压缩
① BI_RLE8:每个像素为8位的RLE压缩编码,可使用编码方式和绝对方式中的任何一种进行压缩,这两种方式可在同一幅图中的任何地方使用
编码方式:由2个字节组成,第一个字节指定使用相同颜色的像素数目,第二个字节指定使用的颜色索引。此外,这个字节对中的第一个字节可设置为0,联合使用第二个字节的值表示:第二个字节的值为0:行的结束。 第二个字节的值为1:图像结束。 第二个字节的值为2:其后的两个字节表示下一个像素从当前开始的水平和垂直位置的偏移量。
绝对方式:第一个字节设置为0,而第二个字节设置为0x03~0xFF之间的一个值。在这种方式中,第二个字节表示跟在这个字节后面的字节数,每个字节包含单个像素的颜色索引。压缩数据格式需要字边界(word boundary)对齐。
例 用十六进制表示的8位压缩图像数据如下:
03 04 05 06 00 03 45 56 67 00 02 78 00 02 05 01 02 78 00 00 09 1E 00 01
这些压缩数据可解释为 :
压缩数据 扩展数据
03 04 04 04 04
05 06 06 06 06 06 06
00 03 45 56 67 00 45 56 67 (?)
02 78 78 78
00 02 05 01 从当前位置右移5个位置后向下移一行
02 78 78 78
00 00 行结束
09 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E
00 01 RLE编码图像结束
② BI_RLE4:每个像素为4位的RLE压缩编码,同样也可使用编码方式和绝对方式中的任何一种进行压缩,这两种方式也可在同一幅图中的任何地方使用。这两种方式是:
编码方式:由2个字节组成,第一个字节指定像素数目,第二个字节包含两种颜色索引,一个在高4位,另一个在低4位。第一个像素使用高4位的颜色索引,第二个使用低4位的颜色索引,第三个使用高4位的颜色索引,依此类推。
绝对方式:这个字节对中的第一个字节设置为0,第二个字节包含有颜色索引数,其后续字节包含有颜色索引,颜色索引存放在该字节的高、低4位中,一个颜色索引对应一个像素。此外,BI_RLE4也同样联合使用第二个字节中的值表示:第二个字节的值为0:行的结束。
第二个字节的值为1:图像结束。 第二个字节的值为2:其后的两个字节表示下一个像素从当前开始的水平和垂直位置的偏移量。
例 用十六进制数表示的4位压缩图像数据:
03 04 05 06 00 06 45 56 67 00 04 78 00 02 05 01 04 78 00 00 09 1E 00 01
这些压缩数据可解释为 :
压缩数据 扩展数据
03 04 0 4 0
05 06 0 6 0 6 0
00 06 45 56 67 00 4 5 5 6 6 7
04 78 7 8 7 8
00 02 05 01 从当前位置右移5个位置后向下移一行
04 78 7 8 7 8
00 00 行结束
09 1E 1 E 1 E 1 E 1 E 1
00 01 RLE图像结束
 颜色表(调色板)
包含的元素与位图所具有的颜色数相同,像素的颜色用RGBQUAD结构来定义。对于24-位真彩色图像就不使用颜色表,因为位图中的RGB值就代表了每个像素的颜色。颜色表中的颜色按颜色的重要性排序,这可以辅助显示驱动程序为不能显示足够多颜色数的显示设备显示彩色图像。RGBQUAD结构描述由R、G、B相对强度组成的颜色
typedef struct tagRGBQUAD {
BYTE rgbBlue; /*指定蓝色分量*/
BYTE rgbGreen; /*指定绿色分量*/
BYTE rgbRed; /*指定红色分量*/
BYTE rgbReserved; /*保留,指定为0*/
} RGBQUAD;
 图像数据字节阵列
 紧跟在颜色表之后
 图像的每一扫描行由表示图像像素的连续的字节组成
 每一行的字节数取决于图像的颜色数目和用像素表示的图像宽度
 扫描行是由底向上存储的,这就是说,阵列中的第一个字节表示位图左下角的像素,而最后一个字节表示位图右上角的像素。
 2色图,1个字节表示8个象素
 16色图,1个字节表示2个象素
 256色图,1个字节表示1个象素
 真彩色图,3个字节表示1个象素
 图像数据按逆序存储
 每一行所占字节都是4的倍数,在读取数据时,应注意每一行的末端可能包含有一些额外添加的字节,读取时应忽略

GIF图像文件格式
 Graphics Interchange Fotmat(图像交换格式)的缩写,文件的后缀名是.GIF
 CompuServe公司于1987年开发,版本号GIF87a,89年扩充后版本号为GIF89a
 适用于多种操作系统,并广泛支持 Internet 标准
 以块(block)为单位存储信息。一个GIF文件由表示图形/图像的数据块、数据子块以及显示图形/图像的控制信息块组成,称为GIF数据流(Data Stream)。数据流中的所有控制信息块和数据块都必须在文件头(Header)和文件结束块(Trailer)之间

GIF文件格式的特点:
 GIF的图像颜色深度从lbit到8bit,也即GIF最多支持256种色彩的图像。
 GIF文件采用了LZW无损压缩算法来存储图像数据。
 GIF文件允许设置背景的透明属性。
 GIF文件格式可在一个文件中存放多幅彩色图像并且制作出幻灯片或者动画效果。(如何实现?)
 GIF文件支持图像数据的交叉处理方式。交叉处理主要用于图像显示时,隔行显示图像的数据。在Internet环境中,下载一个尺寸较大的图像时,交错处理方法将每隔八行显示一次图像数据,并逐渐填补其间的空隙。这样一个大的图像可以逐步显示,让用户首先看到图像概貌,然后逐步清晰。
 GIF文件定义的图像中可以加入文本。(有何作用?如何实现?)

JPEG(Joint Photographic Experts Group) 是一个由 ISO和CCITT两个组织机构联合组成的一个图像专家小组,负责制定静态的数字图像数据压缩编码标准,这个专家组开发的算法称为JPEG算法,并且成为国际上通用的标准
 JPEG是一个适用范围很广的静态图像数据压缩标准,既可用于灰度图像又可用于彩色图像。JPEG不仅适于静止图像的压缩,电视图像的帧内图像的压缩编码,也常采用此算法。JPEG标准还可以大范围地调节图像压缩率及其保真度

JPEG采用的是有损压缩算法,因此它会降低图像质量。每保存一次JPEG文件时都会再次降低图像质量
 GIF和JPEG对质量都有一定的影响
 在GIF与JPEG之间选择时,要考虑质量问题,通常包含单调区域的可以使用GIF压缩。而文件内包含许多色彩的缓和变化时,可以使用JPEG
 JPEG 文件具有较高的压缩率,而且具有渐近式支持交错功能。所谓渐近式支持交错功能是在网上传输图像的一种方式,就是在接收方接收图像时,图像可以先以粗线条的形式显示轮廓,然后逐渐地完善图像细节的显示。这种方式非常有利于在网络上快速传输。但是,如果要输出高质量图像时,还是应该选EPS格式或TIF格式

 数码照片JPEG文件分为两部分,文件头和图像数据部分
 文件头又分为若干段,前几段是通用部分,后面的可以自定义
 JPEG文件格式
 1.FFD8:图像开始(SOI)标记
 2.FFE0:APP0标记,用于JFIF
 3.FFE1:APP1标记,用于EXIF
 4.FFE2:APP2标记,用于扩展的EXIF
 5.FFE3~FFEF:APPn标记,其中n=3~15。没有明确使用,可用于存储自定义信息
 6.FFFB:一个或多个量化表DQT
 7.FFC0:帧图像开始SOF
 8.FFC4:一个或者多个Huffman表DHT
 9.FFDA:扫描开始SOS(Start of Scan)
 10.FFD9:图像结束EOI(End of Image)
ricesorry 2010-12-26
  • 打赏
  • 举报
回复
做个标记。这个我最近在学。有很多资料。等下给你找下。
kapaskey 2008-09-21
  • 打赏
  • 举报
回复
找个专家问问吧……
tobylee999 2008-09-15
  • 打赏
  • 举报
回复
太久没接触了,乱讲两句:

如果是位图中带了调色板的,可以直接恢复出原始数据,再直接保存成不带调色板的即可……
图片调色板信息只是用于减小图片大小的,不适用于其它图片或屏幕,
感觉你不应该直接把图片调色板应用到屏幕上,而应该使用图片调色板恢复出原始数据再使用。
类似于先解压缩再使用~

调色板数据的格式参考BMP格式说明了。
qmm161 2008-09-14
  • 打赏
  • 举报
回复
bmp 是位图,可以说是未压缩的,不过调色板也是压缩的一种方式,bmp 是一定要带调色板的吗?记不太清了...

-----------------------------------------------------------------------
setvgapalette256(&dac256); /* 应用调色板, 定义参见 Svga256.h */
这句是做什么,设置图像显示驱动的调色板?你的意思是在同一个界面上同时显示好几张bmp图片会出现问题?

我的建议是不要用这个接口了,应该有其他接口可以用,比如直接将带调色板的bmp图按照其调色板映射还原成位图,然后显示,就不会有问题了!否则你只能先统一用一个调色板来做图片,保证图片的调色板是一致的,这样的话只需要设置一遍setvgapalette256()!

jpg 和 gif 都是压缩过的,gif我没接触过,jpg的压缩算法比较简单,要找到他的说明也很简单,google jpg 标准 即可找到,解压缩的代码网上也是一堆堆的,但要注意的是解码出来的数据是在哪个色空间里面,yuv or rgb,根据需要进行转换
baihacker 2008-09-14
  • 打赏
  • 举报
回复
jpg和gif得去找资料了。。。貌似还有保护。
BEISHUISHILAN 2008-09-14
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 qmm161 的回复:]
bmp 是位图,可以说是未压缩的,不过调色板也是压缩的一种方式,bmp 是一定要带调色板的吗?记不太清了...

-----------------------------------------------------------------------
setvgapalette256(&dac256); /* 应用调色板, 定义参见 Svga256.h */
这句是做什么,设置图像显示驱动的调色板?你的意思是在同一个界面上同时显示好几张bmp图片会出现问题?

我的建议是不要用这个接口了,应该有其他接口可以用,比…
[/Quote]
我明白这个问题,只是不知道如何把不同图片的调色板还原,这应该是最好的方法,希望您再说明白点,谢。用统一的调色板做图片太麻烦了,好像不太现实,

69,373

社区成员

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

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