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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> GDI+: Загрузка PNG из потока, выскакивает окошко "CPU" 
V
    Опции темы
JohnJ2
Дата 21.4.2009, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Здравствуйте! Не могу разобраться в следующей ситуации:
Загружаю картинку из потока:
Код

procedure TTestGDIP.GDIPLoadImage(aStream: TStream);
var imgFile: TGPImage; 
    aptr: IStream;
begin
  aStream.Seek(0, soFromBeginning);
  aptr := TStreamAdapter.Create(aStream, soReference) as IStream;
  imgFile := TGPImage.Create(aptr); //создаем класс используя поток
  GDIPLoadTGPImage(imgFile);
  imgFile.Free;//уничтожаем класс изображения
end;

Поток получаю от TIdHTTP.Get, которому задаю адрес любой картинки PNG (например: http://nigma.ru/themes/nigma/img/nigma-logo-small.png), и передаю в вышеприведённую процедуру.
Такой вариант работает, но! На строке "imgFile := TGPImage.Create(aptr);" появляется окошко с ассемблеровским кодом с заголовком "CPU". Содержимое выделенной строки (если как-то поможет) "7С90120F C3 ret". Чуть выше строчка "{ntdll.DbgBreakPoint}". Когда я закрываю это ассемблеровское окошко и нажимаю F9, то картинка рисуется как ни в чём не бывало. Если из потока сохранять сначала в файл и потом загружать из файла в TGPImage, то всё работает без проблем. А почему тут такая фигушка?
P.S.: Пробовал aptr создавать так: 
aptr := TStreamAdapter.Create(aStream, soReference);
Ничего не изменилось. 
Другие форматы картинок (bmp, jpg, gif) открываются без проблем, а при png возникает такое вот "прерывание".
Саму технологию загрузки в TGPImage изучал по статье: http://forum.vingrad.ru/faq/topic-157721.html
Нашёл, что и у других были подобные проблемы с png: вопрос по подобной проблеме, и найдено решение, но ссылка на приведённое решение не грузится.
Я плохо разбираюсь в английском, поэтмоу не понял, эта статья по теме или нет, но что-то тоже с проблемами png и gdi: http://lummie.co.uk/tstreamadapter-and-images/
Цитата
When trying to load / save PNG Images from a stream using GDI+ routines to load and save from IStream, there were problems, it turns out with the date/time information returned in the Istream Stats.

И если по теме, то как мне это можно использовать? smile
Заранее благодарен за Вашу помощь.
PM MAIL   Вверх
JohnJ2
Дата 21.4.2009, 12:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Нашёл ответ, точнее мне помогли в другом месте.
Публикую решение сюда:
Как я понял, функция Stat у TStreamAdapter неправильно определяет дату и время png-файла. Чтобы это исправить, мы её перепишем:
Код

interface

type TMyStreamAdapter = class(TStreamAdapter)
      public
       function Stat(out statstg: TStatStg; grfStatFlag: longint): HResult; override; stdcall;
     end;

implementation

function TMyStreamAdapter.Stat(out statstg: TStatStg; grfStatFlag: Longint): HResult;

 function DateTimeToFileTime(DateTime: TDateTime): TFileTime;
  const FileTimeBase = - 109205.0;
        FileTimeStep: extended = 24.0 * 60.0 * 60.0 * 1000.0 * 1000.0 * 10.0; // 10 наносекунд в день
  var E: extended;
      F64: int64;
 begin
   E := (DateTime - FileTimeBase) * FileTimeStep;
   F64 := Round(E);
   Result := TFileTime(F64);
 end;

begin
  Result := S_OK;
  try
   if (@statstg <> nil) then
    with statstg do
     begin
       FillChar(statstg, sizeof(statstg), 0);
       dwType := STGTY_STREAM;
       cbSize := Stream.Size;
       mTime := DateTimeToFileTime(now);
       cTime := DateTimeToFileTime(now);
       aTime := DateTimeToFileTime(now);
       grfLocksSupported := LOCK_WRITE;
     end;
  except
   Result := E_UNEXPECTED;
  end;
end;

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

procedure TTestGDIP.GDIPLoadImage(aStream: TStream);
var imgFile: TGPImage; 
    aptr: IStream;
begin
  aStream.Seek(0, soFromBeginning);
  aptr := TMyStreamAdapter.Create(aStream, soReference) as IStream;
  imgFile := TGPImage.Create(aptr); //создаем класс используя поток
  GDIPLoadTGPImage(imgFile);
  imgFile.Free;//уничтожаем класс изображения
end;

Что очень важно, остальные форматы картинок, которые поддерживались и ранее (jpg, bmp, gif) точно также открываются без ошибок, как и png сейчас.

Это сообщение отредактировал(а) JohnJ2 - 21.4.2009, 12:22
PM MAIL   Вверх
Alexeis
Дата 21.4.2009, 13:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


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

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



Цитата(JohnJ2 @  21.4.2009,  11:21 Найти цитируемый пост)
Как я понял, функция Stat у TStreamAdapter неправильно определяет дату и время png-файла. Чтобы это исправить, мы её перепишем:

  Она просто не может ее определить, потому что такая информация не хранится. Тут похоже косяк в самом GDI+, который неправильно анализирует полученную информацию о дате. Просто нулевые значения его не устраивают, поэтому вместо нулевых туда записали текущие. 
  Хорошо что решился вопрос. Можно было поискать обновления библиотеки GDIPlus.dll


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

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

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Звук, графика и видео"
Girder
Snowy
Alexeis

Запрещено:

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

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

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

FAQ раздела лежит здесь!


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

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


 




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


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

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