热点推荐

小喇叭+ 发布

01-16 02:17
01-16 02:04
01-13 17:30
查看: 752|回复: 0

[脚本示例] wil格式文件调用函数

[复制链接]
avatar

签到天数: 350 天

[LV.8]以坛为家I

7651

主题

255

回帖

31万

积分

司徒主管

Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20

UID
1
司徒币
260203
传世币
3000
元宝
0
在线时间
266 小时

最佳新人灌水之王

QQ
online_admin 发表于 2022-3-29 03:49:24 | 显示全部楼层 |阅读模式
unit MirWil;

interface

uses
SysUtils, Windows, DirectDraw, Assist, AdvDraw;

{------------------------------------------------------------------------------}
// WIL 常量定义
{------------------------------------------------------------------------------}
var
UseDIBSurface: Boolean = True;// 是否在创建 WIL Surface 时使用 DIB 绘制
// 如果直接使用 WIL 文件中的位图 Bits 会出现少量颜色
// 显示不正确,在源代码中的结果也是如此。

{------------------------------------------------------------------------------} 内容来自dedecms

// WIL 文件格式定义
{------------------------------------------------------------------------------}
type
// WIL 文件头格式 (56Byte)
PImageHeader = ^TImageHeader;
TImageHeader = record
Title : string[40]; // 库文件标题 'WEMADE Entertainment inc.'
ImageCount: Integer;// 图片数量
ColorCount: Integer;// 色彩数量
PaletteSize : Integer;// 调色板大小
end;

// WIL 图像信息 (注意, 没有 pack record)
PImageInfo = ^TImageInfo;
TImageInfo = record
Width: SmallInt; // 位图宽度
Height : SmallInt; // 位图高度 织梦好,好织梦

PX : SmallInt; // 未知,似乎不用也可
PY : SmallInt; // 未知,似乎不用也可
Bits : PByte;// 未使用, 实际从文件读出时,要少读 4 字节, 即是此值未读
end;

// WIX 索引文件头格式
PIndexHeader = ^TIndexHeader;
TIndexHeader = record
Title: string[40];// 'WEMADE Entertainment inc.'
IndexCount : integer; // 索引总数
end;

{------------------------------------------------------------------------------}
// TWilFile class
{------------------------------------------------------------------------------}

// TWilFile
TWilFile = class(TObject) 本文来自织梦

private
FFileName: string;// WIL 文件名
FFileHandle: THandle; // 文件句柄
FFileMapping: THandle;// 文件映射句柄
FFilePointer: Pointer;// 文件内容指针(使用文件映射)

FIndexArr: array of Integer;// 图片索引数组(从 WIX 文件中读取)
FMainColorTable: PRGBQuads; // 调色板指针(直接指向 WIL 文件中)
FImageCount: Integer; // 图片数量
FBitmapInfo: TBitmapInfo256;// 位图信息头部(用于 SetDIBitsToDevice)

FDDSurfaceDesc2: TDDSurfaceDesc2; dedecms.com

FSurfaces: array of IDirectDrawSurface7;
FMainDirectDraw: IDirectDraw7;

procedure LoadIndexFile;// 读入 WIX 文件至 IndexArr 中
procedure CreateMapView;// 创建 WIL 文件映射
function GetSurfaces(AIndex: Integer): IDirectDrawSurface7;
function GetImageInfo(AIndex: Integer): PImageInfo;
public
constructor Create(const AFileName: string; ADirectDraw: IDirectDraw7 = nil);
destructor Destroy; override;

// Draw: 将 Index 位置的图片绘制至 Surface 的 X, Y 位置
procedure Draw(Index: Integer; DstSurf: IDirectDrawSurface7; X, Y,
DstWidth, DstHeight: Integer; Transparent: Boolean);
// DrawEx: 将 Index 位置的图片绘制至 Surface 的 X, Y 位置, 包含 Image 的偏移位置 本文来自织梦
procedure DrawEx(Index: Integer; DstSurf: IDirectDrawSurface7; X, Y,
DstWidth, DstHeight: Integer; Transparent: Boolean);


