Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "KOL";
Текущий архив: 2008.04.06;
Скачать: [xml.tar.bz2];

Вниз

PBitmap: запись и считывание из потока   Найти похожие ветки 

 
BMouradov   (2007-08-08 19:44) [0]

По-моему, Bitmap как-то неправильно работает с потоками: картинка pf24bit 13x13. Записываю в поток:

   FBmp.SaveToStream(Stream);

Смещение Position на 474 байта.

Далее, считываю с самого начала из этого же потока, проверяю, что на входе Position имеет то же значение. Далее считываю:

   FBmp := NewBitMap(0, 0);
   FBmp.LoadFromStream(Stream);

но обнаруживаю, что смещение было всего на 54 байта.
При этом размеры и pixelformat правильно считались. Далее, разумеется, программа работать уже не могла. Помогите разобраться, пожалуйста.

Проверил так же у KolPng - там все нормально.
А у KolGif, к великому сожалению, нет метода SaveToStream.


 
Vladimir Kladov   (2007-08-08 19:55) [1]

Посмотрю позже. У меня вроде работало. Попробуйте пока TBitmap.LoadFromStreamEx.


 
BMouradov   (2007-08-08 21:36) [2]

Посмотрел. Всё то же самое, те же 54 байта. Прислать ли пример?


 
Vladimir Kladov   (2007-08-08 23:05) [3]

Зачем же, сам построю.


 
Dimaxx ©   (2007-08-09 10:12) [4]

Сорри за оффтоп. Владимир, перезалейте KOLadd на kolmck.net - архив поврежден.


 
Galkov ©   (2007-08-09 10:52) [5]

2Dimaxx
я сначала тоже так думал. А сейчас думаю что сервак глючит - отдает не все, а сколько ему бог на душу положит


 
Vladimir Kladov   (2007-08-09 16:28) [6]

Вот я и на даче. Посмотрел, всё нормально сохраняется и считывается.

procedure TForm1.Button1Click(Sender: PObj);
var B, B2: PBitmap;
   S: PStream;
begin
 B := NewDibBitmap( 13, 13, pf24bit );
 B.Canvas.Brush.Color := clRed;
 B.Canvas.FillRect( B.BoundsRect );
 B.Canvas.Brush.Color := clGreen;
 B.Canvas.Ellipse( 2, 2, B.Width-2, B.Height-2 );

 S := NewMemoryStream;
 B.SaveToStream( S );

 B2 := NewBitmap( 0, 0 );
 S.Position := 0;
 B2.LoadFromStream( S );

 B.SaveToFile( GetStartDir + "1.bmp" );
 B2.SaveToFile( GetStartDir + "2.bmp" );

 B.Free;
 B2.Free;
 S.Free;
end;


 
BMouradov   (2007-08-10 21:47) [7]

Кажется, понял, откуда проблема. Дело в том, что TBitMap.LoadFromStream не совсем корректно использует Stream.Size, а для сжатых потоков Stream.Size = -1. В моем случае это было

Stream := KolZLib.NewDecompressionStream(FileStream, nil);

Попробовал также Gif-файл записать в поток, а потом считать. Не уверен, но похоже, что KolGif из сжатых потоков также неправильно считывается.

Vladimir, хочу спросить, будет ли эта ситуация исправляться, или на это не нужно надеяться, и искать обходные пути (например, сначала создавать промежуточный поток).


 
Vladimir Kladov   (2007-08-11 09:13) [8]

Не надо на это надеяться, потому что действительно нужен размер остатка у того же битмапа. Исправляется достаточно легко: сначала распаковываете сколько надо в поток в памяти, из него загружаете. Если в потоке несколько картинок, то надо тогда записывать размер несжатой картинки перед ее началом, чтобы знать, сколько распаковывать.


 
BMouradov   (2007-08-11 12:29) [9]

Да, понял, спасибо.

"размер несжатой картинки" - подскажите, как проще всего выяснить этот размер перед записью в поток?

Чисто из любопытства: "нужен размер остатка у того же битмапа" - а разве этот размер не определяется однозначно размерами и форматом пиксела?


 
Vladimir Kladov   (2007-08-11 13:08) [10]

Если бы все так просто было с этими битмапами, фотошоп 5 умел бы нормально загружать pf16bit. А так у него получается правильно только с 24 или 8 и меньше. Поле "смещение изображения в файле" может врать, потому что не все стандарт соблюдают, и когда впихивают 12 байт маски, а когда и нет. И с 24 бит тоже проблемы с этой маской каналов r, g, b бывают.

Размер несжатой - до сжатия.


 
BMouradov   (2007-08-11 13:22) [11]

"Размер несжатой - до сжатия" - Это я понимаю. Но как узнать размер несжатой? Я вижу такой путь: создать дополнительный memorystream, записать туда битмап и посмотреть memorystream.size или memorystream.position. Нет ли более простого пути?


 
Vladimir Kladov   (2007-08-11 18:07) [12]

Это вроде как и есть самый простой путь. Более сложный: зная формат картинки, посчитать ее размер = (число пикселей в строке * бит/на пиксель  / 8 + 3) and not 3 * число строк, прибавить размер заголовка, прибавить размер палитры или маски если есть. Вряд ли это решени целесообразно, если только речь не идёт о битмапах больше 2048х1600.


 
ANTPro ©   (2007-08-11 18:17) [13]

> [11] BMouradov   (11.08.07 13:22)

Преред сжатием, надо сохранять оригинальный размер.


 
BMouradov   (2007-08-12 01:24) [14]

Владимиру:

Все понятно. Спасибо!



Страницы: 1 вся ветка

Форум: "KOL";
Текущий архив: 2008.04.06;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.007 c
15-1203811272
Германн
2008-02-24 03:01
2008.04.06
Внесение французской кухни в список Всемиирного наследия ЮНЕСКО.


2-1205254732
NaRuTo
2008-03-11 19:58
2008.04.06
Проиграть видео без MediaPlayer и DirectX


4-1186298246
aKirill
2007-08-05 11:17
2008.04.06
Как определить разришение(олбласть) экрана на два.. манитора


6-1184321913
Alexey_k
2007-07-13 14:18
2008.04.06
Подсчёт инет-трафика


15-1203749829
NaRuTo
2008-02-23 09:57
2008.04.06
Protect





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский