用于从矢量PDF文件生成核心图形代码的工具
西根
用于从矢量PDF文件生成核心图形代码的工具
安装:
- 编译方式
swift build --product cggen --configuration release
- 将编译的二进制文件添加到路径
用法:
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)ImageInContext
k($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)