Проблема с загрузкой png изображения из inifile
Я сохраняю 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 я использовал тот же подход:
- Загрузить данные в объект TMemoryStream
- Загрузить данные из MemoryStream в объект TPngImage
Показать картинку в компоненте 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;
однако я всегда получаю ошибку исключения:
2 ответа
TIniFile
имеет жестко ограниченный размер любого значения, которое он может прочитать, частично из-за того, что в основе лежит API Windows (GetPrivateProfileString
и друзья) не позволяет запрашивать размер сохраненного значения. IMO TIniFile
должно действительно вызывать исключение при попытке записать большее значение, но независимо от того, если вы используете TMemIniFile
вместо TIniFile
у вас должно быть все в порядке (я только что попробовал).
Крис ответил на прямой вопрос, который вы задали. У меня есть некоторые другие комментарии.
Нет необходимости декодировать 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 никогда не предназначались для хранения больших двоичных двоичных объектов. При первом осмотре может показаться странным, что вы пытаетесь вставить PNG-изображение в INI-файл.