SDWebImageSVGCoder 1.7.0

SDWebImageSVGCoder 1.7.0

DreamPiggyBogdan Poplauschi 维护。



SDWebImageSVGCoder

CI Status Version License Platform Carthage compatible

内容概览

SDWebImageSVGCoder 是 SDWebImage 框架的 SVG 编码插件,为 SVG 提供 SVG 图像加载支持。

SVG 渲染使用 Apple 的框架 CoreSVG.framework 完成(自 iOS 13/macOS 10.15 发行以来)。

SvgKit 用户注意

在 1.0.0 版本之前,这个 SVG 编码器是由第三方库 SVGKit 驱动的。它也支持 iOS 8+(macOS 10.10+)。

然而,由于该第三方库的缺乏支持,以及社区的帮助,大量的问题,版本发布的模糊性,使得我们维护变得痛苦。因此,我们决定弃用 SVGKit 支持,并将其移动到另一个仓库:SDWebImageSVGKitPlugin

使用 SVGKit 或需要支持 iOS 8+(macOS 10.10+) 的用户仍然可以使用那个 SDWebImageSVGKitPlugin。您也可以同时混合这两个 SVG 编码器。但由于 Apple 已经提供了内置框架支持,我们更愿意使用那个,这样可以减少复杂依赖、代码大小,并通过 Apple 的系统升级获得更完美化的体验。

关于 CoreSVG 框架的说明

