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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Создание миниатюр в ListView, работает через раз 
:(
    Опции темы
TechnoMag
Дата 14.10.2013, 17:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



При выборе папки с изображениями могут создаться все миниатюры, для все файлов, а иногда бывает, что файлы пропускаются.
Не пойму: проблема в реализации потока, или в компоненте? Пробовал на Win7 x64 и WinXp x32.
Просьба указать проблемные места в коде.
Прикрепляю файл проекта XE2.

Это сообщение отредактировал(а) TechnoMag - 14.10.2013, 17:17

Присоединённый файл ( Кол-во скачиваний: 16 )
Присоединённый файл  SimpleImageViewer.zip 94,87 Kb
PM MAIL ICQ   Вверх
Illusion Dolphin
Дата 14.10.2013, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Код

FThumbsListView.LargeImages.Clear;

Не рекомендуется в потоке вызывать

Код

        FTempBMP.Canvas.Brush.Color := clWhite;
        FTempBMP.Canvas.FillRect(RECT(0, 0, 128, 128));

Код

// растягиваем
            StretchBlt(FNewImage.canvas.handle,

Не рекомендуется пользоваться канвой в потоке




--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
TechnoMag
Дата 14.10.2013, 18:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



А как быть, если нужно, чтобы окно приложения не подвисало во время создания большого кол-ва миниатюр? С ProcessMessages в основном потоке все равно программа немного подвисает.
З.Ы. FTempBMP и FNewImage не привязаны к окну, и получается, что рисование происходит в памяти, а потом, синхронизированно, добавляются в ListView.
PM MAIL ICQ   Вверх
Illusion Dolphin
Дата 14.10.2013, 18:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата

А как быть, если нужно, чтобы окно приложения не подвисало во время создания большого кол-ва миниатюр?

OwnerData = true это раз. Ещё синхронизация - это долгий и нудный процесс, поэтому данные из потока лучше выдавать пачками, и в каждой пачке делать 
Код

  FThumbsListView.Items.BeginUpdate;
  try
    ... //добавляем пачку данных тута
  finally
    FThumbsListView.Items.EndUpdate;
  end;


Цитата

FTempBMP и FNewImage не привязаны к окну, и получается, что рисование происходит в памяти

И что? Canvas не рассчитано на многопоточность.


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
TechnoMag
Дата 23.10.2013, 19:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Эффект тот же: иногда "рисуются" "пустые" миниатюры в ListView.
Про выдачу данных пачками пока опускаем - нужно сначала понять, что мешает добавляться всем миниатюрам в список.

Код

procedure TImageLoader.AddToListView1;
var
  listItem: TListItem;
begin
  SetStretchBltMode(FNewImage.canvas.handle, 4);// мягкое растягивание
  StretchBlt(FNewImage.canvas.handle,
                          (FNewImage.Width div 2) - (NewWidth div 2), // располагаем по центру по горизониали
                           (FNewImage.Height div 2) - (NewHeight div 2), // располагаем по центру по вертикали
                           NewWidth, NewHeight,
                           Image.canvas.handle,
                           0,
                           0,
                           Image.width,
                           Image.height,
                           SRCCOPY);
  FMask.Assign(FNewImage);
  listItem := FThumbsListView.Items.Add;
  listItem.ImageIndex := FThumbsListView.LargeImages.Add(FNewImage, FMask); // добавляем миниатюру в список
  listItem.Caption := ExtractFileName(FFileName);
end;

procedure TImageLoader.AddThumb1(const FilePath: string);
var
  jpg: TJpegImage;
begin
   Image := TBitmap.Create;
   try
     jpg := TJpegImage.Create;
     try
        if ExtractFileExt(LowerCase(FilePath))='.jpg' then
        begin
            jpg.LoadFromFile(FilePath); // загружаем изображение из файла
            Image.Assign(jpg);
        end;
        if ExtractFileExt(LowerCase(FilePath))='.bmp' then
            Image.LoadFromFile(FilePath);
        // создаем миниатюру
        FNewImage := TBitmap.Create;
        try
          FNewImage.width := 128;
          FNewImage.Height := 128;
          FNewImage.pixelFormat:=pf32bit;
          //SetStretchBltMode(FNewImage.canvas.handle, 4);// мягкое растягивание
          // изменяем размер
          SetSize(Image.Width, Image.Height, NewWidth, NewHeight);
          FMask := TBitmap.Create;
          try
            FMask.Width := NewWidth;
            FMask.Height := NewHeight;
            FMask.Mask(clWhite);
            // растягиваем
            Synchronize(AddToListView1);
          finally
            FMask.Free;
          end;
        finally
          FNewImage.Free;
        end;
     finally
       Jpg.Free;
     end;
   finally
     Image.Free;
   end;
end;

PM MAIL ICQ   Вверх
Illusion Dolphin
Дата 24.10.2013, 00:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Сложно сказать наверняка, давайте я прокоментирую пару строчек, а вы потом ещё опишите, как выглядят пустые изображения (всегда пустое или если перегрузить директорию - грузится? какой цвет у изображения? не может ли быть такое что 2 потока одновременно грузят изображение в 1 лист?)
Цитата

   Image := TBitmap.Create;
   try
     jpg := TJpegImage.Create;
     try
        if ExtractFileExt(LowerCase(FilePath))='.jpg' then
        begin
            jpg.LoadFromFile(FilePath); // загружаем изображение из файла
            Image.Assign(jpg); //тут происходит лёгкая блокировка UI из-за реализации  Bitmap.Assign с критическими секциями
        end;
        if ExtractFileExt(LowerCase(FilePath))='.bmp' then
            Image.LoadFromFile(FilePath);
        //а если расширение .Bmp или .jpEg ? упс - чистая картинка будет

        // создаем миниатюру
        FNewImage := TBitmap.Create;
        try
          FNewImage.width := 128;//надо SetSize - быстрее
          FNewImage.Height := 128;
          FNewImage.pixelFormat:=pf32bit; //перед изменением размера указывайте, быстрее
          //SetStretchBltMode(FNewImage.canvas.handle, 4);// мягкое растягивание
          // изменяем размер
          SetSize(Image.Width, Image.Height, NewWidth, NewHeight);
          FMask := TBitmap.Create;
          try
            FMask.Width := NewWidth;
            FMask.Height := NewHeight;//надо SetSize - быстрее
            FMask.Mask(clWhite);//внутри странная реализация, не нравится мне оно в потоке, пробывали выносить?
            // растягиваем
            Synchronize(AddToListView1);
          finally
            FMask.Free;
          end;
        finally
          FNewImage.Free;
        end;
     finally
       Jpg.Free;
     end;
   finally
     Image.Free;
   end;
end;

Да и способ на 100% - постепенно выносить из потока в Synchronize фугкция за функцию и вы найдёте то, что ищете smile 


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
TechnoMag
Дата 24.10.2013, 12:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

Сложно сказать наверняка, давайте я прокоментирую пару строчек, а вы потом ещё опишите, как выглядят пустые изображения (всегда пустое или если перегрузить директорию - грузится? какой цвет у изображения? не может ли быть такое что 2 потока одновременно грузят изображение в 1 лист?)


Пустое изображение содержит только название файла, область, где должна быть миниатюра таким же цветом как и фон ListView.
Грузит изображения только один поток. Если перезагрузить директорию изображения могут загрузиться.

Цитата

Да и способ на 100% - постепенно выносить из потока в Synchronize фугкция за функцию и вы найдёте то, что ищете


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


PM MAIL ICQ   Вверх
MetalFan
Дата 24.10.2013, 12:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

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



странная логика - вынос в synchronize самой ресурсоемкой операции...
я бы заюзал GDI+, полностью в отдельном треде. с передачей данных в/из него в memory stream или tbytes.


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Illusion Dolphin
Дата 24.10.2013, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата

странная логика - вынос в synchronize самой ресурсоемкой операции...

Как я понимаю - это временно до выяснения причины "пробелов" в загрузке
Цитата

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

Вы зря иронизируете. Проблема в реализации внутри VCL (в котором также есть баги), которая может меняться от версии к версии как минимум и в документации нет чётких данных про thread-safe для каждого метода. Вам, наверное, ещё не приходилось удалять из большого проекта 99% кода, чтобы найти сбойный участок, который может быть ну очень неочевиден. 

P.S. У меня в подписи ссылка на сайт с программой - попробуйте установите и откройте в ней вашу папку с фотографиями. Если вам понравится, то я могу вам помочь.


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
WERITAS
Дата 21.5.2017, 11:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


********
**


Профиль
Группа: Участник
Сообщений: 582
Регистрация: 2.5.2005
Где: Москва

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



Поднимаю тему!
Столкнулся с такой же проблемой: миниатюра в потоке криво формируется. Билдил код автора и смотрел как выполняется - у меня такой же эффект. Как это победить?

Решение найдено!

Это сообщение отредактировал(а) WERITAS - 21.5.2017, 11:50


--------------------
Арт-менеджер клуба, разрешивший концерт Алексея Глызина, уволен с формулировкой "Мудак"
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Звук, графика и видео"
Girder
Snowy
Alexeis

Запрещено:

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

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

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

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


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

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


 




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


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

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