从inifile加载png图像的问题

时间:2014-12-21 16:32:33

标签: delphi png ini

我使用以下代码将PNG图像存储到Ini文件中:

procedure TfrmParametres.SaveIni;
var
  IniFile: TIniFile;
  MS: TMemoryStream;
  PNG: TPngImage;
begin
  IniFile := TIniFile.Create(IniFileName);
  try
  PNG := TPngImage.Create;
  try
    PNG.LoadFromFile(edtLogo.Text);//edtlogo contain image file path
    MS  := TMemoryStream.Create;
    try
      PNG.SaveToStream(MS);
      MS.Seek(0, 0);
      IniFile.WriteBinaryStream('REPORT_HEADER', 'LOGO', MS);
    finally
      MS.Free;
    end;
  finally
    PNG.Free;
  end;
finally
  FreeAndNil(IniFile);
end;
end;

并以另一种形式显示图片OnShow事件我使用了相同的方法:

  1. 在TMemoryStream对象中加载DATA
  2. 从DATAStream加载DATA到TPngImage对象
  3. 在TImage组件中显示图片

    procedure TfrmLoadPicture.FormShow(Sender: TObject);
    var
      IniFile: TIniFile;
      MS: TMemoryStream;
      PNG: TPngImage;
    begin
      IniFile:= TIniFile.Create(frmParametres.IniFileName);
      try
        MS:= TMemoryStream.Create;
        try
          IniFile.ReadBinaryStream('REPORT_HEADER', 'LOGO', MS);
          PNG := TPngImage.Create;
          try
            MS.Seek(0, 0);
            PNG.LoadFromStream(MS);
            Image.Picture.Assign(PNG);
          finally
            PNG.Free;
          end;
        finally
          MS.Free;
        end;
      finally
        IniFile.Free;
      end;
    end;
    
  4. 然而我总是得到异常错误: enter image description here

2 个答案:

答案 0 :(得分:5)

TIniFile对其可读取的任何一个值的大小都有一个硬编码上限,部分原因是底层Windows API(GetPrivateProfileString和朋友)不允许查询保存值的大小。 IMO TIniFile应该在尝试写一个更大的值时引发异常,但无论如何,如果你使用TMemIniFile而不是TIniFile,你应该没问题(我只是试过了)它)。

答案 1 :(得分:1)

克里斯回答了你提出的直接问题。我还有其他一些评论。

无需解码PNG以将其传输到INI文件

您可以直接复制文件而无需解码PNG,然后重新编码。

Stream := TFileStream.Create(FileName, fmOpenRead);
try
  IniFile.WriteBinaryStream('REPORT_HEADER', 'LOGO', Stream);
finally
  Stream.Free;
end;

十六进制编码效率不高

WriteBinaryStream不是将二进制编码为文本的非常有效的方法。实际上,您使用的是base16,使用base64会更加传统和高效。

我建议您将二进制文件流编码为base64字符串,并将该字符串写入INI文件。

INI文件不适合二进制数据

INI文件从未打算用于存储大型二进制blob。在第一次检查时,您尝试将PNG图像转换为INI文件似乎很奇怪。