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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Создание миниатюр в ListView, GDI+ 
V
    Опции темы
TechnoMag
Дата 18.9.2013, 11:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Создаю миниатюры функцией:
Код


procedure TImageLoader.SetSize(const imgWidth, imgHeight: integer;
  var newImgWidth, newImgHeight: integer);
var
  ratio: real;
begin
   try
     ratio:=Min(128/imgWidth, 128/imgHeight);

     newImgWidth:=round(ratio * imgWidth);
     newImgHeight:=round(ratio * imgHeight);
   except
     newImgWidth := imgWidth;
     newImgHeight := imgHeight;
   end;
end;

procedure CreateThumb;
var
 gdiGraphics: TGPGraphics;
 Img, Thumb: TGPImage;
 W, H: integer;
begin
 TempBmp:=TBitmap.Create;
 TempBmp.Width:=128;
 TempBmp.Height:=128;

 gdiGraphics:=TGPGraphics.Create();
 Img:=TGPImage.Create();

 Img:=Img.FromFile(FilePath);
 Thumb:=Img.GetThumbnailImage(0, 0, nil, nil);

 SetSize(Img.GetWidth, Img.GetHeight, W, H);
 gdiGraphics:=gdiGraphics.FromHDC(TempBmp.Canvas.Handle);
 gdiGraphics.DrawImage(Thumb,
  (TempBmp.Width div 2) - (W div 2),
  (TempBmp.Height div 2) - (H div 2),
  W,
  H);
 ThumbsListView.LargeImages.Add(TempBMP, nil);
 Img.Free;
 Thumb.Free;
 gdiGraphics.Free;
 TempBmp.Free;
end;


При добавлении в ListView на краях изображения есть белые  рамки.
user posted image
Хотелось бы так:
user posted image
Как от них избавиться?

P.S. Как улучшить качество масштабирования? StretchBlt делает более четкие картинки.

Это сообщение отредактировал(а) TechnoMag - 18.9.2013, 11:37
PM MAIL ICQ   Вверх
Illusion Dolphin
Дата 18.9.2013, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Проверьте, что у вас ImageList 32 бита и всё, что не входит в изображение - прозрачное.

Цитата

StretchBlt делает более четкие картинки.

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

Цитата

ListView 

А для чего ваше приложение? В более-менее серьёзном я бы посоветовал попробовать более функциональные контролы.

Цитата

 Img.Free;
 Thumb.Free;
 gdiGraphics.Free;
 TempBmp.Free;

try-finally не забывайте, картинки это большое количество памяти - будите тепять будет очень плохо

[sarcasm]
Цитата

   try
     ratio:=Min(128/imgWidth, 128/imgHeight);
     newImgWidth:=round(ratio * imgWidth);
     newImgHeight:=round(ratio * imgHeight);
   except
     newImgWidth := imgWidth;
     newImgHeight := imgHeight;
   end;

Шикарнейше!
[/sarcasm]


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


Шустрый
*


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

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



Цитата

Проверьте, что у вас ImageList 32 бита и всё, что не входит в изображение - прозрачное.


Наверно, помимо битности нужно что-то еще устанавливать. Не работает. Изображение "накладывается" на TBitmap с белым фоном, а TBitmap загружется в TImageList размером 128х128, и этот размер постоянный для всех изображений, т.к. задан в TImageList.
PM MAIL ICQ   Вверх
MetalFan
Дата 18.9.2013, 14:34 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



для GDI+ так же можно указать алгоритм преобразования, AFAIK (TGPGraphics - SetCompositingQuality/SetSmoothingMode).
TempBMP - Установить 32битность (PixelFormat = ps32bit), т.к. по-умолчанию, вроде бы, 24бита pfDevice.
или вообще рисовать в TGPBitmap, а его уже преобразовывать в TBitmap

Это сообщение отредактировал(а) MetalFan - 18.9.2013, 14:38


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


Шустрый
*


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

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



Цитата

для GDI+ так же можно указать алгоритм преобразования, AFAIK (TGPGraphics - SetCompositingQuality/SetSmoothingMode).


Визуально никаких изменений.

Цитата

TempBMP - Установить 32битность (PixelFormat = ps32bit), т.к. по-умолчанию, вроде бы, 24бита pfDevice.

 Никаких изменений. 

Когда делал через StretchBlt - добавлял маску, работало. А с GDI+ маска не работает.

Код

    mask := TBitmap.Create;
    mask.Width := NewWidth;
    mask.Height := NewHeight;
    mask.Mask(clWhite);
    // растягиваем
    StretchBlt(NewImage.canvas.handle,
               (NewImage.Width div 2) - (NewWidth div 2), // располагаем по центру по горизониали
               (NewImage.Height div 2) - (NewHeight div 2), // располагаем по центру по вертикали
               NewWidth, NewHeight,
               Image.canvas.handle,
               0,
               0,
               Image.width,
               Image.height,
               SRCCOPY);
    // маска для прозрачности краев
    mask.Assign(NewImage);
   ThumbsListView.LargeImages.Add(NewImage, mask); // добавляем миниатюру в список

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


