【问题标题】:How to create a colored 1x1 UIImage on the iPhone dynamically?如何在 iPhone 上动态创建彩色 1x1 UIImage?
【发布时间】:2010-11-02 17:19:45
【问题描述】:

我想根据 UIColor 动态创建 1x1 UIImage。

我怀疑这可以通过 Quartz2d 快速完成,我正在仔细研究文档以试图掌握基本原理。但是,看起来有很多潜在的陷阱:没有正确识别每个事物的位数和字节数,没有指定正确的标志,没有释放未使用的数据等。

如何使用 Quartz 2d(或其他更简单的方法)安全地完成此操作?

【问题讨论】:

    标签: ios uiimage core-graphics quartz-graphics


    【解决方案1】:

    您可以为此使用CGContextSetFillColorWithColorCGContextFillRect

    斯威夫特

    extension UIImage {
        class func image(with color: UIColor) -> UIImage {
            let rect = CGRectMake(0.0, 0.0, 1.0, 1.0)
            UIGraphicsBeginImageContext(rect.size)
            let context = UIGraphicsGetCurrentContext()
    
            CGContextSetFillColorWithColor(context, color.CGColor)
            CGContextFillRect(context, rect)
    
            let image = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
    
            return image
        }
    }
    

    Swift3

    extension UIImage {
        class func image(with color: UIColor) -> UIImage {
            let rect = CGRect(origin: CGPoint(x: 0, y:0), size: CGSize(width: 1, height: 1))
            UIGraphicsBeginImageContext(rect.size)
            let context = UIGraphicsGetCurrentContext()!
    
            context.setFillColor(color.cgColor)
            context.fill(rect)
    
            let image = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
    
            return image!
        }
    }
    

    Objective-C

    + (UIImage *)imageWithColor:(UIColor *)color {
        CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
        UIGraphicsBeginImageContext(rect.size);
        CGContextRef context = UIGraphicsGetCurrentContext();
    
        CGContextSetFillColorWithColor(context, [color CGColor]);
        CGContextFillRect(context, rect);
    
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        return image;
    }
    

    【讨论】:

    • 不错 :-) 我建议将此方法作为类方法放入一个类别中,然后可以简单地将其添加到项目中,并使用[UIImage imageWithColor: [UIColor redColor]] 之类的行调用。
    • 如果您在循环中创建这些图像或使用更大的尺寸,优化将是仅当颜色具有 alpha 时才使用不透明画布。像这样:const CGFloat alpha = CGColorGetAlpha(color.CGColor); const BOOL opaque = alpha == 1; UIGraphicsBeginImageContextWithOptions(size, opaque, 0);
    • 请提供快速版本
    • 有没有办法让 swift 变成自定义初始化器?
    • 为什么UIGraphicsGetCurrentContext()返回nil编辑:我知道了,我将0 传递给rectwidth
    【解决方案2】:

    这是基于 Matt Stephen 的代码的另一个选项。它会创建一个可调整大小的纯色图像,以便您可以重复使用它或更改它的大小(例如,将其用作背景)。

    + (UIImage *)prefix_resizeableImageWithColor:(UIColor *)color {
        CGRect rect = CGRectMake(0.0f, 0.0f, 3.0f, 3.0f);
        UIGraphicsBeginImageContext(rect.size);
        CGContextRef context = UIGraphicsGetCurrentContext();
    
        CGContextSetFillColorWithColor(context, [color CGColor]);
        CGContextFillRect(context, rect);
    
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        image = [image resizableImageWithCapInsets:UIEdgeInsetsMake(1, 1, 1, 1)];
    
        return image;
    }
    

    将其放入 UIImage 类别并更改前缀。

    【讨论】:

      【解决方案3】:

      我多次使用马特史蒂文的答案,所以为它做了一个类别:

      @interface UIImage (mxcl)
      + (UIImage *)squareImageWithColor:(UIColor *)color dimension:(int)dimension;
      @end
      
      @implementation UIImage (mxcl)
      + (UIImage *)squareImageWithColor:(UIColor *)color dimension:(int)dimension {
          CGRect rect = CGRectMake(0, 0, dimension, dimension);
          UIGraphicsBeginImageContext(rect.size);
          CGContextRef context = UIGraphicsGetCurrentContext();
      
          CGContextSetFillColorWithColor(context, [color CGColor]);
          CGContextFillRect(context, rect);
      
          UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
          UIGraphicsEndImageContext();
      
          return image;
      }
      @end
      

      【讨论】:

        【解决方案4】:

        使用 Apple 最新的 UIGraphicsImageRenderer,代码非常小:

        import UIKit
        
        extension UIImage {
            static func from(color: UIColor) -> UIImage {
                let size = CGSize(width: 1, height: 1)
                return UIGraphicsImageRenderer(size: size).image(actions: { (context) in
                    context.cgContext.setFillColor(color.cgColor)
                    context.fill(.init(origin: .zero, size: size))
                })
            }
        }
        

        【讨论】:

          【解决方案5】:

          对我来说,Swift 中的便利 init 感觉更整洁。

          extension UIImage {
          
              convenience init?(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) {
          
                  let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
                  UIGraphicsBeginImageContext(rect.size)
                  guard let context = UIGraphicsGetCurrentContext() else {
                      return nil
                  }
          
                  context.setFillColor(color.cgColor)
                  context.fill(rect)
          
                  guard let image = context.makeImage() else {
                      return nil
                  }
                  UIGraphicsEndImageContext()
          
                  self.init(cgImage: image)
              }
          
          }
          

          【讨论】:

            【解决方案6】:

            好的,这不是您想要的,但是这段代码会画一条线。您可以对其进行调整以说明问题。或者至少从中获得一些信息。

            将图像设为 1x1 似乎有点奇怪。笔画沿着这条线行驶,因此在 0.5 处宽度为 1.0 的笔画应该可以工作。随便玩玩吧。

            - (void)drawLine{
            
            UIGraphicsBeginImageContext(CGSizeMake(320,300));
            
            CGContextRef ctx = UIGraphicsGetCurrentContext();
            
            float x = 0;
            float xEnd = 320;
            float y = 300;
            
            CGContextClearRect(ctx, CGRectMake(5, 45, 320, 300));
            
            CGContextSetGrayStrokeColor(ctx, 1.0, 1.0);
            
            CGContextSetLineWidth(ctx, 1);
            CGPoint line[2] = { CGPointMake(x,y), CGPointMake(xEnd, y) };
            
            CGContextStrokeLineSegments(ctx, line, 2);
            
            UIImage *theImage=UIGraphicsGetImageFromCurrentImageContext();
                UIGraphicsEndImageContext();
            }
            

            【讨论】:

              猜你喜欢
              • 2013-04-06
              • 2013-06-01
              • 2021-08-03
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-12-08
              相关资源
              最近更新 更多