Извършване на скъпоструваща операция за разграждане! какво е това и как да го поправя?

Конзолата за отстраняване на грешки за моето тестово приложение Core Filters показва това съобщение:

CGImageRef 0x7a0e890 има подпълване на редове. Извършване на скъпоструваща операция за разграждане!

Не можах да намеря попадение за точно това съобщение (без информацията за показалеца) в заглавките или в търсене с Google.

Въпросите ми са (1) какво означава това и (2) как мога да поправя ситуацията?

Следното е пример за това как генерирам филтрирано UIImage с помощта на CIFilter.

- (UIImage*)sepia
{    
    CIImage *beginImage = [CIImage imageWithCGImage:[self CGImage]];
    CIContext *context = [CIContext contextWithOptions:nil];

    CIFilter *filter = [CIFilter filterWithName:@"CISepiaTone" 
                                  keysAndValues: kCIInputImageKey, beginImage, 
                        @"inputIntensity", [NSNumber numberWithFloat:0.8], nil];
    CIImage *outputImage = [filter outputImage];

    CGImageRef cgimg = 
    [context createCGImage:outputImage fromRect:[outputImage extent]];
    UIImage *newImg = [UIImage imageWithCGImage:cgimg];

    self = newImg;

    CGImageRelease(cgimg);
    return self;
}

person james_womack    schedule 17.11.2011    source източник
comment
Никога не получих верен отговор на въпроса си — ситуацията ми е специфична за iOS и предоставих кода, който причинява проблема, но не получих решение. Робин беше единственият човек, който предостави някаква помощ и не беше проявен интерес към въпроса. Бих предложил премия, но съм виждал много награди, присъдени без достатъчен отговор, така че не си струва.   -  person james_womack    schedule 24.11.2011
comment
Току-що започнахме да се сблъскваме с този проблем днес и също имаме проблеми с проследяването му.   -  person Beltalowda    schedule 12.01.2012
comment
@ThuggishNuggets — моля, уведомете ме, ако откриете нова информация   -  person james_womack    schedule 14.01.2012
comment
Поправихме това, като се уверихме, че ширината на изображението е кратна на 4, което има смисъл предвид отговора на @Robin по-долу. Моето разбиране за това как работи това е, че броят на байтовете в един ред трябва да се дели на степен 2. Това проработи в нашия случай, защото нашият пикселен формат беше RGBA8888 или 4 байта на пиксел. Като ограничихме нашата ширина да бъде кратна на 4, ние гарантирахме, че всяко увеличение от 4 пиксела в ширината на изображението добавя 16 байта към реда, което прави броя на байтовете в реда винаги делим на 16, което е 2^4 (делимо на степен от 2).   -  person Beltalowda    schedule 15.01.2012


Отговори (3)


Подпълването на байтове е допълнителни байтове, добавени в края на всеки ред на изображението, за да се гарантира, че всеки ред започва с 2^n байта, множествено в паметта. Това увеличава производителността на достъпа до паметта за сметка на размера на изображението. Можете да проверите това, ако сравните резултата от CGImageGetBytesPerRow и очакваните байтове на ред, изчислени от размерите на изображението и байтовете на пиксел.

Що се отнася до това как да коригирате премахването на подложката - трябва да намерите точно коя операция задейства разместването и да я вземете от там. Отстраняването е скъпо, защото основно цялата памет на изображението трябва да бъде разбъркана, за да се премахнат всички пропуски в края на реда.

person Robin Summerhill    schedule 17.11.2011

Бих написал коментар, но тъй като не мога да го направя поради ниската си репутация, ще го публикувам като отговор тук:

Току-що имах същата грешка и се опитах да я поправя, като използвах предложението на Thuggish Nuggets. Оказа се, че това е правилният подход, но размерът на изображението трябва да бъде множество от 8. Току-що подравних ширината към множеството от 8, не знам дали височината също трябва да бъде множество от 8, тъй като изображението I тествах този подход с беше квадратичен така или иначе.

Ето (вероятно не много ефективен) алгоритъм, за да ви даде основна представа как да изчислите необходимия размер:

UIImage *image = ...;
CGSize targetSize = image.frame.size; //e.g. 51 x 51
double aspectRatio = targetSize.width / targetSize.height;
targetSize.width = targetSize.width + 8 - ((int)targetSize.width % 8);
targetSize.height = targetSize.width / aspectRatio;
person Florian    schedule 27.06.2012

Подозирам, че „скъпата операция по разпълване“ е фалшива. Причина: Получавам го на симулатора, но не на устройството. Следователно вярвам, че това е подвеждащ артефакт на средата на симулатора.

person matt    schedule 27.04.2013
comment
Публикацията ми е създадена преди около 16 месеца (така че не знам какви са били подробностите), но усещането, което имам, казва, че е възможно да сте прав. Кое устройство, коя версия на ОС? По това време използвах iOS 5. - person james_womack; 27.04.2013