// BitBlt: 将 Index 位置的图片绘制至 DC 的 X, Y 位置
procedure BitBlt(Index: Integer; DC: HDC; X, Y: Integer);
// StretchBlt: 以缩放方式将图片绘制至 DC
procedure StretchBlt(Index: Integer; DC: HDC; X, Y, Width, Height: Integer;
ROP: Cardinal);
// SaveTofile: 将索引位置的图片保存为 BMP 文件
procedure SaveToFile(Index: Integer; const FileName: string);

// 已打开的 WIL 文件名
property FileName: string read FFileName;
// 主调色板指针
property MainColorTable: PRGBQuads read FMainColorTable; 织梦内容管理系统
// IDirectDraw7, 用于创建 Surfaces 数组, 如果不指定也可以使用 BitBlt
property MainDirectDraw: IDirectDraw7 read FMainDirectDraw write FMainDirectDraw;
// 图片总数
property ImageCount: Integer read FImageCount;
// 图片的 Surface
property Surfaces[AIndex: Integer]: IDirectDrawSurface7 read GetSurfaces;
// 图片的信息
property ImageInfo[AIndex: Integer]: PImageInfo read GetImageInfo;
end;


implementation

{ TWilFile }

constructor TWilFile.Create(const AFileName: string; ADirectDraw: IDirectDraw7 = nil);
begin
FFileName := AFileName;

FMainDirectDraw := ADirectDraw;

// 读入图片索引文件
LoadIndexFile;

// 创建 WIL 文件的映射
CreateMapView; 本文来自织梦

// 读入 WIL 文件头数据

// 读入文件头中的图片数量, (图片数量已由 LoadIndexFile 设置, 这是由
// 于 Weapon.wix 中的数量错误导致的修改, savetime 2005.1.3)
// FImageCount := PImageHeader(FFilePointer)^.ImageCount;

// 设置 FSurfaces 数组大小
SetLength(FSurfaces, FImageCount);
// 保存调色板指针
FMainColorTable := IncPointer(FFilePointer, SizeOf(TImageHeader));

// 设置位图固定信息,以免每次 Blt 时设置
// TODO: 位图文件头还可进一步压缩
with FBitmapInfo.bmiHeader do
begin
biSize := SizeOf(TBitmapInfoHeader);
// 这二项由读入图片后设置
// biWidth := ImagePos^.Width;
// biHeight := ImagePos^.Height;
biPlanes := 1; copyright dedecms
biBitCount := 8;
biCompression := BI_RGB;// 注意,这里只使用未压缩数据
biSizeImage := 0; // 压缩时才需要 biSizeImage
biXPelsPerMeter := 0;
biYPelsPerMeter := 0;
biClrUsed := 0;
biClrImportant := 0;
end;

// 初始化 FDDSurfaceDesc2, 以免每次创建 Surface 时初始化
// 此处不用 FillChar(FDDSurfaceDesc2)
FDDSurfaceDesc2.dwSize := SizeOf(FDDSurfaceDesc2);
FDDSurfaceDesc2.dwFlags := DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT;
FDDSurfaceDesc2.ddsCaps.dwCaps := DDSCAPS_OFFSCREENPLAIN or DDSCAPS_SYSTEMMEMORY;
end;

procedure TWilFile.CreateMapView;
var
ContentFileName: string;
begin
// WIL 文件名 织梦好,好织梦

ContentFileName := FFileName + '.WIL';

// 打开 WIL 文件
FFileHandle := CreateFile(PChar(ContentFileName), GENERIC_READ, FILE_SHARE_READ, nil,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_RANDOM_ACCESS, 0);

if FFileHandle = INVALID_HANDLE_value then
raise Exception.CreateFmt('打开文件 "%s" 失败!', [ContentFileName]);

// 创建文件映射对象
FFileMapping := CreateFileMapping(FFileHandle, nil, PAGE_READONLY, 0, 0, nil);

if FFileMapping = 0 then
begin
CloseHandle(FFileHandle);
raise Exception.CreateFmt('创建文件映射 "%s" 失败!', [ContentFileName]);
end;

