Контекст изображения создает артефакты при компоновке UIImages - PullRequest
1 голос
/ 20 февраля 2010

Я пытаюсь наложить пользовательское полупрозрачное изображение поверх базового изображения. Наложение изображения растягивается и создается так:

[[UIImage imageNamed:@"overlay.png"] stretchableImageWithLeftCapWidth:5.0 topCapHeight:5.0]

Затем я передаю это методу, который накладывает его на фоновое изображение кнопки:

- (void)overlayImage:(UIImage *)overlay forState:(UIControlState)state {
    UIImage *baseImage = [self backgroundImageForState:state];      

    CGRect frame = CGRectZero;
    frame.size = baseImage.size;

    // create a new image context
    UIGraphicsBeginImageContext(baseImage.size);        

    // get context
    CGContextRef context = UIGraphicsGetCurrentContext();   

    // clear context
    CGContextClearRect(context, frame);

    // draw images
    [baseImage drawInRect:frame];   
    [overlay drawInRect:frame];// blendMode:kCGBlendModeNormal alpha:1.0];

    // get UIImage
    UIImage *overlaidImage = UIGraphicsGetImageFromCurrentImageContext();

    // clean up context
    UIGraphicsEndImageContext();

    [self setBackgroundImage:overlaidImage forState:state];
}

Результирующий overlaidImage выглядит в основном правильно, это правильный размер, альфа-канал смешан правильно и т. Д., Однако он имеет вертикальные артефакты / шум.

Пример артефактов UIImage http://acaciatreesoftware.com/img/UIImage-artifacts.png

(пример на http://acaciatreesoftware.com/img/UIImage-artifacts.png)

Я попытался сначала очистить контекст, а затем отключить сжатие PNG - что уменьшает некоторые артефакты (я думаю, что они не растянуты).

Кто-нибудь знает метод рисования растягиваемых UIImages без такого рода артефактов?

Ответы [ 2 ]

0 голосов
/ 25 февраля 2010

Вы слишком скупы на исходное изображение и заставляете его растягиваться, а не сжиматься? Я нашел лучшие результаты для изображений, которые соответствуют одинаковому соотношению сторон и были уменьшены в размере. Может не решить твою проблему.

0 голосов
/ 24 февраля 2010

Так что ответ таков: не делай этого. Вместо этого вы можете нарисовать наложение процедурно. Вот так:

- (void)overlayWithColor:(UIColor *)overlayColor forState:(UIControlState)state {
    UIImage *baseImage = [self backgroundImageForState:state];      

    CGRect frame = CGRectZero;
    frame.size = baseImage.size;

    // create a new image context
    UIGraphicsBeginImageContext(baseImage.size);        

    // get context
    CGContextRef context = UIGraphicsGetCurrentContext();   

    // draw background image
    [baseImage drawInRect:frame];   

    // overlay color
    CGContextSetFillColorWithColor(context, [overlayColor CGColor]);
    CGContextSetBlendMode(context, kCGBlendModeSourceAtop);
    CGContextFillRect(context, frame);

    // get UIImage
    UIImage *overlaidImage = UIGraphicsGetImageFromCurrentImageContext();

    // clean up context
    UIGraphicsEndImageContext();

    [self setBackgroundImage:overlaidImage forState:state];
}
...