代码之家  ›  专栏  ›  技术社区  ›  Ben Lachman

图像上下文在合成UIImage时生成工件

  •  1
  • Ben Lachman  · 技术社区  · 16 年前

    我正在尝试将自定义半透明图像覆盖在基础图像上。覆盖图像是可拉伸的,创建方式如下:

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

    生成的叠加图像看起来基本正确,大小正确,alpha正确混合,等等。但是它有垂直伪影/噪波。

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

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

    我尝试先清除上下文,然后关闭PNG压缩——这减少了一些伪影(我认为完全是在非拉伸图像上)。

    有没有人知道一种方法,可以在不出现这种伪影的情况下绘制可拉伸的图像?

    2 回复  |  直到 16 年前
        1
  •  0
  •   Ben Lachman    16 年前

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

    - (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];
    }
    
        2
  •  0
  •   pms1969    16 年前

    你是否对你的原始图像过于吝啬,强迫它拉伸而不是收缩?我已经找到了最佳效果的图像,适合相同的纵横比,并减少了大小。也许不能解决你的问题。