用于从矢量PDF文件生成核心图形代码的工具

西根

用于从矢量PDF文件生成核心图形代码的工具

安装:

  1. 编译方式swift build --product cggen --configuration release
  2. 将编译的二进制文件添加到路径

用法:

cggen [--objc-header OBJC_HEADER] [--objc-impl OBJC_IMPL]
      [--objc-header-import-path OBJC_HEADER_IMPORT_PATH]
      [--objc-prefix OBJC_PREFIX]
      [-h] [--verbose]
      pdfs

positional arguments:
  pdfs                  pdf files to process


optional arguments:
  -h, --help            show help message and exit
  --verbose             print some debug info to stdout
  --objc-header OBJC_HEADER
                        Path to file where objc header will be generated,
                        intermediate dirs should exist
  --objc-impl OBJC_IMPL
                        Path to file where objc implementanion will be generated,
                        intermediate dirs should exist
  --objc-header-import-path OBJC_HEADER_IMPORT_PATH
                        Objc implementation file should import header file, so
                        this argument will be used in #import "..."
  --objc-prefix OBJC_PREFIX
                        It is usally good to prefix names of function in objc
                        code, because of global namespace. This prefix
                        will be added to every function and constant name.

生成完成后,应编译生成的实现文件 并链接到您的项目中。

您可以通过导入头文件来访问绘图功能。 函数的名称为: , 逻辑点大小:($PRFX)Draw($PDFNAME)ImageInContextk($PRFX)($PDFNAME)ImageSize

为了便于使用,请将此助手添加到您的UIImage类别中(我敢打赌您有一个🙂)

目标:

@interface UIImage (Additions)

+ (UIImage*)imageWithSize:(CGSize)size
          drawingFunction:(void(*)(CGContextRef))drawingFunction;

@end

@implementation UIImage (YBAdditions)

+ (UIImage*)imageWithSize:(CGSize)size
          drawingFunction:(void(*)(CGContextRef))drawingFunction {
  static const size_t kBitsPerComponent = 8;
  static const size_t kBytesPerRow = 0;  // Auto
  const CGFloat scale = UIScreen.mainScreen.scale;
  const CGFloat w = size.width * scale;
  const CGFloat h = size.height * scale;
  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  CGContextRef context = CGBitmapContextCreate(NULL,
                                               w,
                                               h,
                                               kBitsPerComponent,
                                               kBytesPerRow,
                                               colorSpace,
                                               kCGImageAlphaPremultipliedLast);
  CGAffineTransform transform = CGAffineTransformMakeScale(scale, scale);
  CGContextConcatCTM(context, transform);
  CGColorSpaceRelease(colorSpace);

  drawingFunction(context);

  CGImageRef imgRef = CGBitmapContextCreateImage(context);
  UIImage* img = [UIImage imageWithCGImage:imgRef
                                     scale:scale
                               orientation:UIImageOrientationUp];
  CGImageRelease(imgRef);
  CGContextRelease(context);
  return img;
}

@end

swift:

extension UIImage {
  static func makeImage(size: CGSize, function: (CGContext) -> Void) -> UIImage {
    let bitsPerComponent = 8
    let bytesPerRow = 0
    let scale = UIScreen.main.scale
    let w = size.width * scale
    let h = size.height * scale
    let colorSpace = CGColorSpaceCreateDeviceRGB()
    let context = CGContext.init(data: nil,
                                 width: Int(w),
                                 height: Int(h),
                                 bitsPerComponent: bitsPerComponent,
                                 bytesPerRow: bytesPerRow,
                                 space: colorSpace,
                                 bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)!
    function(context)
    let cgImage = context.makeImage()!
    return UIImage(cgImage: cgImage, scale: scale, orientation: .up)
  }
}

So you can use it like this:

Objc:

UIImage* img = [UIImage yb_imageWithSize:kYYIconImageSize
                         drawingFunction:YYDrawIconImageInContext];

swift:

let img = UIImage.makeImage(size: kYYIconImageSize,
                            function: YYDrawIconImageInContext)

Swift-friendly protocol-oriented way

  • Add generation arguments:

--generation-style=swift-friendly
--cggen-support-header-path=/path/to/generated/sources/cggen_support.h
--module-name=YourResourcesModule
  • Make a protocol in your code:

public protocol ImageDescriptor {
  var drawingHandler: @convention(c) (CGContext) -> Void { get }
  var size: CGSize { get }
}
  • Add an implementation:

extension ImageDescriptor {
  public var image: Image {
    return UIImage.makeImage(size: size, function: function)
  }
}
  • For each generated module, add drawing support with just one line of code:
extension YourResourcesModule.ImageDescriptor: ImageDescriptor {}
  • Now you can use generated resources in a bit more convenient way: .let icon: UIImage = YourResourcesModule.ImageDescriptor.yourIconName.image

Feel free to add some typealiases and/or extensions for the code which uses resources! Example for :UIImageView

extension UIImageView {
  func setIcon(_ icon: YourResourcesModule.ImageDescriptor)  {
    image = icon.image
  }
}

let view = UIImageView()
view.setIcon(.yourIconName)

GitHub

点击跳转