Чтение (запись) файла в (из) Image черз буфер

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Чтение (запись) файла в (из) Image черз буфер

Сообщение shyub » 29.02.2016 15:38:40

При открытии графического файла помимо отображения рисунка хотелось бы прочитать и его заголовок. Для этого хотелось бы использовать что-то типа такой процедурц.
Код: Выделить всё
procedure TForm1.ReadDPI();
var
  Buffer: ^Byte;
  Stream: TFileStream;
  Size:   LongInt;
begin
  Stream := TFileStream.Create(UTF8ToSys(OpenPictureDialog1.FileName), fmOpenRead);
  try
    Size := Stream.Size;
    GetMem(Buffer, Size);
    try
      Stream.ReadBuffer(Buffer[0], Size);

      ...   // Здесь проверка заголовка графического файла.

      Image1.Picture.LoadFrom...(Buffer);   // Как это можно сделать?
    finally
      FreeMem(Buffer);
    end;
  finally
    Stream.Free;
  end;
end;

Можно было бы после проверки заголовка загрузить файл с диска:
Код: Выделить всё
...
ReadDPI();
Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);
...

Но не хотелось бы дважды обращаться к диску.
Далее. Перед сохранении графического файла на диске необходимо "в рукопашную" откорректировать его заголовок, т.е. из Image выгрузить графический файл сначала в буфер, а после коррекции заголовка перенести его на диск.
shyub
постоялец
 
Сообщения: 112
Зарегистрирован: 25.11.2014 23:15:19

Re: Чтение (запись) файла в (из) Image черз буфер

Сообщение Дож » 01.03.2016 01:42:57

Но не хотелось бы дважды обращаться к диску.

Можно загрузить весь файл в память, дальше уже грузиться из памяти.

Можно открыть файл каким-нибудь потоком с буферизацией и поддержкой Rewind'а, прочесть картинку, далее сделать Rewind на начало и прочесть заголовок.

Можно воспользоваться ленивым mmap'ом.

Далее. Перед сохранении графического файла на диске необходимо "в рукопашную" откорректировать его заголовок, т.е. из Image выгрузить графический файл сначала в буфер, а после коррекции заголовка перенести его на диск.

Создаём поток, записывающий данные в оперативку, сохраняем в него изображение, хачим заголовок в памяти и уже результирующую память сохраняем в файл.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Чтение (запись) файла в (из) Image черз буфер

Сообщение shyub » 01.03.2016 09:05:13

Дож, спасибо Вам за совет.
Однако, загрузить в памят у меня получается
Stream.ReadBuffer(Buffer[0], Size);
(запись из оперативки в файл - аналогично), но проблема с загрузкой из памяти в Image и выгрузкой из Image в память.
Буду очень Вам благодарен, если приведёте пример функций, которые позволят это реализовать...
shyub
постоялец
 
Сообщения: 112
Зарегистрирован: 25.11.2014 23:15:19

Re: Чтение (запись) файла в (из) Image черз буфер

Сообщение Снег Север » 01.03.2016 09:30:21

Вот рабочий пример из Делфи, если это то, о чем спрашивали:
Код: Выделить всё
function TCPicture.ReadFromStream(var Stream : TStream) :boolean;
var
   FirstBytes: AnsiString;
begin
    Result := false;
    if Stream.Size = 0 then
    begin
         Result := true;
         Exit;
    end;
    SetLength(FirstBytes, 8);
    Stream.Read(FirstBytes[1], 8);
    if Copy(FirstBytes, 1, 2) = 'BM' then
    begin
      FPicture.Graphic := TBitmap.Create;
    end else
    if FirstBytes = #137'PNG'#13#10#26#10 then
    begin
      FPicture.Graphic := TPngImage.Create;
    end else
    if Copy(FirstBytes, 1, 3) =  'GIF' then
    begin
      FPicture.Graphic := TGIFImage.Create;
    end else
    if Copy(FirstBytes, 1, 2) = #$FF#$D8 then
    begin
      FPicture.Graphic := TJPEGImage.Create;
    end;
    if Assigned(FPicture.Graphic) then
    begin
      try
        Stream.Seek(0, soFromBeginning);
        FPicture.Graphic.LoadFromStream(Stream);
        Result := true;
      except
      end;
    end;
end;
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2995
Зарегистрирован: 27.11.2007 16:14:47

Re: Чтение (запись) файла в (из) Image черз буфер

Сообщение Дож » 01.03.2016 12:21:56

shyub писал(а):Дож, спасибо Вам за совет.
Однако, загрузить в памят у меня получается
Stream.ReadBuffer(Buffer[0], Size);
(запись из оперативки в файл - аналогично), но проблема с загрузкой из памяти в Image и выгрузкой из Image в память.
Буду очень Вам благодарен, если приведёте пример функций, которые позволят это реализовать...

Нужно над памятью создать поток и читать уже из него, это делает TMemoryStream
http://www.freepascal.org/docs-html/rtl ... mfile.html
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47


Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 23

Рейтинг@Mail.ru