// 映射文件至内存
FFilePointer := MapViewOfFile(FFileMapping, FILE_MAP_READ, 0, 0, 0);
if FFilePointer = nil then
begin 织梦内容管理系统
CloseHandle(FFileMapping);
CloseHandle(FFileHandle);
raise Exception.CreateFmt('映射文件 "%s" 失败!', [ContentFileName]);
end;
end;

destructor TWilFile.Destroy;
var
I: Integer;
begin
// 清除索引文件内容
SetLength(FIndexArr, 0);

// 清除 FSurfaces 数组
for I := 0 to Length(FSurfaces) - 1 do
FSurfaces[I] := nil;
SetLength(FSurfaces, 0);

// 清除 FMainDirectDraw
FMainDirectDraw := nil;

// 关闭文件映射及相关句柄
UnmapViewOfFile(FFilePointer);
CloseHandle(FFileMapping);
CloseHandle(FFileHandle);


inherited;
end;

procedure TWilFile.LoadIndexFile;
var
F: file;
IdxHeader: TIndexHeader; copyright dedecms
NumRead: Integer;
IndexFileName: string;
begin
// 索引文件名
IndexFileName := FFileName + '.WIX';

// 打开索引文件
FileMode := fmOpenRead;
AssignFile(F, IndexFileName);
Reset(F, 1);
try
// 读索引文件头
BlockRead(F, IdxHeader, SizeOf(IdxHeader), NumRead);
if NumRead  SizeOf(IdxHeader) then
raise Exception.CreateFmt('"%s" 文件头错误!', [IndexFileName]);

// 设置索引数组大小
SetLength(FIndexArr, IdxHeader.IndexCount);

// 读索引内存至数组
BlockRead(F, PInteger(FIndexArr)^, IdxHeader.IndexCount * 4, NumRead);
if NumRead = IdxHeader.IndexCount * 4 then
FImageCount := IdxHeader.IndexCount dedecms.com

else
// 由于 Weapon.wix 的索引文件头中的图片数与实际的索引个数不同, 为了兼容,
// 即不触发异常, 详细情况见此文件最上标注.
// raise Exception.CreateFmt('"%s" 文件内容错误!', [IndexFileName]);
FImageCount := NumRead div 4;
finally
CloseFile(F);
end;
end;

procedure TWilFile.BitBlt(Index: Integer; DC: HDC; X, Y: Integer);
var
ImageInfo: PImageInfo;
PBits: Pointer;
begin
// 检查 Index 是否合法
if (Index < 0) or (Index >= FImageCount) then
raise Exception.Create('TWilFile.BitBlt 数组超界!');

// dingwei到图片位置
ImageInfo := IncPointer(FFilePointer, FIndexArr[Index]);

// 设置位图大小 织梦好,好织梦
with FBitmapInfo.bmiHeader do
begin
biWidth := ImageInfo^.Width;
biHeight := ImageInfo^.Height;
end;

// 填充调色板
Move(MainColorTable^, FBitmapInfo.bmiColors, SizeOf(FBitMapInfo.bmiColors));

// PBits 指向位图的 Bits
PBits := IncPointer(ImageInfo, SizeOf(TImageInfo) - 4);

// 直接将 DIB Bits 写到设备环境
SetDIBitsToDevice(DC, X, Y, ImageInfo^.Width, ImageInfo^.Height, 0, 0, 0,
ImageInfo^.Height, PBits, PBitmapInfo(PBitmapInfo256(@FBitmapInfo))^,
DIB_RGB_COLORS);
end;

procedure TWilFile.StretchBlt(Index: Integer; DC: HDC; X, Y, Width, Height: Integer;
ROP: Cardinal);
var
ImageInfo: PImageInfo;
PBits: Pointer;
begin
// 检查 Index 是否合法
if (Index < 0) or (Index >= FImageCount) then 本文来自织梦
raise Exception.Create('TWilFile.StretchBlt 数组超界!');

// dingwei到图片位置
ImageInfo := IncPointer(FFilePointer, FIndexArr[Index]);

