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

vqlkdk9b  于 2023-01-14  发布在  其他
关注(0)|答案(6)|浏览(283)

矢量支持在Xcode 6中是如何工作的?
当我尝试调整图像大小时,它看起来参差不齐,这是什么原因?

zour9fqk

zour9fqk1#

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

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

UIImage(named: "myImage")

如何在旧版本的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验证这一点)。
例如,假设您有一个44 x44矢量资源foo.pdf,在构建时它将生成以下文件:

  • 44 x44时foo@1x.png
  • foo@2x.png,分辨率为88 x88
  • 132 x132时的foo@3x.png

这对于任何大小的图像都是一样的。例如,如果你有bar.pdf,它是100 x100,你会得到:

  • 在100 x100处bar@1x.png
  • 在200 x200处的x1米10英寸
  • 300 x300时的bar@3x.png

含义:

*无法为图像选择新大小;只有保持44 x44的大小,它才会看起来很好。原因是未实现完全矢量支持。这些矢量所做的唯一事情是保存您保存图像资产的时间。如果您有一个工具(例如Photoshop脚本),其已经使这成为一步式过程,使用pdf vectors的唯一好处是面向未来的支持(例如,如果在iOS 9中,Apple开始需要@4x资产,这些将正常工作),而且您需要维护的文件更少
*您应要求所有资源的大小为@1x,并另存为PDF文件。除其他外,这将允许UIImageViews具有正确的固有内容大小。

为什么(可能)是这样的:

  • 这使得它向后兼容以前的iOS版本。
  • 调整向量大小在运行时可能是计算密集型任务;通过这种方式实现,不会影响性能
pengsaosao

pengsaosao2#

在Xcode 8中,您仍然可以添加pdf,创建新的图像集,并在属性检查器中设置缩放为单一缩放选项。

8xiog9wr

8xiog9wr3#

这是对@Senseful的精彩回答的补充。

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

我将告诉如何在Inkscape中做到这一点,因为它是免费和开源的,但其他程序应该是类似的。

在Inkscape中:

1.创建一个新项目。
1.转到文件〉文档属性,然后将自定义页面大小设置为任何@1x大小(44 x44,100 x100等),单位为px。
1.创作你的艺术作品。
1.转到文件〉另保存为...〉可打印文档格式(*.pdf)〉保存〉确定。(或者,您可以转到打印〉打印到文件〉输出格式:PDF〉打印,但没有那么多选项。)

注:

  • 正如在已接受的答案中提到的,您不能调整图像的大小,因为Xcode在构建时仍然会生成栅格化图像。如果您需要调整图像的大小,您应该创建一个不同大小的新.pdf文件。

1.如果您已有页面大小错误的.svg图像,请执行以下操作:
1.更改页面大小(Inkscape〉文件〉文档属性)
1.选择工作空间中的所有对象(Ctrl+A),并调整它们的大小以适应新的页面大小。(按住Ctrl保持纵横尺寸。)
1.要将.svg文件转换为.pdf文件,您还可以找到在线实用程序来为您完成这项工作。Here is one example from this answer。这有一个好处,允许您轻松设置.pdf文件的大小。

进一步阅读

sq1bmfud

sq1bmfud4#

对于那些仍然没有更新的人来说,Xcode 9(iOS 11)有变化。
可可Touch的最新动态(WWDC 2017第201场会议)(@32:55)https://developer.apple.com/videos/play/wwdc2017/201/
简而言之,资产目录现在在属性检查器中包含了名为“保留矢量数据”的新复选框。选中后,PDF数据将包含在编译的二进制文件中,当然会增加其大小。但它为iOS提供了一个在两个方向上缩放矢量数据并提供漂亮图像的机会。(有其自身的困难)。对于11以下的iOS,将使用答案中描述的旧缩放机制。

x759pob2

x759pob25#

Xcode图像类型
光栅图像.png

比例因子@1x、@2x、@3x
作为一个开发人员,你有责任将.png设置为相应的因子
Official doc - Image Size and Resolution

矢量图像.pdf和.svg
**矢量PDF(可移植文档格式)**并非所有PDF文件都是矢量文件。

  • X代码6 -single scale;构建时间;PDF格式-〉PNG格式(1倍、2倍、3倍);
  • Xcode 9和iOS 11 -Preserve Vector Data;运行时间;动态缩放
    SVG(可缩放矢量图形)
  • Xcode 12和iOS〈13 - SVG -〉PNG格式(1倍、2倍、3倍)
  • Xcode 12和iOS 13 -Preserve Vector Data;运行时间;动态缩放
    差异
  • 大多数情况下,SVG比PDF小
  • SVG在文本编辑器中可读且可编辑
    实验

如果您创建一个项目并使用.pdf和.svg文件构建它(不仅针对特定设备-Any iOS device),您将看到它们以相同的方式工作

  • 生成png文件(Assets.car文件About(https://stackoverflow.com/a/61040332/4770877))
  • 选择Preserve Vector DataIndividual scales(而不是Single scale)时,结果将是动态缩放

Preserve Vector Data关闭和打开

生成的文件

d6kp6zgx

d6kp6zgx6#

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

}

相关问题