矢量支持如何在Xcode 6中工作?
当我尝试调整图像大小时,它看起来是锯齿状的,是什么给出的?
UIImage(named: "myImage")
矢量支持在Xcode中令人困惑,因为当大多数人想到矢量时,他们会想到可以向上和向下扩展并且看起来仍然很好的图像。但是,Xcode 6和7没有iOS的完全矢量支持,因此工作方式略有不同。
矢量系统非常简单。它需要你的.pdf
图像,并在构建时创建@1x.png
,@2x.png
和@3x.png
资产。 (你可以use a tool to examine the contents of Assets.car来验证这一点。)
例如,假设您获得了foo.pdf
,这是一个44x44矢量资产。在构建时,它将生成以下文件:
[email protected]
,44x44[email protected]
在88x88[email protected]
在132x132对于任何尺寸的图像,这都是相同的。例如,如果您的bar.pdf
为100x100,您将获得:
[email protected]
在100x100[email protected]
在200x200[email protected]
在300x300这是@Senseful的优秀答案的补充。
我将告诉你如何在Inkscape中这样做,因为它是免费的和开源的,但其他程序应该是类似的。
在Inkscape中:
笔记:
对于那些仍未更新的人,Xcode 9(iOS 11)有所变化。
Cocoa Touch的新变化(WWDC 2017 Session 201)(@ 32:55)https://developer.apple.com/videos/play/wwdc2017/201/
简而言之,资产目录现在包含名为“保存矢量数据”的属性检查器中的新复选框。选中后,PDF数据将包含在已编译的二进制文件中,当然会增加其大小。但它为iOS提供了在两个方向上缩放矢量数据并提供漂亮图像的机会。(有其自身的困难)。对于低于11的iOS,使用在答案中向上描述的旧缩放机制。
您可以将项目中的普通PDF文件用作矢量图像,并使用此扩展名渲染任意大小的图像。这种方式更好,因为iOS不会从PDF文件中生成.PNG图像,而且您可以渲染任意大小的图像:
extension UIImage {
static func fromPDF(filename: String, size: CGSize) -> UIImage? {
guard let path = Bundle.main.path(forResource: filename, ofType: "pdf") else { return nil }
let url = URL(fileURLWithPath: path)
guard let document = CGPDFDocument(url as CFURL) else { return nil }
guard let page = document.page(at: 1) else { return nil }
let imageRect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
if #available(iOS 10.0, *) {
let renderer = UIGraphicsImageRenderer(size: size)
let img = renderer.image { ctx in
UIColor.white.withAlphaComponent(0).set()
ctx.fill(imageRect)
ctx.cgContext.translateBy(x: 0, y: size.height)
ctx.cgContext.scaleBy(x: 1.0, y: -1.0)
ctx.cgContext.concatenate(page.getDrawingTransform(.artBox, rect: imageRect, rotate: 0, preserveAspectRatio: true))
ctx.cgContext.drawPDFPage(page);
}
return img
} else {
// Fallback on earlier versions
UIGraphicsBeginImageContextWithOptions(size, false, 2.0)
if let context = UIGraphicsGetCurrentContext() {
context.interpolationQuality = .high
context.setAllowsAntialiasing(true)
context.setShouldAntialias(true)
context.setFillColor(red: 1, green: 1, blue: 1, alpha: 0)
context.fill(imageRect)
context.saveGState()
context.translateBy(x: 0.0, y: size.height)
context.scaleBy(x: 1.0, y: -1.0)
context.concatenate(page.getDrawingTransform(.cropBox, rect: imageRect, rotate: 0, preserveAspectRatio: true))
context.drawPDFPage(page)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
return nil
}
}
}