Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Рисунок в файл, Добавление нескольких рисунков один файл 
:(
    Опции темы
dimonskif
  Дата 12.3.2006, 20:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 6.1.2006

Репутация: нет
Всего: нет



Каким образом можно несколько рисунков (и не только рисунков) добавить в один файл один за другим, чтобы в последующем можно было их оттуда вытащить и пользоваться?
я сделал так, но так только одна картинка smile
Код


procedure TForm1.Button1Click(Sender: TObject);
var
  f, f2:file of char;
  cop:char;
begin
AssignFile(f, 'c:\key.jpg');
AssignFile(f2, 'c:\picteres.txt');
{$I-}

Reset(f); 
ReWrite(f2); 
  while not Eof(f) do
  begin
    Read(f,cop);
    Write(f2,cop);
    end;
  CloseFile(f); 
  CloseFile(f2);
{$I+}

end;



PM MAIL   Вверх
Poseidon
Дата 12.3.2006, 21:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 53
Всего: 133



Несколько рисунков в один файл? Так это у тебя уже Gif-анимация получится. Или тебе не обязательно иметь возможность их отображать?
В любом случае используй базу данных


--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
dimonskif
Дата 12.3.2006, 21:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 6.1.2006

Репутация: нет
Всего: нет



Фишка в том, что отображать собранными мне их не надо. Это вроде для того, чтобы они были все в одном файле. Прога открывает этот файл и считывает из него все рисунки и файлы, а потом наоборот.
А базу данных использовать не хочу- с ней тягаться неудобно
PM MAIL   Вверх
Guedda
Дата 12.3.2006, 22:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Подрывник
****


Профиль
Группа: Завсегдатай
Сообщений: 3137
Регистрация: 27.12.2005
Где: Ростов-на-Дону

Репутация: 14
Всего: 78



И так, начнем...
ЗАДАЧА:
Мне нужно сделать, чтобы картинки сохранялись в один файл, и по требованию пользователя загружались из этого файла (например в память). И считывая картинки из памяти программа показывает их в TImage по порядку с заданным интервалом. Короче
программа-слайдшоу.

ОБЩИЙ ПЛАН:
Придумываем свой формат файла (бинарный естественно).
- Изображения ложатся в файл друг за другом. Считываются так же.
- При чтении нужно знать, сколько занимает считываемая картинка. Варианты:
а) писать перед каждой картинкой её размер (одно целое число);
б) записать вначале список, содержащий размеры всех картинок, возможно, их смещения в файле.
Первый способ самый простой и понятный. Но второй более универсальный. Он даёт возможность хранить список имеющихся изображений, возможность произвольного доступа к любой из них.
Для начинающих лучше было бы избрать первый вариант. Но я тут предпочту второй. Не люблю тупиковых направлений.
- Обычно в бинарных форматах, в самом начале, помещают заголовок файла. Сделаем и мы его. Запишем туда какую-то сигнатуру (чтобы проверять, что файл «свой») и количество изображений. Можно зарезервировать немного места для каких-то будущих расширений формата, например, добавление картинок без перезаписи файла.

ФОРМАТ ФАЙЛА:
Файл состоит из следующих частей, расположенных друг за другом
1. Заголовок
Код

TFileHead = packed record 
  Signature:   Array [1..2] of Char;  // тут пишем 'IL' – Images List 
  Version:     Array [1..2] of Byte;  // на будущее, пока 0,0 
  RecordCount: DWord;                 // количество картинок в файле 
  Reserve:     Array [1..24] of Byte; 
end;    
//Всего вышло 32 байта на заголовок 


2. Список картинок
Последовательность лежащих друг за другом записей :
Код

TFileItemDescr = packed record 
  Offset: DWord;                 // Смещение картинки в файле 
  Size:   DWord;                 // Её размер 
  Kind:   Array [1..3] of Char;  // Тип (расширение) 
  Name:   String[20];            // Если захочется хранить имя 
end;

Каждая запись описывает одну из картинок, лежащих в теле файла. Количество записей задаётся параметром RecordCount заголовка. Таким образом, длинна этой части файла SizeOf(TFileItemDescr) * RecordCount.

3. Тело файла, сами картинки.
При записи сюда ложатся друг за другом картинки. Их местоположения записаны во 2-й части формата.
Замечания
а. Используются packed record, а не просто record для того, чтобы копилятор не пытался выравнивать поля, не вставлял «дырок» между ними.
б. Строки можно хранить только как массив байтов или как короткие строки (указывается длинна). Если короткая строка, нужно иметь ввиду, что один байт отводится на хранение длинны строки.

АЛГОРИТМ ЗАПИСИ
Предполагаем, что у нас есть список файлов, содержащих картинки, которые нужно собрать в один файл «нашего» формата. Будем работать с файлом через TFileStream. Его интерфейс самый простой.

1. Описываем базовые переменные
Код

var 
  Head: TFileHead; 
  List: Array of TFileItemDescr; 

Заполняем их
Код

ZeroMemory( @Head, SizeOf(Head) ); 
Head.Signature[1] := 'I'; 
Head.Signature[1] := 'I'; 
Head.RecordCount := … 
SetLength( List, … );    

