【问题标题】:Cocoa Touch - Adding texture with overlay viewCocoa Touch - 使用叠加视图添加纹理
【发布时间】:2023-03-18 07:21:06
【问题描述】:

我有一组作为 UIView 的图块,它们具有可编程的背景颜色,每个图块 可以是不同的颜色。我想为每一个添加纹理,比如侧光斜角。这可以通过覆盖视图或其他方法来完成吗?

我正在寻找不需要为每种情况提供自定义图像文件的建议。

【问题讨论】:

    标签: cocoa-touch core-graphics quartz-graphics


    【解决方案1】:

    这可能对某人有所帮助,尽管这是从 SO 上的其他主题拼凑而成的。 为了创建一个具有任意颜色的斜面平铺图像,用于正常和视网膜显示,我在 Photoshop 中制作了一个斜面图像并将饱和度设置为零,制作了一个名为 tileBevel.png

    的灰度图像

    我还为视网膜显示器创建了一个 (tileBevel@2x.png)

    代码如下:

    + (UIImage*) createTileWithColor:(UIColor*)tileColor {
    
        int pixelsHigh = 44;
        int pixelsWide = 46;
        UIImage *bottomImage;
    
        if([UIScreen respondsToSelector:@selector(scale)] && [[UIScreen mainScreen] scale] == 2.0) {
            pixelsHigh *= 2;
            pixelsWide *= 2;
            bottomImage = [UIImage imageNamed:@"tileBevel@2x.png"];        
        }
        else {
            bottomImage = [UIImage imageNamed:@"tileBevel.png"];
        }
    
        CGImageRef theCGImage = NULL;
        CGContextRef tileBitmapContext = NULL;
    
        CGRect rectangle = CGRectMake(0,0,pixelsWide,pixelsHigh);
    
        UIGraphicsBeginImageContext(rectangle.size);
    
        [bottomImage drawInRect:rectangle];
    
        tileBitmapContext = UIGraphicsGetCurrentContext();
    
        CGContextSetBlendMode(tileBitmapContext, kCGBlendModeOverlay);
    
        CGContextSetFillColorWithColor(tileBitmapContext, tileColor.CGColor);        
        CGContextFillRect(tileBitmapContext, rectangle);
    
        theCGImage=CGBitmapContextCreateImage(tileBitmapContext);
    
        UIGraphicsEndImageContext();
    
        return [UIImage imageWithCGImage:theCGImage];
    
    }
    

    这会检查是否使用了视网膜显示器,调整要绘制的矩形的大小,选择适当的灰度基础图像,将混合模式设置为叠加,然后在底部图像的顶部绘制一个矩形。所有这些都是在由 BeginImageContext 和 EndImageContext 调用括起来的图形上下文中完成的。这些设置 UIImage drawRect: 方法所需的当前上下文。 Core Graphics 函数需要上下文作为参数,通过调用获取当前上下文。

    结果如下:

    【讨论】:

      【解决方案2】:

      如果要保留源图像的 alpha 通道,只需将其添加到 jim 的代码中填充 rect 之前:

      // Apply mask
      CGContextTranslateCTM(tileBitmapContext, 0, rectangle.size.height);
      CGContextScaleCTM(tileBitmapContext, 1.0f, -1.0f);
      
      CGContextClipToMask(tileBitmapContext, rectangle, bottomImage.CGImage);
      

      【讨论】:

        【解决方案3】:

        Swift 3 解决方案,基本上基于 Jim 对 Scriptease 的回答,以及一些小的改动:

        class func image(bottomImage: UIImage, topImage: UIImage, tileColor: UIColor) -> UIImage? {
            let pixelsHigh: CGFloat = bottomImage.size.height
            let pixelsWide: CGFloat = bottomImage.size.width
        
            let rectangle = CGRect.init(x: 0, y: 0, width: pixelsWide, height: pixelsHigh)
            UIGraphicsBeginImageContext(rectangle.size);
        
            bottomImage.draw(in: rectangle)
        
            if let tileBitmapContext = UIGraphicsGetCurrentContext() {
                tileBitmapContext.setBlendMode(.overlay)
                tileBitmapContext.setFillColor(tileColor.cgColor)
                tileBitmapContext.scaleBy(x: 1.0, y: -1.0)
                tileBitmapContext.clip(to: rectangle, mask: bottomImage.cgImage!)
                tileBitmapContext.fill(rectangle)
                let theCGImage = tileBitmapContext.makeImage()
                UIGraphicsEndImageContext();
        
                if let theImage = theCGImage {
                    return UIImage.init(cgImage: theImage)
                }
            }
        
            return nil
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多