Избягвайте декомпресията на изображението, която блокира основната нишка

Имам код за показване на анимирано GIF изображение с помощта на UIImageView тук: https://github.com/amleszk/GifBlocking

Работи добре в 99% от случаите, въпреки че има проблем с определен тип GIF изображение. Пример може да се намери тук: http://i.imgur.com/mbImw.gif

Този gif получава добре 101 изображения, след което блокира основната нишка, когато дойде време за показване на UIImageView, съдържащ анимираните изображения. Добре е да декомпресирам gif, ако има компресия, но как да спра това блокиране на основната нишка?

Методите, които се извикват в главната нишка, са DGifDecompressInput DGifDecompressLine copyImageBlockSetGIF

проблемът е, че декомпресията на gif се случва, когато изгледът се добави към иерархията - което трябва да се направи в основната нишка

Благодаря


person amleszk    schedule 24.03.2013    source източник
comment
някакъв код, подобен на ... е доста неясен. Трудно е да се помогне без да се види точният код.   -  person Martin R    schedule 24.03.2013
comment
Добавено git репо за възпроизвеждане тук: github.com/amleszk/GifBlocking   -  person amleszk    schedule 24.03.2013


Отговори (3)


Кодът на grasGendarme е полезен, но имайте предвид, че UIImage е мързелив и няма да декодира изображението, докато не е наистина необходимо. Ключът е, че трябва да принудите декомпресията на фонова нишка, като използвате CGContextDrawImage. Затова използвайте UIImage+JTImageDecode.h, за да създадете версия на некомпресирано изображение на заден план, след което го задайте обратно към основната нишка.

person Jano    schedule 24.03.2013
comment
Работи добре (недостатъкът е, че изображението се изобразява два пъти?), git repo е актуализирано с пример. - person amleszk; 25.03.2013
comment
Рендиране означава генериране на изображение от форматирани данни. Тук изображението се изобразява (декомпресира) веднъж, след това се запазва в обекта UIImage и се изхвърля във видео паметта по-късно. Независимо дали го правите на две стъпки или на една, изображението ще бъде изобразено само веднъж. - person Jano; 25.03.2013
comment
Опитах това и моето предполагаемо анимирано UIimage вече не е анимирано, то само показва първия кадър - нещо друго, което пренебрегвам? - person Dom Vinyard; 28.03.2013
comment
Това няма да работи с анимирани изображения, тъй като рисува един кадър. Използвайте github.com/mayoff/uiimage-from-animated-gif, което вече извлича (и декомпресира) изображенията с CGImageSourceCreateImageAtIndex. - person Jano; 28.03.2013

Би било чудесно да видите действителния код. Без това помощта ни е ограничена.

Може би можете да поставите ред:

[self performSelectorInBackground:@selector(yourBlockingMethod:) withObject:yourObject];

Или променете библиотеката си, за да декомпресирате GIF във фонова нишка, след което използвайте setNeedsDisplay в основната нишка.

person Ilea Cristian    schedule 24.03.2013

Можете да накарате всичко да се случи в отделна нишка, като използвате Grand Central Dispatch и серийни опашки:

// create the queue that will process your data:
dispatch_queue_t dataProcessQueue = dispatch_queue_create("data process queue", NULL); // the name is there for debugging purposes
    //dispatch to the newly created queue, and do not wait for it to complete
    dispatch_async(dataProcessQueue, ^{
        // load and decode gif
        // ...
        dispatch_async(dispatch_get_main_queue(), ^{
            // put gif in place (UI work always happen on the main queue)
            // ...
    });
});
person toasted_flakes    schedule 24.03.2013