图像上下文在合成UIImages时产生伪像

问题描述:

我正试图在基本图像上覆盖自定义半透明图像。覆盖图像是可拉伸的和这样创建的:图像上下文在合成UIImages时产生伪像

[[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看起来大多正确,它是正确的大小,alpha是正确混合等,但它有垂直的人为因素/噪音。

UIImage artifacts example http://acaciatreesoftware.com/img/UIImage-artifacts.png

(例如在http://acaciatreesoftware.com/img/UIImage-artifacts.png

我试图首先清除上下文,然后关闭PNG压缩 - 这减少了伪像一些(完全在非拉伸的图像我想)。

有没有人知道一种方法绘制可伸缩的UIImages出这种artifacting发生?

+1

'-stretchableImage ...'将整数作为输入。通过'5'而不是'5.0'(它不会解决问题)。 – kennytm 2010-02-20 08:39:22

+0

谢谢。我有点惊讶g​​cc并没有抱怨。我很习惯图形尺寸浮动,我甚至没有注意到它不是。 – 2010-02-20 08:50:01

+1

C的自动类型降级使得5.0是一个合法且有效的int参数。因此,类型检查不会导致警告。但我很惊讶地发现gcc似乎没有提供降级警告。 – danielpunkass 2010-02-20 13:52:53

所以答案是:不要这样做。相反,您可以在程序上绘制覆盖图。像这样:

- (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]; 
} 

你是不是太吝啬你的原始图像,并迫使它伸展而不是缩小?我已经找到了适合相同宽高比并缩小尺寸的最佳效果。可能无法解决你的问题。

+0

有趣。我会试一试。 – 2010-02-26 06:55:00