5,386
社区成员
发帖
与我相关
我的任务
分享
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type tagIconDirEntry = packed record
bWidth:BYTE;// 图标图片的显示宽度,以像素为单位,最大值为255 ($10=16D)
bHeight:BYTE;// 图标图片的显示高度,以像素为单位,最大值为255 ($10=16D)
bColorCount:BYTE;// 图标图片的颜色数($00)
bReserved:BYTE;// 保留域总是 0 ($00)
wPlanes:WORD;// 图标图片的位面数 ($00 00)
wBitCount:WORD;// 图标图片的颜色深度($00 00)
dwBytesInRes:DWORD;// 图标图片占用的数据量($00000568)
dwImageOffset:DWORD; // 图标图片的开始位置 ($00000046)
end;// 这个结构是16个字节
type tagIconDir = packed record
idReserved:WORD;// 保留域,目前始终为 0(开始的数据$00 00)
idType:WORD; //定义为资源类型,图标值为 $0001、光标是$0002($0001)
idCount:WORD; //idCount 表示的是这个文件里包含了几个图标($0004)
idEntries:array[0..0] of tagIconDirEntry; //不包括本数组,以上一共6个字节
end;
type
TFormMain = class(TForm)
Button1: TButton;
Image1: TImage;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
function MakICOData( Mem:TStream): Boolean;
function MakICOHead(const Mem:TStream): Boolean;
end;
var
FormMain: TFormMain;
IconHand: tagIconDir;
iMemory:TMemoryStream;
implementation
{$R *.dfm}
function TFormMain.MakICOData( Mem:TStream): Boolean;
var
Mem1,Mem2:TMemoryStream;
Size:Longint;
BmtMapHandle2:TBitmapInfoHeader;
begin
Mem1:=TMemoryStream.Create;
Mem2:=TMemoryStream.Create;
Size:=Mem.Size-14;//跳过14字节的BMP文件由文件头
Mem.Position:=14;
try
Mem1.SetSize(Size);
Mem.Read(Mem1.Memory^,Size);//BMP到Mem1
Mem1.Seek(0,soFromBeginning);
Mem1.Read(BmtMapHandle2,sizeof(TBitmapInfoHeader));//BMP文件的信息头
Mem2.SetSize(Size-40);//跳过40字节的BMP文件信息头
FillChar(Mem2.Memory^,Size-40,$0);//Mem2填充0 ,使掩码效果为白色
Mem2.Position:=0;
BmtMapHandle2.biHeight:=IconHand.idEntries[0].bHeight *2;//有两幅图
BmtMapHandle2.biSizeImage:=Mem2.Size*2;
Mem1.Seek(0,soFromBeginning);
Mem1.Write(BmtMapHandle2,sizeof(TBitmapInfoHeader));
Mem1.Position:=0;
Mem.Size:=0;
//MS.SetSize(0);
Mem.Write(IconHand,sizeof(tagIconDir){22});//写ICO文件头
Mem.Write(Mem1.Memory^,Mem1.Size);//写BMP片
Mem.Write(Mem2.Memory^,Mem2.Size);//写掩码
Result:=True;
finally
FreeAndNil(Mem1);
FreeAndNil(Mem2);
end;
end;
function TFormMain.MakICOHead(const Mem:TStream): Boolean;
var//采用流来生成
BMPHead1:tagBITMAPFILEHEADER;
BMPHead2: TBitmapInfoHeader;
BitsTotal:DWord;
begin
Result:=False;
Mem.Position:=0;
Mem.Read(BMPHead1,SizeOf(tagBITMAPFILEHEADER));//读取BMP文件由文件头
Mem.Read(BMPHead2,SizeOf(TBitmapInfoHeader));// 读取BMP位图信息头
if BMPHead2.biCompression=0 then //位图没有压缩
begin
if (BMPHead2.biWidth<=255) and (BMPHead2.biHeight <=255)then
begin
//caption:=IconFileName;
IconHand.idEntries[0].bWidth:= Byte(BMPHead2.biWidth) ;//IOC宽
IconHand.idEntries[0].bHeight:=Byte(BMPHead2.biHeight); //IOC高
BitsTotal:=(Mem.Size-54)*2+40;
//(BMP文件的大小- 文件头、位图信息头)*2+位图信息头=ICO数据量
//乘以二的原因是:加icXOR的信息
IconHand.idEntries[0].dwBytesInRes:= BitsTotal;
IconHand.idEntries[0].dwImageOffset:=$00000016;
Result:=True;
end;
Mem.Position:=0;
end;
end;
procedure TFormMain.Button1Click(Sender: TObject);
begin
iMemory:=TMemoryStream.Create;
try
Image1.Picture.Bitmap.SaveToStream(iMemory);
Image1.Picture.Assign(nil);
if MakICOHead(iMemory) then
begin
if MakICOData(iMemory) then
begin
iMemory.Position:=0;
Image1.Picture.Icon.LoadFromStream(iMemory);
end;
end;
finally
iMemory.Free;
end;
end;
end.