截至目前(Xcode 11.4 且 iOS 13.4),CoreSVG.framework 仍然处于私有框架。我已经提交了反馈雷达要求公开此框架。如果您愿意,请帮助我们向苹果发送雷达并要求:[https://feedbackassistant.apple.com/](https://feedbackassistant.apple.com/)

CoreSVG.framework API 是稳定的,与 CoreGraphics 的 PDF API 保持相同的概念,因此没有理由保持私有。而我们已将使用 CoreSVG 渲染矢量图像的应用程序提交到 App Store。

此处所有 SPI 访问均使用运行时访问和早期检查,即使未来操作系统升级中断该功能,此框架也不会使您的应用程序崩溃,而只是加载失败。我将继续更新每个固件更新中的最新更改。

如果您仍然担心 SPI 的使用,可以使用 SDWebImageSVGKitPlugin。但我们可能不会对与 SVGKit 相关的任何解析器或渲染问题做出回应,因为它已经不再维护。

还有另一种解决方案:SVG-Native,Adobe 的新 W3C 标准,它是 SVG/1.1 的子集。苹果/谷歌/微软已经加入了此标准的协议,您可以尝试使用来自 SVG-native-viewer 的代码编写自己的编码器,并为矢量图像采用 SVG-native。

示例

要运行示例项目,请克隆仓库,然后首先从 Example 目录运行 pod install

您可以选择修改代码或使用其他 SVG 文件来检查兼容性。

要求

  • iOS 13+
  • tvOS 13+
  • macOS 10.15+
  • watchOS 6+

安装

CocoaPods

SDWebImageSVGCoder 可通过 CocoaPods 获得。要安装它,只需将以下行添加到您的 Podfile 中

pod 'SDWebImageSVGCoder'

Carthage

SDWebImageSVGCoder 可通过 Carthage 获得。

github "SDWebImage/SDWebImageSVGCoder"

Swift 包管理器

SDWebImageSVGCoder 可通过 Swift 包管理器 获得。

let package = Package(
    dependencies: [
        .package(url: "https://github.com/SDWebImage/SDWebImageSVGCoder.git", from: "1.4")
    ]
)

用法

将 SVG 作为矢量图像渲染

要使用 SVG 编码器,您首先应将 SDImageSVGCoder 添加到编码器管理器中。然后您可以调用视图类别方法以开始加载 SVG 图像。有关这些步骤,请参阅此处的 Wiki - 编码器使用

注意 SVG 是一种 矢量图像 格式,而 UIImageView/NSImageView 也支持矢量图像的渲染。这意味着您可以更改大小而不会丢失任何细节。

  • Objective-C
// register coder, on AppDelegate
SDImageSVGCoder *SVGCoder = [SDImageSVGCoder sharedCoder];
[[SDImageCodersManager sharedManager] addCoder:SVGCoder];
// load SVG url
UIImageView *imageView;
[imageView sd_setImageWithURL:url]
// Changing size
CGRect rect = imageView.frame;
rect.size.width = 200;
rect.size.height = 200;
imageView.frame = rect;
  • Swift
// register coder, on AppDelegate
let SVGCoder = SDImageSVGCoder.shared
SDImageCodersManager.shared.addCoder(SVGCoder)
// load SVG url
let imageView: UIImageView
imageView.sd_setImage(with: url)
// Changing size
var rect = imageView.frame
rect.size.width = 200
rect.size.height = 200
imageView.frame = rect

注意:由于 UIImageView/NSImageView 支持这种矢量渲染,这意味着该编码器插件可以与 SwiftUI 兼容。有关使用方法,请检查 SDWebImageSwiftUI

注意:对于不支持 UIKit 的 watchOS,因此不能使用矢量图像格式。这包括 SVG 和 PDF。

将 SVG 转换为位图图像

大多数情况下,首选矢量 SVG。但有时您可能想要 SVG 的位图形式,用于图像处理或 watchOS。

默认情况下使用 SVG 视图框(viewport)大小。您也可以在图像加载时使用 .imageThumbnailPixelSize 上下文选项指定所需的大小。并且可以使用 .imagePreserveAspectRatio 上下文选项指定在缩放时是否保持纵横比。

注意:当使用 imageThumbnailPixelSize 时,传递宽度或高度为 0 将移除此长度的限制。例如,给定原始尺寸为 (40,50) 的 SVG 图像

保持纵横比 宽度 高度 效果
50 50 (40,50)
0 100 (80,100)
20 0 (20,25)
0 0 (40,50)
50 50 (50,50)
0 100 (40,100)
20 0 (20,50)
0 0 (40,50)

注意:一旦传递了 imageThumbnailPixelSize,我们总是会生成位图表示。如果您希望得到矢量格式,请不要传递它,让 UIImageView 动态拉伸 SVG。

  • Objective-C
UIImageView *imageView;
CGSize bitmapSize = CGSizeMake(500, 500);
[imageView sd_setImageWithURL:url placeholderImage:nil options:0 context:@{SDWebImageContextThumbnailPixelSize: @(bitmapSize)];
  • Swift
let imageView: UIImageView
let bitmapSize = CGSize(width: 500, height: 500)
imageView.sd_setImage(with: url, placeholderImage: nil, options: [], context: [.imageThumbnailPixelSize : bitmapSize])

导出 SVG 数据

SDWebImageSVGCoder 提供了一种简单的方法,可以将由该编码器插件生成的 SVG 图像导出为原始 SVG 数据。

注意:SVG 的位图形式不支持 SVG 数据导出。

  • Objective-C
UIImage *svgImage; // UIImage with vector image, or NSImage contains `NSSVGImageRep`
if (svgImage.sd_isVector) { // This API available in SDWebImage 5.6.0
    NSData *svgData = [svgImage sd_imageDataAsFormat:SDImageFormatSVG];
}
  • Swift
let svgImage: UIImage // UIImage with vector image, or NSImage contains `NSSVGImageRep`
if svgImage.sd_isVector { // This API available in SDWebImage 5.6.0
    let svgData = svgImage.sd_imageData(as: .SVG)
}

对 CoreSVG 框架的兼容性

当存在填充颜色时,CSS opacity 无法应用

  • 示例
<path d="M399.8,68.2c77.3,3.1,160.6,32.1" opacity="0.15" fill="rgb(29,36,60)" />
  • 行为

应用崩溃。

  • 解决方案:使用 CSS rgba 设置透明度。
<path d="M399.8,68.2c77.3,3.1,160.6,32.1" fill="rgba(29,36,60,0.15)" />

向后兼容部署

本框架支持在iOS 12-/macOS 10.14-上进行回滚部署。您可以将 SDWebImageSVGCoder 和用于更高固件版本的 SDWebImageSVGKitPlugin 结合使用,为较低固件版本使用 SDWebImageSVGKitPlugin

CocoaPods用户可以在Podfile中跳过平台版本验证

platform :ios, '13.0' # This does not effect your App Target's deployment target version, just a hint for CocoaPods

请注意,您应该始终使用运行时版本检查以确保这些符号可用,您还应该使用 API_AVAILABLE 注释标记所有使用公开API的类。如下所示

if (@available(iOS 13, *)) {
    [SDImageCodersManager.sharedCoder addCoder:SDImageSVGCoder.sharedCoder];
} else {
    [SDImageCodersManager.sharedCoder addCoder:SDImageSVGKCoder.sharedCoder];
}

屏幕截图

这些SVG图像来自 wikimedia,您也可以尝试使用自己的SVG图像进行演示。

作者

DreamPiggy

许可

SDWebImageSVGCoder遵循MIT许可协议。更多信息请参阅LICENSE文件。