矢量图像如何在Xcode(即pdf文件)中工作?
矢量支持在Xcode 6中是如何工作的 当我尝试调整图像大小时,它看起来参差不齐,有什么好处?如何在Xcode(7和6.3+)中使用向量:矢量图像如何在Xcode(即pdf文件)中工作?,xcode,vector-graphics,Xcode,Vector Graphics,矢量支持在Xcode 6中是如何工作的 当我尝试调整图像大小时,它看起来参差不齐,有什么好处?如何在Xcode(7和6.3+)中使用向量: 以适当的@1x大小(例如)将图像另存为.pdf文件 在Images.xcsets文件中,创建一个新的图像集 在属性检查器中,将比例因子设置为单个向量 将pdf文件拖放到全部、通用部分 现在,您可以通过名称引用图像,就像引用任何.png文件一样 如何在旧版本的Xcode(6.0-6.2)中使用向量: 按照上述步骤进行操作,除了步骤3,将类型设置为向量
- 按照上述步骤进行操作,除了步骤3,将类型设置为向量
矢量在Xcode中的工作原理 矢量支持在Xcode中是令人困惑的,因为当大多数人想到矢量时,他们想到的是可以放大和缩小的图像,并且仍然看起来不错。然而,Xcode 6和7对于iOS并没有完全的矢量支持,所以工作方式有点不同 向量系统非常简单。它获取您的
.pdf
图像,并在构建时创建@1x.png
、@2x.png
和@3x.png
资产。(您可以通过以下方式进行验证。)
例如,假设您获得了一个44x44矢量资源foo.pdf
。在构建时,它将生成以下文件:
在44x44处foo@1x.png
在88x88处foo@2x.png
在132x132处foo@3x.png
bar.pdf
,您将得到:
在100x100处bar@1x.png
在200x200时bar@2x.png
在300x300处bar@3x.png
启示:
- 您不能为图像选择新的大小;只有保持44x44的尺寸才好看。原因是没有实现完全向量支持。这些向量所做的唯一一件事就是节省您保存图像资源的时间。如果您有一个工具(例如Photoshop脚本)已经使这成为一个一步的过程,那么使用pdf vectors您将获得的唯一好处就是经得起未来考验的支持(例如,如果在iOS 9中Apple开始需要@4x资产,那么这些就可以正常工作了),并且您需要维护的文件将更少
- 您应该以@1x大小请求所有资产,并保存为PDF文件。除其他外,这将允许UIImageView具有正确的固有内容大小
- 这使得它与以前的iOS版本向后兼容
- 在运行时调整向量大小可能是计算密集型任务;通过这种方式实现,不会对性能造成影响
- 正如在接受的答案中提到的,您无法调整图像的大小,因为Xcode在构建时仍会生成光栅化图像。如果需要调整图像大小,则应创建一个不同大小的新.pdf文件
- 如果您已经有一个页面大小错误的.svg图像,请执行以下操作:
- 更改页面大小(Inkscape>文件>文档属性)
- 选择工作空间上的所有对象(Ctrl+A),并调整其大小以适应新的页面大小。(按住Ctrl键以保持纵横比大小。)
- 要将.svg文件转换为.pdf文件,您还可以找到在线实用程序来完成这项工作。从…起这样做的好处是可以轻松设置.pdf大小
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
}
}
}
在Xcode 8中,您仍然可以添加pdf,创建新的图像集,并在属性检查器中,将比例设置为单比例选项。
对于那些仍然没有更新的用户,Xcode 9(iOS 11)中有一些变化 Cocoa Touch的新功能(WWDC 2017年第201期)(@32:55) 简而言之,资产目录现在在属性检查器中包含名为“保留向量数据”的新复选框。选中后,PDF数据将包含在已编译的二进制文件中,当然会增加其大小。但这给iOS提供了一个机会,可以在两个方向上缩放矢量数据,并提供漂亮的图像(有其自身的困难)。
对于低于11的iOS,将使用“答案向上”中描述的旧缩放机制。写得不错。这将在2014年WWDC第411次会议-“Interface Builder中的新功能”44:13讨论。注意,他们说光栅化是在构建时完成的。同样有趣的是,在MAC上,它将在运行时使用向量。在未来的某个遥远的时刻,希望iOS也会这样做。不幸的是,它没有缩放切片值。因此,如果您在5处剪切角点,则无法将2x和3x图像的角点缩放为10和15。@Jesse如果您要缩放切片值,可以自行缩放
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
}
}
}