Шустрый
*


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

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



Получилось!

Код

procedure CreateThumb;
var
  gdiGraphics: TGPGraphics;
  Img, Thumb: TGPImage;
  NewWidth, NewHeight: integer;
  mask: TBitmap;
begin
  gdiGraphics := TGPGraphics.Create;
  Img := TGPImage.Create;
  TempBmp := TBitmap.Create;
  TempBMP.PixelFormat := pf32Bit;
  TempBmp.Width := 128;
  TempBmp.Height := 128;
  TempBMP.Canvas.Brush.Color := clWhite;
  TempBMP.Canvas.FillRect(RECT(0, 0, 128, 128));
  // маска для отсечения белых рамок
  mask := TBitmap.Create;
  mask.Width := 128;
  mask.Height := 128;
  mask.PixelFormat := pf32bit;
    try
      Img := Img.FromFile(FilePath);
      Thumb := Img.GetThumbnailImage(0, 0, nil, nil);
      // расчитаем размер миниатюры
      SetSize(Img.GetWidth, Img.GetHeight, NewWidth, NewHeight);
      gdiGraphics := gdiGraphics.FromHDC(TempBmp.Canvas.Handle);
      gdiGraphics.DrawImage(Thumb,
            (TempBmp.Width div 2) - (NewWidth div 2), // располагаем изображение по середине по горизонтали
            (TempBmp.Height div 2) - (NewHeight div 2), // располагаем изображение по середине по вертикали
            NewWidth,
            NewHeight);
      mask.Assign(TempBMP);
      mask.Mask(clWhite);
      ThumbsListView.LargeImages.Add(TempBMP, mask{nil}); // добавляем миниатюру в список
    finally
      Img.Free;
      Thumb.Free;
      gdiGraphics.Free;
      TempBmp.Free;
      mask.Free;
    end;
end;

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


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


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

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



кстати, так GetThumbnailImage может возвращать Thumbnail нужного размера... зачем потом еще городить огород с DrawImage?
А качество превью завист от того, какого размера превью уже есть в файле и есть ли вообще.


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


Эксперт
***


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

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



Код
   
   try
      Img := Img.FromFile(FilePath); //и вдруг не загрузилась картинка!
      Thumb := Img.GetThumbnailImage(0, 0, nil, nil);
  finally
      Img.Free;
      Thumb.Free; //и мы тогда очищаем "что-то" "где-то" и апликация крашится красиво-красиво и самое главное - внезапно



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


Шустрый
*


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

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



Цитата

//и мы тогда очищаем "что-то" "где-то" и апликация крашится красиво-красиво и самое главное - внезапно


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

Это сообщение отредактировал(а) TechnoMag - 19.9.2013, 18:40
PM MAIL ICQ   Вверх
Illusion Dolphin
Дата 19.9.2013, 19:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата

Попробую исправить эту ошибку, может поможет.

Тут наверное проблема с синхронизацией. Покажите код потока - подскажу

Это сообщение отредактировал(а) Illusion Dolphin - 19.9.2013, 19:12


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


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


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

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



Цитата(TechnoMag @  19.9.2013,  18:39 Найти цитируемый пост)
 иногда загружаются все, а иногда не все

ну так если просто вынес и из доп.потока добавляешь в ImageList с формы, то вполне понятно, что могут быть проблемы.
Я сталкивался с проблемой по отрисовке в доп.потоке, когда передавал bitmap из/в поток... в итоге перешел на передачу битмапа, сохраненного в стрим, что почти решило проблему.


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


Шустрый
*


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

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



Цитата(MetalFan @ 20.9.2013,  09:16)
Цитата(TechnoMag @  19.9.2013,  18:39 Найти цитируемый пост)
 иногда загружаются все, а иногда не все

ну так если просто вынес и из доп.потока добавляешь в ImageList с формы, то вполне понятно, что могут быть проблемы.
Я сталкивался с проблемой по отрисовке в доп.потоке, когда передавал bitmap из/в поток... в итоге перешел на передачу битмапа, сохраненного в стрим, что почти решило проблему.

Т.е. TimageList не потокобезопасен? Я в потоке добавляю в TImageList миниатюры (пробовал и синхронизированно - synchronise), а когда поток закончил работу - добавляю элементы в TListView.
PM MAIL ICQ   Вверх
MetalFan
Дата 1.10.2013, 11:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(TechnoMag @  29.9.2013,  18:53 Найти цитируемый пост)
Т.е. TimageList не потокобезопасен?

Никакие компоненты VCL непотокобезопасны. А тем более, "лежащие" на какой-либо форме приложения.


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Звук, графика и видео"
Girder
Snowy
Alexeis

Запрещено:

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

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

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

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


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

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


 




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


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

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