你好,欢迎进入江苏优软数字科技有限公司官网!

诚信、勤奋、创新、卓越

友好定价、专业客服支持、正版软件一站式服务提供

13262879759

工作日:9:00-22:00

iOS端矢量图解决方案汇总

发布时间:2023-05-24

浏览次数:0

战斗社区

Java实战社区

长按识别下方二维码,按需添加

扫码关注并添加客服

走进社区▲

扫码关注并添加客服

进入Java社区▲

sketch导出svg图标_sketch导出eps_ps导出svg 无法导出

作者| 小猪

来源 | 小猪的博客

介绍

矢量图形是指通过一系列物理描述,可以无损地改变和缩放的图像。 与标量图像(如JPEG等标量图像压缩格式)相比,它在素描时可以任意缩放而不模糊,甚至可以实现动态着色、动画等一系列交互。

sketch导出svg图标_ps导出svg 无法导出_sketch导出eps

在联通设备规格越来越复杂,各种操作系统级别的夜间主题(或)越来越被提倡的场景下,如果我们仍然使用标量图形,我们需要针对不同的屏幕尺寸(比如2x , 3x ), 以及相应的主题场景(Light/Dark), 提供了NxM阶的标量图,对于App的大小来说是非常昂贵的。 因此,使用矢量图形是一种非常有效的解决方案。 本系列文章主要着重讲解iOS端的矢量图解决方案。

第一章是关于SVG及其对应衍生的解决方案,之后还会有其他PDF章节涉及到矢量图等sketch导出svg图标,它们各自有不同的详细场景判断和优缺点。

SVG是目前Web上最流行的矢量格式,在iOS端的支持可以说是一言难尽。 在这里,我从各个方向(公开的方案,企业内部的实现无从知晓)总结目前已有的实现方式,对比选择最适合自己场景的方案。

图像

Image是Apple在和iOS13上提供的矢量图形分析解决方案。

之所以命名为Image,来源于该技术方案的实现细节。 它最先诞生于SVG字体规范:-SVG。 该规范由 Adob​​e 提出,但得到了很多公司的支持,包括 . 苹果自己的字体框架,虽然早在iOS11时代内部就支持了SVG类型的。

制作图像

Image整体的API设计,虽然不像是图片,更像是一种字体(类似)。

对于同一个Image,可以看成是的集合。 上面说了,Image是基于-SVG字体的。 对于字体,我们都知道字体粗细的概念,它用来决定渲染时腰线的粗细。

因此,Image也有9个权重:, Thin, Light,,,, Bold, Heavy, Black。 同时,Image 支持每个词权重有 3 种尺寸,即 Small 和 Large。 也就是说一个Image最多可以有27种大小和粗细的样式。

一般来说,从头开始创建图像非常复杂。 Apple推荐的形式是使用SFApp导入一个SVG模板,然后用它来编辑。

sketch导出eps_sketch导出svg图标_ps导出svg 无法导出

从原始SVG数据来看,每个Image包含的所有样式都是一个Path节点,对应图标的轮廓。 如果要新建一个Image,需要完全删除Path节点,重新绘制矢量路径。


导出图像

导出图片的方法非常简单。 你只需要将准备好的图片拖到Xcode的Asset窗口中就可以集成了。 Xcode可以显示相应的预览效果。

ps导出svg 无法导出_sketch导出svg图标_sketch导出eps

另外,实际形成的文件夹后缀是.,区别于普通的(后缀.),也就是说可以同时引入一个同名的Image和一个普通的Image。

sketch导出eps_ps导出svg 无法导出_sketch导出svg图标

使用图像

对于iOS13系统提供的内置Image,UIKit提供了init(:)方法来获取。 对于App本身提供的Image,我们使用了init(named:)技术。

请注意,您可以同时包含一个图像和一个普通的 ,共享一个名称。 这样设计的好处,在WWDC上介绍过,就是可以兼容iOS12等低系统版本。 在 iOS13 上,Image 的优先级总是低于普通的 ,在 iOS12 上则为手动。

