Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 1 047

/ вопрос открыт /

Доброго времени суток, уважаемые эксперты!

1. Как организовать хранение набора изображений в одном файле?

2. Как добавить изображение (записать) в ветку xml (в текстовом виде, как в dfm в Delphi?

Alexx-358 Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: Alexx-358 (статус: Посетитель)
Вопрос отправлен: 29 октября 2007, 05:30
Состояние вопроса: открыт, ответов: 1.

Ответ #1. Отвечает эксперт: Вадим К

Здравствуйте, Alexx!
Есть универсальный метод хранения изображений.
XML в данном случае будет слишком избыточным (картинка на 100 кб будет занимать чуть больше 200 кб). Суть заключается в разработке правильного формата.
итак, запись обычно идёт так. вначале файла записываем пару байт - сигнатура.
дальше пишем 4 байта - кол-во картинок
а дальше в цикле размер картинки, какие то данные - например имя её и сама картинка. Причём можно не только bmp, а и любые другие, даже не картинки
в коде это будет выглядеть где то так

var 
  abm:array of TBitmap;
  i:integer;
  b:byte;
  fs:TFilestream;
  ms:TMemoryStream;
  s :string[10];//размер должен быть задан!
begin
  fs := TFileStream.create('filename', fmCreate);
  b:=10;  fs.write(b,1);
  b:=20;  fs.write(b,1);//сигнатуру записали
  fs.write(length(abm),4);
  for i:= 0 to length(abm)-1 do begin
    s := 'namepict';
    fs.write(s[1], 10);
    ms:=TMemoryStream.create;
    abm[i].SaveToStream(ms);
    fs.write(ms.size,4);
    ms.SaveToStream(fs);
    ms.free;
  end;
end;
чтение подобно
var 
  abm:array of TBitmap;
  i, l,sz:integer;
  b:byte;
  fs:TFilestream;
  ms:TMemoryStream;
  s :string[10];//размер должен быть задан!
begin
  fs:=TFileStream.create('filename', fmOpenRead);
  fs.read(b,1);fs.read(b,1);//вычитали сигнатуру. дальше может проверку сделать
  fs.read(l,4); // кол-во объектов
  SetLength(abm,l);
  for i:=0 to l-1 do
  begin
    abm[i]:=TBitmap.create;
    fs.read(s[1], 10);//метку прочитали
    fs.read(sz,4);//размер прочитали
    ms:=TMemorySream.create;
    ms.copyFrom(fs, sz);
    abm[i].loadFromStream(ms);
    ms.free;
    fs.position := fs.position + sz;
  end;
  fs.free;
end;
приимущество этого способа - что сделав метку, можно организовать по ним case и грузить самые разнообразные объекты (TStringList тоже умеет сохранятся в поток). а если объект, сохранённый в потоке нам неизвестен, то всегда можно пропустить его.

по поводу второго вопроса. преобразовать изображение в "строку". Это просто.
сохранение в строку (c Image в Memo)
  var
  ms:TMemoryStream;
  s:string;
  i:integer;
  b:byte;
begin
  ms := TMemoryStream.Create;
  Image1.Picture.Bitmap.SaveToStream(ms);
  ms.Position := 0;
  setlength(s,ms.size*2);
  for i := 0 to ms.size-1 do
    begin
      ms.Read(b,1);
      s[i*2+1] := inttohex((b and $F0) shr 4,1)[1];
      s[i*2+2] := inttohex((b and $F),1)[1];
    end;
  memo1.Lines.Text := s;
  ms.Free;
end;
и обратно
  var
  ms:TMemoryStream;
  s:string;
  i:integer;
  b:byte;
begin
  s:=memo1.Lines.text;
  ms := TMemoryStream.Create;
 
  for i:=0 to (length(s)-2) div 2 do
    begin
      b := Strtoint('$'+copy(s, i*2+1,2));
      ms.Write(b,1);
    end;
  ms.Position := 0;
  Image2.Picture.Bitmap.LoadFromStream(ms);
  ms.Free;
end;

Ответ отправил: Вадим К (статус: Академик)
Время отправки: 29 октября 2007, 12:48
Оценка за ответ: 5

Комментарий к оценке: Спасибо

Мини-форум вопроса

Всего сообщений: 2; последнее сообщение — 30 октября 2007, 14:52; участников в обсуждении: 2.
Alexx-358

Alexx-358 (статус: Посетитель), 29 октября 2007, 11:07 [#1]:

Поясню.. мне надо разработать хранилище файлов графических форматов на основе одного файла-контейнера.
Покажите на примере с bmp, пожалуйста.. Как привести зображение к такому виду (из dfm)

Left = 8
Top = 8
Width = 105
Height = 105
Picture.Data = {
07544269746D617076580200424D765802000000000076000000280000008002
0E00100000100040000000000005802000000000000000000100000000000
0000000000000000800000800000008080008000000080008000808000007F7F
7F00BFBFBF000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFF
FF00BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF1FB1BFBFBFBFBF
BFBFB3BFBFBFBFBFBFBFB1BF1FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF
BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF
BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB1BF1F
BFBFBFBFBFBFBFBFBFB1BFBFBFB3BFBFBFB3BFBFBFB1BFBFBFB3BFBFBFB3BFBF
BFB1BFBFBFBFBFBFBFBFBFBF1FB1BFBFBFBFBFBFBFBFBFBF1FBFBFBFBFBFBFBF
BFBFBFBF1FBFBFBFBFBFBFBFBFBFBFBF1FBFBFBFBFBFBFBFBFBFB1BF1FBFBFBF
BFBFBFBFBFBFB1BFBFBFB3BFBFBFB3BFBFBFB1BFBFBFB3BFBFBFB3BFBFBFB1BF}
Feniks

Feniks (статус: Бакалавр), 30 октября 2007, 14:52 [#2]:

Я так понимаю, Вы хотите преобразовать бинарный файл (BMP) в набора байт в текстовом виде. Для этого используйте функцию IntToHex, он описана в Хелпе. А далее все просто, используйте формат INI-файла или просто пишити сразу все в TXT-файл.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:46
Выполнено за 0.03 сек.