2. Открываем файл, пишем первые два блока. Второй блок пока пустой, мы просто зарезервируем место в файле.
Код

var F: TFileStream; 
F := TFileStream.Create( '…', fmCreate   ); 
F.Write( Head, SizeOf(Head) ); 
F.Write( List[0], SizeOf(TFileItemDescr) * Head.RecordCount );    

3. Пишем картинки.
Заведём для доступа к ним отдельный поток.
Код

var 
  Fi: TFileStream; 
  i,n: Integer; 
... 
for i:=0 to … do 
begin 
  Fi := TFileStream.Create( '…', fmOpenRead ); 
  n := Fi.Size; 
  List[i].Offset := F.Position; 
  List[i].Size   := n; 
  List[i].Kind   := '…'; 
  F.CopyFrom( Fi, n ); 
  Fi.Free; 
end;    

4. Сохранение списка
Теперь 2-й блок нашего файла заполнен. Запишем его на место.
Код

F.Seek( SizeOf(Head), soFromBeginning ); 
F.Write( List[0], SizeOf(TFileItemDescr) * Head.RecordCount );    

Всё. Файл записан.

АЛГОРИТМ ЧТЕНИЯ

1. Открываем файл. Проверяем, что это «наш» файл, читаем список.
Код

var 
  Head: TFileHead; 
  List: Array of TFileItemDescr; 
  F: TFileStream; 

F := TFileStream.Create( '…', fmOpenRead ); 
F.Read( Head, SizeOf(Head) ); 
if (Head.Signature <> 'IL' ) then raise … 
if (Head.Vervion[1] <> 0) or (Head.Vervion[2] <> 0) then raise … 
SetLength( List, Head.RecordCount ); 
F.Read( List[0], SizeOf(TFileItemDescr) * Head.RecordCount );    

2. Чтение картинки.
Наш формат файла предусматривает возможность чтения произвольной картинки
Код

function Xxx.LoadImage( Index: Integer ): TGraphic; 
var 
  Fi: TMemoryStream; 
begin 
with List[Index] do 
begin 
  Result := nil; 
  If Kind = 'bmp' then Result := TBitmap.Create else 
  if Kind = 'jpg' then Result := TJPEGImage.Create else 
  Exit; 
  F.Seek( Offset, soFromBeginning ); 
  Fi := TMemoryStream.Create; 
  Fi.CopyFrom( F, Size ); 
  Fi.Offset( 0, soFromBeginning ); 
  Result.LoadFromStream( Fi ); 
  Fi.Free; 
end; 
end;    


Ну вот, вроде бы и всё. Надеюсь, что этого будет достаточно, чтобы Вы разобрались и написали работающий код. Все фрагменты кода писались «с ума», т.е. могут содержать описки, ошибки.

По поводу хранения в БД. Конечно, это тоже вариант. Скорее всего он даже даст более простую реализацию. Но по-моему, для такой простой задачи подключать БД – излишество. Тут никаких связей, поисков, только хранение данных в одной единственной табличке.

Это сообщение отредактировал(а) Guedda - 12.3.2006, 22:30


--------------------
Ll 2
PM MAIL WWW ICQ Skype GTalk   Вверх
Alexeis
Дата 13.3.2006, 10:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Guedda, Зачем так сложно можно ведь в ресурс поместить или
еще лучше в паинте склеить все справа налево сверху вниз тогда
вообще можно будет их грузить при помощи TImageList одной командой.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Snowy
Дата 13.3.2006, 10:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



PM MAIL   Вверх
Guedda
Дата 13.3.2006, 10:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Подрывник
****


Профиль
Группа: Завсегдатай
Сообщений: 3137
Регистрация: 27.12.2005
Где: Ростов-на-Дону

Репутация: 14
Всего: 78



Я понимаю, что можно и в ресурс (чтобы все картинки были в программе), и по другому... Но человек попросил именно сохранить несколько картинок в один файл. И как, по-твоему, можно сохранить в файл ImageList с картинками быстрее, чем этот способ?

ИМХО, код нормальный, удовлетворяющий требованию участника, который задал этот вопрос.


--------------------
Ll 2
PM MAIL WWW ICQ Skype GTalk   Вверх
Snowy
Дата 13.3.2006, 10:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Если не торопит, то подожди недельку.
Я как раз работаю над такой тулзой, которая собирает файлы в кучу и генерит код для работы с ними.
PM MAIL   Вверх
Alexeis
Дата 13.3.2006, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Цитата

как, по-твоему, можно сохранить в файл ImageList с картинками быстрее, чем этот способ?


делается картинка на подобии этой
http://alexei-s1.narod.ru/Image2.jpg
А ImageList воспринимает ее как набор картинок одинакового (например 16х16) размера и позволяет обращатся к каждой.

Способ создания не быстрый(в графическом редакторе) зато наглядный.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Guedda
Дата 13.3.2006, 18:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Подрывник
****


Профиль
Группа: Завсегдатай
Сообщений: 3137
Регистрация: 27.12.2005
Где: Ростов-на-Дону

Репутация: 14
Всего: 78



Я то это знаю... А если каждый раз прийдется? Заново постоянно перерисовывать картинки?


--------------------
Ll 2
PM MAIL WWW ICQ Skype GTalk   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0587 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.