// 设置位图大小
with FBitmapInfo.bmiHeader do
begin
biWidth := ImageInfo^.Width;
biHeight := ImageInfo^.Height;
end;

// 填充调色板
Move(MainColorTable^, FBitmapInfo.bmiColors, SizeOf(FBitMapInfo.bmiColors));

// PBits 指向位图的 Bits
PBits := IncPointer(ImageInfo, SizeOf(TImageInfo) - 4);

// 缩放方式将 DIB Bits 写到设备环境
StretchDIBits(DC, X, Y, Width, Height, 0, 0, ImageInfo^.Width, ImageInfo^.Height,
PBits, PBitmapInfo(PBitmapInfo256(@FBitmapInfo))^, DIB_RGB_COLORS, ROP);
end;

function TWilFile.GetSurfaces(AIndex: Integer): IDirectDrawSurface7; copyright dedecms

var
InfoPtr: PImageInfo;// 图像信息, 使用临时变量将加快速度
ColorKey: TDDColorKey;// 透明色值
DDSD: TDDSurfaceDesc2;// 用于 Surface.Lock
Y: Integer; // Surface 的行值
PBits: PByte; // 指向 Bits 的指针
DC: HDC;// 用于 Surface.GetDC
begin
// 检查 AIndex 是否合法
if (AIndex < 0) or (AIndex >= FImageCount) then
raise Exception.Create('TWilFile.GetSurfaces 数组超界!');

// 检查 MainDirectDraw 是否存在
if FMainDirectDraw = nil then
raise Exception.Create('必须指定 MainDirectDraw!'); 本文来自织梦

// 如果索引位置的 FSurface 已经创建, 则直接返回该值
Result := FSurfaces[AIndex];
if FSurfaces[AIndex]  nil then Exit;

// 否则创建新的 FSurface[AIndex]
InfoPtr := ImageInfo[AIndex];

FDDSurfaceDesc2.dwWidth := InfoPtr^.Width;
FDDSurfaceDesc2.dwHeight := InfoPtr^.Height;

if FMainDirectDraw.CreateSurface(FDDSurfaceDesc2, FSurfaces[AIndex], nil)  DD_OK then
raise Exception.Create('不能创建 WIL Surface!');

if UseDIBSurface then // 写入表面位图方法之一:使用 DC, BitBlt
begin
if FSurfaces[AIndex].GetDC(DC) = DD_OK then
begin
SelectObject(DC, NULL_BRUSH);
Rectangle(DC, 0, 0, ImageInfo[AIndex]^.Width, ImageInfo[AIndex]^.Height);
BitBlt(AIndex, DC, 0, 0); dedecms.com

FSurfaces[AIndex].ReleaseDC(DC);
end
else
begin // 如果获取 DC 失败, 则关闭当前 FSurface
FSurfaces[AIndex] := nil;
Exit;
end;
end
else // 写入表面位图方法之二:直接拷贝 WIL Bits 数据至 Surface
begin
DDSD.dwSize := SizeOf(DDSD);
if FSurfaces[AIndex].Lock(nil, DDSD, DDLOCK_WAIT, 0)  DD_OK then Exit;
// 这里比较奇怪,需要从位图的最后一行写入表面第一行,逆行序
PBits := IncPointer(InfoPtr, (SizeOf(TImageInfo) - 4) +
((InfoPtr^.Height - 1) * InfoPtr^.Width));
try
for Y := 0 to InfoPtr^.Height - 1 do 织梦内容管理系统
begin
Move(PBits^, DDSD.lpSurface^, InfoPtr^.Width);
Inc(PByte(DDSD.lpSurface), DDSD.lPitch);
Dec(PBits, InfoPtr^.Width);
end;
finally
FSurfaces[AIndex].Unlock(nil);
end;
end;

// 设置 ColorKey (黑色)
ColorKey.dwColorSpaceLowvalue := 0;
ColorKey.dwColorSpaceHighvalue := 0;
FSurfaces[AIndex].SetColorKey(DDCKEY_SRCBLT, @ColorKey);