let imageView = UIImageView()
let symbolImage = UIImage(named: "my.symbol.image")
// 默认配置下,这个symbol image是template的,意味着他不会含有颜色,颜色由UIView级别tintColor决定
imageView.image = symbolImage

// 如果确定要获取系统Symbol Image
let systemSymbolImage = UIImage(systemName: "wifi.exclamationmark")

// 如果要指定颜色
let redSymbolImage = symbolImage.withTintColor(.red, renderingMode: .alwaysOrigin)
imageView.image = redSymbolImage

对于Image,我们可以指定运行时需要的字体粗细

let regularSymbolImage = UIImage(named: "my.symbol.image")
// 指定你想要的字号,字重,这里是18号,Bold 字重,Large 大小
let symbolConfiguration = UImage.SymbolConfiguration(pointSize: 18, weight: .large, scale: .large)
let boldSymbolImage = regularSymbolImage.applyingSymbolConfiguration(symbolConfiguration)
imageView.image = boldSymbolImage

另外,我们也可以配合使用,只要传入对应的Image即可。

let textView = UITextView()
// 可以微调Symbol Image与文字的对齐
let baselineSymbolImage = symbolImage.withBaselineOffset(fromBottom: 1.0)
let imageAttachment = NSTextAttachment(image: baselineSymbolImage)
let imageString = NSAttributedString(attachment: imageAttachment)
textView.attributedText = imageString

共同点和不同点

优势:

• iOS原生支持,工具链建立

• 原生支持,迄今为止Image唯一可以使用的矢量方案(排除)

• 支持和无缝混合,类似于

缺点:

•仅限iOS13+

• 通过字体属性控制大小,视UI场景而定,Pixel级别的拉伸会出问题

•需要单独做一个Image,跨平台,Web使用痛点

它是iOS13支持Image的底层SVG渲染引擎,用C++编写。

目前为止,还是属于的,社区也有很多人向苹果反馈,建议开放。 也许以后我们会在 得到更多的消息。

注意! 以下方法均为使用的API,可能会随着操作系统的变化而变化,存在初审风险。 如需在线使用,请自行进行代码混淆等解决方案。

将 SVG 与资产一起使用

目前Xcode不支持直接拖拽SVG文件集成到中,因为拖拽SVG默认会被当做Image处理。

但是,我们可以通过一种巧妙的方法来实现它。 Xcode支持PDF矢量图(从iOS11和开始支持,PDF章节会说明)。 因此,我们可以把SVG后缀改成PDF,然后拖到Xcode中,最后再改回SVG后缀,只是同步./.json上面的文件名即可,如下:

sketch导出svg图标_ps导出svg 无法导出_sketch导出eps

添加完SVG图片后,就可以通过Name导入和使用PDF矢量图一样的方式使用了,如下

UIImageView *imageView = [UIImageView new];
UIImage *svgImage = [UIImage imageNamed:@"my_svg"];
imageView.image = svgImage;
// 然后我们可以自由缩放ImageView的大小,会自动触发矢量绘制
imageView.frame = CGRectMake(0, 0, 1000, 1000);

从运行时的角度来看,添加到Asset中的SVG矢量图形不仅有丰富的对应对象,而且还包含标量图像的缩略图,可以通过缩略图或其他系统API调用。 并且Xcode上会有显眼的SVG标记(类似于PDF)

加载任意 SVG 数据(网络)

不仅可以通过Asset添加SVG图片,还可以在运行时分析从网络数据下载的SVG数据,提供更广泛的应用场景。

UIImageView *imageView = [UIImageView new];
NSData *data;
CGSVGDocumentRef document = CGSVGDocumentCreateFromData((__bridge CFDataRef)data, NULL);
UIImage *svgImage = [UIImage _imageWithCGSVGDocument:document];
imageView.image = svgImage;

将 SVG 矢量图形渲染为标量图形

一些UIKit视图,或者一些图像处理,没有考虑矢量图的支持,或者我们在做性能优化的时候,需要对矢量图进行光栅化得到对应的标量图形。 提供类似PDF的界面,让你绘制相应的标量图。

