大家一定要帮帮我,怎样将多个位图存入一个文件中(作资源文件用)(50分)

  • 主题发起人 主题发起人 jialiang
  • 开始时间 开始时间
J

jialiang

Unregistered / Unconfirmed
GUEST, unregistred user!
程序要打开好多个位图,为了节约调入时间,想把位图缩小后存入一文件中,下次就不
用再成生成了,直接可以调用。本来打算用资源文件,但不知道怎么动态生成一资源文件,
所有想能把这些个位图存入一个文件中也成啊,是否有这样的例子及控件,能够存入及
调取单个位图,最好像资源文件一样也支持多种资源,如ICO、String等。
分不多,多谢各位了。

 
1.用笔记本写一文件:abc.rc 内容如下:mybmp bitmap bmp1.bmp

2./bin/brcc32.exe abc.rc 生成abc.res文件,COPY到程序目录下

3.在程序中{$R*.RES}下加入一句:{$R ABC.RES}

4.使用:image1.picture.bitmap.loadfronresourcename(hinstance,'mybmp'};
 
使用delphi 自带的imagedit
新建一个res
可以放入ico,bmp,string等、
 
楼上的方法不错。
 
多谢各位,不过这些多是手工做的,我是想要程序动态生成,图片有多少,只有在我程序
运行时知道,也只有在程序运行时才转换为小图片,之后才存入一文件中,以便下次调用,
当然调用时还要考虑这些图片有无多出来或少几个,一句话,就是动态生成,让程序自己
实现。
自己先建个资源文件,程序运行时再往里写也想过,不过做之前我想问问各位有无其它的
方法了。
 
资源文件是编译连接时写入exe或dll文件的
 
那位有这控件的源码:
TDataCollection 是能将 .GIF、.BMP、.JPG、.ICO、.WMF 等各类图形图像文件或文字字
符串、OLE 组件压缩储存至单一文件的类,并且能够轻易读取、写入、维护储存其内数据
( 1.1 版,无源码 Delphi 5.0 版适用 ),作者 : Tomaz Koritnik。
要的就是这。
 
那位知道把图片写入dll的实现过程怎样,大概讲一下。

 
用TFileStream(文件流)来处理,分读、写两个部分:
写文件:
1、定义两个TFileStream: fsRead,fsWrite;
2、建立一个结构:
type
TMyFileRec = record
FileName : ShortString; //文件名
BeginPos: LongInt; //资源开始位置
EndPos: LongInt; //资源结束位置
end;

3、建立一个TMyFileRec类型的动态数组;
4、依次用fsRead打开图片文件,每打开一次文件就把文件信息写到动态数组中,
将fsRead中的数据拷贝到fsWrite中,fsWrite打开要写入的资源文件,将数据
写到文件尾部,当所有的图片都完后,把动态数组写到文件尾部,最后,把动
态数组长度(一个整形变量)写到文件尾部。

读文件:
1、建立一个TFileStream: fsRead,打开资源文件;
2、从资源文件尾部开始,向回读取一个整形变量(即标识动态数组长度的变量),
根据该变量读出整个动态数组(读取的尺寸为:该变量值 x SizeOf(TMyFileRec)),
再根据动态数组各元素里的信息:BeginPos,将文件指针的位置移动到BeginPos处,
读取EndPos减BeginPos的尺寸,就读出了相应位置的图片。
 
Sachow:
有示例吗?可以再加分。要不我要做个测试程序了,也够麻烦的。
 
有原理最好了(那些是由我的程序反向输出的),拿着原理自己做会更好,能弄懂这是怎么
做的。我的源程序很大,把那些部分分解出来又不太方便,而且是C++ Builder的代码,上
面有不少C的用法(指针等),你不一定会喜欢的。
如果你一定要的话,我晚上弄给你。
 
