将图像和其他数据保存到delphi中的文件

时间:2014-09-25 09:05:08

标签: delphi

我有一个图像,一个字符串和一个整数,我需要保存/读取为文件。什么是最好的方法来做到这一点。我在考虑一个TStream,但我不确定如何实现它。

3 个答案:

答案 0 :(得分:3)

虽然您可以使用自己的容器格式,但使用预先存在的容器格式对我来说更有意义。

对我来说最明显的选择是ZIP文件。 Delphi内置了库来读写ZIP文件。这就是Office保存文件的方式。就像Office一样,您不需要使用.zip扩展名。

您可以将图像放在ZIP中的一个文件中,将元数据放在另一个文件中。例如,元数据可以作为JSON持久化。

答案 1 :(得分:3)

您可以使用Delphi的内置组件流支持,并将其保存为二进制或文本数据。这种方法的一个缺点是,如果您的图像是高分辨率的,那么与图像的原始文件格式相比,当将内存像素数据转储到磁盘时,您可能会受到更大文件大小的惩罚。 JPEG。在下面的示例中,我从TImage派生了一个类,并添加了一个字符串值MyString和一个整数MyInteger并保存为二进制数据。

将组件流式传输到二进制文件

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls;

type
  TMyImage = class(TImage)
  private
    FString : string;
    FInteger : integer;
  public

  published
    property MyString: string read FString write FString;
    property MyInteger: Integer read FInteger write FInteger;
  end;

  TFormMain = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    FMyImage : TMyImage;
    FMyImage2 : TMyImage;
  public

  end;

var
  FormMain: TFormMain;

implementation

{$R *.dfm}    

procedure WriteComponent(Component: TComponent; Filename : String);
var
  m :TMemoryStream;    
begin
  m := TMemoryStream.Create;
  try
    m.WriteComponent(Component);
    m.Seek(0, soFromBeginning);
    m.SaveToFile(Filename);
  finally
    m.Free;
  end;
end;

function ReadComponent(Filename : String): TComponent;
var
  m :TMemoryStream;    
begin
  m := TMemoryStream.Create;
  try
    m.LoadFromFile(FileName);
    m.Seek(0, soFromBeginning);
    result := m.ReadComponent(nil);
  finally
    m.Free;
  end;
end;

procedure TFormMain.FormCreate(Sender: TObject);
begin
  FMyImage := TMyImage.Create(Self);

  FMyImage.Picture.LoadFromFile('C:\...\Delphi\Common Images\ALIGNPAL.BMP');
  FMyImage.MyString := 'Hello World';
  FMyImage.MyInteger := 12345;

  WriteComponent(FMyImage, 'c:\test.dat');
  FMyImage2 := ReadComponent('c:\test.dat') as TMyImage;
end;

initialization

 RegisterClass(TMyImage);

end.

简化方法

如果你只想使用一个字符串和一个整数,那么你可以使用TImage的字幕和标签属性。

...
FImage : TImage;
FImage2 : TImage;
....

procedure TFormMain.FormCreate(Sender: TObject);
begin
  FImage := TImage.Create(Self);

  FImage.Picture.LoadFromFile('C:\...\Delphi\Common Images\ALIGNPAL.BMP');
  FImage.Caption := 'Hello World';
  FImage.Tag := 12345;

  WriteComponent(FImage, 'c:\test.dat');

  FImage2 := ReadComponent('c:\test.dat') as TImage;
end;

将组件流式传输到文本

如果你想通过对二进制数据进行字符串表示来获得更多“可读”的数据文件,下面我还添加了有用的辅助函数found here。但文件大小会增加。

function StringToComponentProc(Value: string): TComponent;
var
  StrStream:TStringStream;
  BinStream: TMemoryStream;
begin
  StrStream := TStringStream.Create(Value);
  try
    BinStream := TMemoryStream.Create;
    try
      ObjectTextToBinary(StrStream, BinStream);
      BinStream.Seek(0, soFromBeginning);
      Result:= BinStream.ReadComponent(nil);
    finally
      BinStream.Free;
    end;
  finally
    StrStream.Free;
  end;
end;

function ComponentToStringProc(Component: TComponent): string;
var
  BinStream:TMemoryStream;
  StrStream: TStringStream;
  s: string;
begin
  BinStream := TMemoryStream.Create;
  try
    StrStream := TStringStream.Create(s);
    try
      BinStream.WriteComponent(Component);
      BinStream.Seek(0, soFromBeginning);
      ObjectBinaryToText(BinStream, StrStream);
      StrStream.Seek(0, soFromBeginning);
      Result:= StrStream.DataString;
    finally
      StrStream.Free;
    end;
  finally
    BinStream.Free
  end;
end;

答案 2 :(得分:1)

this SO问题中讨论了向图像添加任意数据而不影响可用性的一些有趣的方法。

  • Exif - 可交换图像文件格式是一种标准,用于指定数码相机(包括智能手机),扫描仪和处理录制的图像和声音文件的其他系统使用的图像,声音和辅助标签的格式通过数码相机。
  • XMP - 可扩展元数据平台是ISO标准,最初由Adobe Systems Inc.创建,用于创建,处理和交换各种资源的标准化和自定义元数据。
  • 隐写术是隐藏其他消息,图片或文件中的消息,图片或文件的艺术或做法。