关于BMP文件转换为24真彩色ICO 文件的问题

imho888 2009-04-02 03:06:42

我是参考网上的一篇文章写的程序
地址:http://dev.yesky.com/449/2463449.shtml

生成的图标有问题,有热心的朋友帮忙看看哪里出来问题,非常感谢!100分送上,不够可以支会一声

我写的程序如下:

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.
...全文
182 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
grass1928 2009-04-22
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 imho888 的回复:]
靠,找到了,解决了,分全给你吧,只有你一个顶奥
[/Quote]
兄台,还是我,呵呵.我正想用DELPHI做一个EXE提取真彩色图标保存成ICO文件的小程序,可是没有找到现成的代码,只找到了你的文章,不知道可不可以分提供一下帮助啊.如果可以的话,发一份代码到我邮箱:19281928@qq.com 谢谢!
imho888 2009-04-03
  • 打赏
  • 举报
回复
靠,找到了,解决了,分全给你吧,只有你一个顶奥
constantine 2009-04-03
  • 打赏
  • 举报
回复
参考但前bcb区JSP老大写的代码。
imho888 2009-04-03
  • 打赏
  • 举报
回复
自己顶吧,难道真没人知道吗?
谁能帮我看一下问题在哪,我单独开贴加分

5,386

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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