Sachow:
C++ Builder 的?如果这部分是以纯C或C++的过程、函数,那还麻烦你传一下,正想学
C++,不过不是C++ Builder。
传后,请到以下二贴子拿分,这二贴子没人答,回题我也自己解决了,所以不想浪费了,
请跟个贴给你发分.
http://www.delphibbs.com/delphibbs/dispq.asp?lid=602371(50分)
http://www.delphibbs.com/delphibbs/dispq.asp?lid=548178(50分)











 
是用的VCL类库,修改的工作量较大,尤其是从资源文件中以文件流读出图片并显示的部分,
如果改为SDK编程,会是件比较费事的活(估计需要一整天的时间)。
我试着改成Delphi的代码吧,这样还会更快一点。
 
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, JPEG, ExtCtrls, ExtDlgs;

type
TForm1 = class(TForm)
Button1: TButton;
ListBox1: TListBox;
Button2: TButton;
OpenDialog1: TOpenPictureDialog;
Panel1: TPanel;
Image1: TImage;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

TMyFileRec = record
FileName : ShortString; //文件名
BeginPos: LongInt; //资源开始位置
Size: LongInt; //资源结束位置
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var fsRead,fsWrite: TFileStream;
RA: array of TMyFileRec;
i,iCount: Integer;
begin
if OpenDialog1.Execute then
begin
fsWrite := TFileStream.Create(ExtractFilePath(ParamStr(0))+'MyFilePack.bin',fmCreate or fmOpenReadWrite);
ListBox1.Items := OpenDialog1.Files;
iCount := OpenDialog1.Files.Count;
SetLength(RA,iCount);
for i:=0 to iCount-1 do
begin
fsRead := TFileStream.Create(ListBox1.Items.Strings,fmOpenRead);

RA.FileName := ExtractFileName(ListBox1.Items.Strings);
if i=0 then
RA.BeginPos := 0
else
RA.BeginPos := RA[i-1].BeginPos + RA[i-1].Size;
RA.Size := fsRead.Size;

fsWrite.Seek(0,soFromEnd);
fsWrite.CopyFrom(fsRead,fsRead.Size);
fsRead.Free;
end;
for i:=0 to iCount-1 do
fsWrite.WriteBuffer(RA,SizeOf(TMyFileRec));
fsWrite.WriteBuffer(iCount,SizeOf(iCount));
fsWrite.Free;
ShowMessage('写包完成!');
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var fsRead: TFileStream;
MS: TMemoryStream;
Buf: TMyFileRec;
RA: array of TMyFileRec;
i,iCount,InfoSz: Integer;
begin
fsRead := TFileStream.Create(ExtractFilePath(ParamStr(0))+'MyFilePack.bin',fmOpenRead);
MS := TMemoryStream.Create;
fsRead.Seek(-1*SizeOf(iCount),soFromEnd);
fsRead.ReadBuffer(iCount,SizeOf(iCount));
InfoSz := SizeOf(TMyFileRec)*iCount;
SetLength(RA,iCount);
fsRead.Seek(-(SizeOf(iCount)+InfoSz),soFromEnd);
for i:=0 to iCount-1 do
begin
fsRead.ReadBuffer(Buf, SizeOf(TMyFileRec));
RA := Buf;
end;
i := StrToInt(Edit1.Text);
if i>iCount then
begin
ShowMessage('不存在第'+IntToStr(i)+'幅图!');
fsRead.Free;
MS.Free;
Exit;
end;
fsRead.Seek(RA.BeginPos,soFromBeginning);
MS.CopyFrom(fsRead,RA.Size);
MS.SaveToFile(ExtractFilePath(ParamStr(0))+RA.FileName);
Image1.Picture.LoadFromFile(ExtractFilePath(ParamStr(0))+RA.FileName);

RA := nil;
fsRead.Free;
MS.Free;
end;

end.

备注:Image不能直接从流中读出JPEG图片进行显示,此时用一个TJpegImage来代换一下
即可,即:先用一个TJPEGImage对象读出流中的数据,然后Image1.Picture.Assign(该JPEG对象)。
 
多谢Sachow,请到其它二个贴子跟下贴,我给你发分。

 
用记事本建立bmp.rc文件,比如
bitmap1 bitmap c:/bitmap/1.bmp
......
然后在命令行下运行brcc32 bmp.rc,即可生成bmp.res资源文件
在delphi使用命令{$R bmp.res}即可将此资源文件加入工程
使用LoadBitmap函数(可能是吧)便可从资源中调图形
 
接受答案了.
 
后退
顶部