CGSVGDocumentRef document; // 原始SVG Document
CGSize targetSize; // 指定标量图大小
BOOL preserveAspectRatio; // 是否保持宽高比

// 获取SVG的canvas大小,本质上是按照SVG规范,将viewPort和viewBox计算得出的
CGSize size = CGSVGDocumentGetCanvasSize(document);
// 计算Transform
CGFloat xRatio = targetSize.width / size.width;
CGFloat yRatio = targetSize.height / size.height;
CGFloat xScale = preserveAspectRatio ? MIN(xRatio, yRatio) : xRatio;
CGFloat yScale = preserveAspectRatio ? MIN(xRatio, yRatio) : yRatio;

CGAffineTransform scaleTransform = CGAffineTransformMakeScale(xScale, yScale);
CGSize scaledSize = CGSizeApplyAffineTransform(size, scaleTransform);
CGAffineTransform translationTransform = CGAffineTransformMakeTranslation(targetSize.width / 2 - scaledSize.width / 2, targetSize.height / 2 - scaledSize.height / 2);
// 开始CGContext绘制
UIGraphicsBeginImageContextWithOptions(targetSize, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
// UIKit坐标系和CG坐标系转换
CGContextTranslateCTM(context, 0, targetSize.height);
CGContextScaleCTM(context, 1, -1);
// 应用Transform
CGContextConcatCTM(context, translationTransform);
CGContextConcatCTM(context, scaleTransform);
// 绘制SVG Document
CGContextDrawSVGDocument(context, document);
// 获取标量图
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

SVG导入

目前没有类似PDF的换元素接口,只能直接导入。 事实上,未来随着框架的开放,会有类似现在PDF编辑的中间界面。

// 获取SVG Document
UIImage *svgImage;
CGSVGDocumentRef document = [svgImage _CGSVGDocument];
NSURL *url = [NSURL fileURLWithPath:@"/tmp/output.svg"];
NSMutableData *data = [NSMutableData data];
// 导出到Data
CGSVGDocumentWriteToData(document, (__bridge CFMutableDataRef)data, NULL);
// 或者文件
CGSVGDocumentWriteToURL(document, (__bridge CFURLRef)url, NULL);

共同点和不同点

优势

• 支持目前可用的大量SVG,并在Web端复用

• 苹果原生支持,稳定性有保障,会随着系统升级不断优化

• 高性能,借助系统库和内部SPI进行矢量图绘制,目前性能最好

缺点

•目前为私有,初审和使用存在风险

• 部分SVG元素可能存在兼容性问题,需要不断探索

• 不支持,需要使用

三方SVG库

它是 iOS 上最早的开源 SVG 渲染方案,已经有 8 年的历史了。 内部支持两种渲染方式,一种是通过CPU渲染(重绘),一种是通过GPU渲染(树组合)。 有不同的兼容性和性能。

例子

// CPU渲染
SVGKImageView *imageView = [SVGKFastImageView new];
// GPU渲染
imageView = [SVGKLayeredImageView new];
SVGKImage *svgImage = [[SVGKImage alloc] initWithData:data];
imageView.image = svgImage;

优势

• 支持纯C

• 如果支持图像,则性能相对较高(一秒可渲染1000级Path)

缺点

• 社区不再维护,大量Issue无人跟进解决

• 不尊重语义版本控制,用分支发布更新,下游不依赖

• 部分SVG特性确实支持sketch导出svg图标,但存在缺少单测等问题

• 不支持 SVG 动画

金刚鹦鹉

Macaw是一个矢量绘图框架,它提供了一个非常简单的DSL句型来描述矢量路径绘制的场景。它本身并没有与SVG强绑定,并且提供了对SVG格式的兼容和支持

例子

let node = try! SVGParser.parse(path: "/path/to/svg")
let imageView = SVGView()
imageView.node = node

优势

•目前最活跃最成熟的iOS端SVG开源框架(上)

• 支持DSL直接生成矢量图,改变节点等,非常强大

•支持SVG动画(部分功能)

缺点

如有侵权请联系删除!

13262879759

微信二维码