首  页   最新日志    火人论坛        火人作品    编程园地    网络日志    网友作品     留言本本     关于火人
用户登陆
用户:
密码:
 

站点日历
73 2017 - 11 48
   1234
567891011
12131415161718
19202122232425
2627282930




日志搜索

 标题   内容

 
 
冒险岛资源结构(三)BMP与PNG图片文件结构 网络版珠宝大对决游戏
晴天 冒险岛资源结构(四)data.wz中图片数据的提取
   [分类:编程园地][发表日期:2006-9-26] [发表:火人[查看:146288]

按此在新窗口打开图片  按此在新窗口打开图片
      冒险岛里的图片格式实际上是比较特殊的,每个象素的R、G、B、A分量分别只能取以下的值
红色通道(R)  :$00,$11,$22......$FF,共16种
绿色通道(G)  :$00,$11,$22......$FF,共16种
蓝色通道(B)  :$00,$11,$22......$FF,共16种
Alpha通道(A):$00,$11,$22......$FF,共16种
所以冒险岛里的图片实际上只有16*16*16=4096色,加上ALPHA通道的效果,相当于4096*16=65536,即16位真彩色的效果,对于二维的卡通类游戏来说足够了。
      有人肯定会问,为什么要用这种方式呢,直接用默认的16位真彩模式不好吗?各分量的值为什么要这样设定呢?问得好,这也是我们应该向人家学习的地方:一是因为默认的BMP16位真彩模式是不带ALPHA通道的,二是因为各分量这样取值 ,图片存储的时候只要以rgba(rgba各4位,共16位)方式存储,比起RGBA(RGBA各8位,共32位)方式来,省了一半的空间;三是取出图片时,可以很方便地将数据转换为支持ALPHA通道的32位BMP图像(将取出的各分量* $11即可)。小小的改变,既节省了空间,又提高了效率!
      
     另外为了节省data.wz文件空间,每幅图只存储图像数据,不存储BMP文件头相关信息,并且图像数据是压缩后存储的,压缩算法是开源并备受好评的LZ777算法,DELPHI自带了标准的ZLIB库可实现这类算法。

   好了,进正题,首先找到存储图片的起始地址(下节介绍),在开始处读取图片的宽、高及大小:imgwidth、imgHeight、bufSize,将图像数据读取到内存流中并用ZLIB库解压:
程序代码:[ 复制代码到剪贴板 ]
//解压函数  
function StreamDecompression(mInputStream: TStream; mOutputStream: TStream): Integer;
  var
    vBuffer: array[0..4096] of Char;
    I: Integer;
  begin
    Result := -1;
    if not (Assigned(mInputStream) and Assigned(mOutputStream)) then
      Exit;
    with TDecompressionStream.Create(mInputStream) do
    try
      repeat
        I := Read(vBuffer, 4096);
        mOutputStream.Write(vBuffer, I);
      until I = 0;
      Result := mOutputStream.Size;
    finally
      Free;
    end;
  end;

//图像数据读取,变量声明省略
begin
   f.seek(0,baseoffset)//f为data.wz文件流,baseoffset为图像起始地址
    imgwidth := rPackNum(f);//宽
    imgheight := rPackNum(f);//高
    val := rPackNum(f); //
    val2 := rU8(f); //
    f.read(nulls, 4); //
    bufSize := rU32(f) - 1;//数据长度
    flag := rU8(f); //check(flag,  0x00, f);

    setlength(buf, bufSize);
    f.read(pointer(buf)^, bufSize);
    vInputStream := TStringStream.Create(buf);
    vOutputStream := TMemoryStream.Create();
    StreamDecompression(vInputStream, vOutputStream);//
end;

vOutputStream即为解压后的图像数据内存流,再用如下代码将其变为32位BMP模式的图像数据
程序代码:[ 复制代码到剪贴板 ]
   
    //BMP 是上下颠倒的,故从 imgheight-1开始,否则显示出来的图像是倒的
    //将argb转换成aarrggbb
    for y := imgheight-1 downto 0 do
    begin
      vOutputStream.Seek(2*y*imgwidth,0);
      for i := 1 to (imgwidth) do
      begin
        if vOutputStream.position>vOutputStream.size then
             pp:=0
        else
        vOutputStream.Read(pp,2);
        a:=(pp shr 12) and $0F; a := a * $11;
        r:=(pp shr 8) and $0F;  r := r * $11;
        g:=(pp shr 4) and $0F;  g := g * $11;
        b:=(pp ) and $0F;       b := b * $11;
        cc := a shl 24 + r shl 16 + g shl 8 + b;
        vBMPStream.Write(cc, 4);//vBMPStream即32位BMP格式的图像数据流
      end;
    end;

当然,不要忘了加上32位BMP图像的文件头数据
程序代码:[ 复制代码到剪贴板 ]
    try
    FillChar(BF, SizeOf(TBitmapFileHeader) , 0);
    with BF do
    begin
      bfType := Ord('B') + Ord('M') * $100;   //2
      bfSize := 2*vOutputStream.Size+SizeOf(TBitmapFileHeader)+SizeOf(TBitmapInfo);//4  整个文件大小
      bfReserved1 := 0; //2
      bfReserved2 := 0; //2
      bfOffBits := SizeOf(TBitmapFileHeader) + SizeOf(TBitmapInfoHeader);  //4 从文件开始到位图数据开始之间的数据(bitmap data)之间的偏移量
    end;
    vBMPStream.WriteBuffer(BF, SizeOf(TBitmapFileHeader));

    FillChar(BI, SizeOf(TBitmapInfo) , 0);
    with BI do
    begin
      BI.bmiHeader.biSize := SizeOf(TBitmapInfoHeader);  //Bitmap Info Header)的长度
      BI.bmiHeader.biWidth := imgwidth;
      BI.bmiHeader.biHeight := imgheight;
      BI.bmiHeader.biPlanes :=1;
      BI.bmiHeader.biBitCount := 32;
      BI.bmiHeader.biCompression:=BI_RGB;
    end;
    vBMPStream.WriteBuffer(BI, SizeOf(TBitmapInfo));


用vBMPStream.SavetoFile函数即可得到带ALPHA通道的32位BMP图像文件!
为方便测试,提供两个盛大服的data.wz文件图像起始地址:
263823096:虎精      268637083:月牙牛魔王



[本日志由 火人 于 2006-09-27 10:46 PM 编辑]

引用这个评论 Ronhosy 于 2017-11-13 11:55 PM 发表评论: 
Viagra Ou Acheter Forum Buy Cialis Online Mastercard Cheap Sex Pills  [url=http://cialtobuy.com]cialis online[/url] Where Can I Get Cephalexin Sildenafil Tadalafil Generic Compare Viagra Levitron Cialis  

引用这个评论 Ronhosy 于 2017-10-29 08:04 PM 发表评论: 
Comprar Cialis 20mg Cytotec Vente En Ligne  [url=http://cheapvia50mg.com]viagra[/url] Overnight Cephalexin Online Venta Cialis Original Propecia Saw Palmetto Serenoa Repens  

引用这个评论 Ronhosy 于 2017-10-12 02:53 PM 发表评论: 
Compra De Propecia Viagra Generic Levitra Tadalis Sx Acheter Tadalis Sx Original  [url=http://howtogetvia.com]viagra online prescription[/url] Generic Viagra Spain  

引用这个评论 Ronhosy 于 2017-10-03 11:25 AM 发表评论: 
Calais Pills From Canada Pharmacy  [url=http://howmuchisvia.com]buy viagra[/url] Achat Cialis Site Securise How Good Is Kamagra  

引用这个评论 JeffEntino 于 2017-09-20 05:08 AM 发表评论: 
Conseil Acheter Cialis  [url=http://cialtobuy.com ]cialis[/url] Where To Buy Clomid Online Bodybuilding  
Giving Your Baby Amoxicillin  
Cialis 5 Mg Foro  <a href=http://cialtobuy.com >online pharmacy</a> Buy Plavix Online Canada 

引用这个评论 火人 于 2006-10-24 08:22 PM 发表评论: 
请看留言版的回复

引用这个评论 Chienlin 于 2006-10-24 03:49 PM 发表评论: 
火人大大
263823096:虎精      268637083:月牙牛魔王

台灣版 沒辦法找到各兩各呢0.0
(幾乎都沒看到怪物的圖片呢)

是不是台灣版的 不該搜尋40056 ?

好像都只能找到 裝備 人物...找不到怪物的呢 0.0

 

发表评论
发表: 用户:  密码:   注册?  
验证码    
评论:

禁止表情
禁止UBB
禁止图片
识别链接
识别关键字
表  情
 

Copyright © 2006 All rights reserved. Design by huosoft

电话:13974847258    QQ群:7155339
Powered by L-Blog V-Blog 2004-2005