矢量图像如何在Xcode中工作(即pdf文件)?

时间:2014-09-13 01:01:33

标签: xcode vector-graphics

矢量支持如何在Xcode 6中工作?

当我尝试调整图像大小时,它看起来是锯齿状的,是什么给出了?

5 个答案:

答案 0 :(得分:338)

如何在Xcode(7和6.3 +)中使用向量:

  1. 将图像保存为适当的@ 1x大小的 .pdf 文件(例如24x24 for a toolbar button)。
  2. Images.xcassets 文件中,创建一个新的图像集
  3. 属性检查器中,将比例因子设置为单个矢量
  4. 将您的pdf文件拖放到全部,通用部分。
  5. 您现在可以按名称引用图片,就像使用任何 .png 文件一样。

    UIImage(named: "myImage")
    
  6. 如何在旧版Xcode(6.0 - 6.2)中使用向量:

    • 按照上述步骤操作,步骤3除外,将类型设置为矢量

    矢量如何在Xcode中工作

    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矢量资产。在构建时间,它将生成以下文件:

    • foo@1x.png at 44x44
    • foo@2x.png at 88x88
    • foo@3x.png,电话:132x132

    对于任何尺寸的图像,这都是相同的。例如,如果您的bar.pdf为100x100,您将获得:

    • bar@1x.png,100x100
    • bar@2x.png 200x200
    • bar@3x.png at 300x300

    意义:

    • 您无法为图片选择新尺寸;如果你把它保持在44x44的大小,它只会看起来很好。原因是全矢量支持未实现。这些向量唯一能做的就是节省您保存图像资源的时间。如果你有一个工具(例如一个Photoshop脚本)已经使这个过程分为一步,那么使用pdf向量你唯一能获得的是面向未来的支持(例如,如果在iOS 9 Apple中开始需要@ 4x资产,这些只会工作),你将有更少的文件来维护
    • 您应该要求@ 1x尺寸的所有资产,保存为PDF文件。除此之外,这将允许UIImageViews具有正确的内在内容大小。

    为什么它(可能)以这种方式工作:

    • 这使得以前的iOS版本向后兼容
    • 调整大小矢量可能是运行时的计算密集型任务;通过这种方式实施,没有性能点击

答案 1 :(得分:21)

在Xcode 8中,您仍然可以添加pdf,创建新的图像集,然后在“属性”检查器中,将“缩放比例”设置为“单个比例”选项。 enter image description here

答案 2 :(得分:14)

这是对@Senseful的优秀答案的补充。

如何制作.pdf格式的矢量图像

我将告诉你如何在Inkscape中执行此操作,因为它是免费和开源的,但其他程序应该类似。

在Inkscape中:

  1. 创建一个新项目。
  2. 转到文件>文档属性并将自定义页面大小设置为@ 1x大小(44x44,100x100等),单位为px。
  3. 制作你的作品。
  4. 转到文件>另存为...>可打印文档格式(* .pdf)>保存>好。 (或者,您可以转到打印>打印到文件>输出格式:PDF>打印但没有多少选项。)
  5. 备注:

    • 如接受的答案中所述,您无法调整图像大小,因为Xcode仍会在构建时生成光栅化图像。如果您需要调整图像大小,则应创建一个不同大小的新.pdf文件。
    • 如果您的.svg图片页面大小错误,请执行以下操作:

      1. 更改页面大小(Inkscape>文件>文档属性)
      2. 选择工作区中的所有对象(Ctrl + A)并调整它们以适应新的页面大小。 (按住Ctrl键保持宽高比。)
    • 要将.svg文件转换为.pdf,您还可以找到在线实用程序来为您完成工作。来自Here is one examplethis answer。这样可以让您轻松设置.pdf大小。

    进一步阅读

答案 3 :(得分:7)

对于那些仍未更新的人,Xcode 9(iOS 11)中有变化。

Cocoa Touch的新变化(WWDC 2017 Session 201)(@ 32:55) https://developer.apple.com/videos/play/wwdc2017/201/

简而言之,资产目录现在包含名为“保存矢量数据”的属性检查器中的新复选框。选中后,PDF数据将包含在已编译的二进制文件中,当然会增加其大小。但它为iOS提供了在两个方向上缩放矢量数据并提供漂亮图像的机会。(有其自身的困难)。 对于低于11的iOS,使用了向上答案中描述的旧缩放机制。

答案 4 :(得分:1)

您可以将项目中的普通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
        }
    }

}