SDWebImageSVGCoder
内容概览
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文件。