// 返回当前 Surface
Result := FSurfaces[AIndex];
end;

function TWilFile.GetImageInfo(AIndex: Integer): PImageInfo;
begin
// 检查 AIndex 是否合法
if (AIndex < 0) or (AIndex >= FImageCount) then
raise Exception.Create('TWilFile.GetImageInfo 数组超界!'); 内容来自dedecms


// dingwei到图片位置
Result := IncPointer(FFilePointer, FIndexArr[AIndex]);
end;

procedure TWilFile.SaveToFile(Index: Integer; const FileName: string);
var
FileHeader: BITMAPFILEHEADER;
InfoHeader: BITMAPINFOHEADER;
ColorTableSize: Integer;
InfoPtr: PImageInfo;
PBits: PByte;
F: file;
begin
// 检查 AIndex 是否合法
if (Index < 0) or (Index >= FImageCount) then
raise Exception.Create('TWilFile.SaveToFile 数组超界!');

// 图片信息指针
InfoPtr := ImageInfo[Index];

// 色彩表内存大小
ColorTableSize := SizeOf(TRGBQuad) * 256;

// 位图文件头
FileHeader.bfType := MakeWord(Ord('B'), Ord('M'));
FileHeader.bfSize := SizeOf(FileHeader) + SizeOf(InfoHeader) + ColorTableSize +
InfoPtr^.Width * InfoPtr^.Height; dedecms.com
FileHeader.bfReserved1 := 0;
FileHeader.bfReserved2 := 0;
FileHeader.bfOffBits := SizeOf(FileHeader) + SizeOf(InfoHeader) + ColorTableSize;

// 位图信息头
InfoHeader.biSize := SizeOf(InfoHeader);
InfoHeader.biWidth := InfoPtr^.Width;
InfoHeader.biHeight := InfoPtr^.Height;
InfoHeader.biPlanes := 1;
InfoHeader.biBitCount := 8;
InfoHeader.biCompression := 0;
InfoHeader.biSizeImage := 0;
InfoHeader.biXPelsPerMeter := 0;
InfoHeader.biYPelsPerMeter := 0;
InfoHeader.biClrUsed := 0;
InfoHeader.biClrImportant := 0;

// 开始保存文件
FileMode := fmOpenWrite;
AssignFile(F, FileName);
Rewrite(F, 1);

try
BlockWrite(F, FileHeader, SizeOf(FileHeader));
BlockWrite(F, InfoHeader, SizeOf(InfoHeader)); copyright dedecms
if ColorTableSize > 0 then
BlockWrite(F, FMainColorTable^, ColorTableSize);
PBits := IncPointer(InfoPtr, SizeOf(TImageInfo) - 4);
BlockWrite(F, PBits^, InfoPtr^.Width * InfoPtr^.Height);
finally
CloseFile(F);
end;
end;

procedure TWilFile.Draw(Index: Integer; DstSurf: IDirectDrawSurface7;
X, Y, DstWidth, DstHeight: Integer; Transparent: Boolean);
var
R: TRect;
SizePtr: PImageInfo;
begin
SizePtr := ImageInfo[Index];
SetRect(R, X, Y, X + SizePtr.Width, Y + SizePtr.Height);
FastBlt(DstSurf, X, Y, DstWidth, DstHeight, Surfaces[Index], SizePtr.Width,
SizePtr.Height, Transparent);
end;

procedure TWilFile.DrawEx(Index: Integer; DstSurf: IDirectDrawSurface7;
X, Y, DstWidth, DstHeight: Integer; Transparent: Boolean); dedecms.com

var
SizePtr: PImageInfo;
begin
SizePtr := ImageInfo[Index];
FastBlt(DstSurf, X + SizePtr.PX, Y + SizePtr.PY, DstWidth, DstHeight,
Surfaces[Index], SizePtr.Width, SizePtr.Height, Transparent);
end;

end.

帖子地址: 





上一篇:地上爆的钱突破2000一堆修改方法
下一篇:关于动态ip处理办法
回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【乱回复灌水将给予禁言处理】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则