SVGKit:如何使用 SVGKit 渲染引用 iOS 设备照片的 SVG XML 字符串
Posted
技术标签:
【中文标题】SVGKit:如何使用 SVGKit 渲染引用 iOS 设备照片的 SVG XML 字符串【英文标题】:SVGKit: How do i render an SVG XML String that references a iOS device photo using SVGKit 【发布时间】:2016-10-03 22:27:56 【问题描述】:所以,我的基本问题是:
ios 上有没有办法使用 SVGKit 来呈现包含对本地图像的引用的 SVG?血腥细节
我的应用程序需要生成和渲染 SVG(NSString 中的 XML)。 XML 将引用设备上的图像 URL(在相机胶卷中)。我在 iOS 上使用SVGKit。我可以使用以下方法从图像 PHAsset 中获取 URL(参见:***:nsurl-from-phasset):
+ (void) getUrlFromPHAsset:(PHAsset *)asset
completionHandler:(void (^)(NSURL *url)) handler
PHImageRequestOptions *imgOptions = [PHImageRequestOptions new];
PHContentEditingInputRequestOptions *options =
[PHContentEditingInputRequestOptions new];
imgOptions.version = PHImageRequestOptionsVersionCurrent;
[asset requestContentEditingInputWithOptions:options
completionHandler:^(PHContentEditingInput * _Nullable contentEditingInput, NSDictionary * _Nonnull info)
handler(contentEditingInput.fullSizeImageURL);
];
然后我在生成的 SVG XML 字符串中使用该图像 URL(这个是在模拟器中生成的):
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 2175 1537" style="background-color:#ffffff">
<defs>
<clipPath id="my-uuid" clipPathUnits="userSpaceOnUse"> <rect x="1062" y="-1" />
</clipPath>
</defs>
<g clip-path="url(#my-uuid)">
<image overflow="hidden" transform="translate(1062, -64.58393285371704) rotate(0, 555, 832)" x="0" y="0" xlink:href="file:///Users/joe/Library/Developer/CoreSimulator/Devices/E8B8D888-93EC-4152-B0AD-B82D0C1B2FFE/data/Media/DCIM/100APPLE/IMG_0003.JPG"></image>
</g>
</svg>
我尝试过的
我尝试使用 SVGKSourceString 创建一个 SVGKImage,但这会为本地图像 URL 返回一个空白图像(远程 URL 引用工作正常)。 “空白图像”是指具有大小但没有图像内容的非零对象。
// DOESNT WORK on Simulator or real device
+ (SVGKImage *) svgImageFromString:(NSString *)text
SVGKSource *source = [SVGKSourceString sourceFromContentsOfString:svgText];
SVGKImage *img = [SVGKImage imageWithSource:source]; // returns a blank image
我在模拟器上注意到,如果我从设备上的文件中读取 SVG 内容,它就可以工作。我觉得这很奇怪,但是,无论如何。当它从文件中读取 SVG 内容时,它必须以不同的方式处理 URL 引用。因此,我将 NSString 转换为 NSInputStream,然后使用 SVGSourceLocalFile.initWithInputStream: 创建 SVGKSourceLocalFile,它也在模拟器上运行。渲染的 SVG 中引用的本地图像。 (注意:我必须使用假文件名设置 filePath 以防止 imageWithSource 爆炸。)
但是,遗憾的是,这在真实设备上不起作用。 SVGKImage imageSource:返回一个空白图像。
// WORKS ON THE SIMULATOR, not on a real device
+ (SVGKImage *) svgImageFromString:(NSString *)text
NSData *svgData = [text dataUsingEncoding:NSUTF8StringEncoding];
NSInputStream *inp = [NSInputStream inputStreamWithData:svgData];
SVGKSourceLocalFile *fsource = [[SVGKSourceLocalFile alloc] initWithInputSteam:inp];
// hack: set filePath to prevent SVGKit from barfing
fsource.filePath = @"foo.bar";
return [SVGKImage imageWithSource:fsource];
我强烈怀疑它不喜欢设备 URL 引用。我知道从 PHAsset 获取通用 URL 存在问题。模拟器上的 URL 在 Safari 模拟器中有效。但是我在真实设备上返回的 URL(看起来像“file:///var/mobile/Media/DCIM/102APPLE/IMG_2405.JPG”)在设备的 Safari 应用程序上不起作用。我还尝试将 PHAsset 转换为 ALAssetURL..(请参阅 ***:how-to-get-an-alasset-url-from-a-phasset ),但这也不起作用。这也会返回一个空白图像。
版本详情
iOS 版本:10.0.2(真机),sim 上的各种版本(8.4、9.3、10.0) SVGKit 版本:pod 'SVGKit', :git => 'https://github.com/SVGKit/SVGKit.git', :branch => '2.x'【问题讨论】:
【参考方案1】:SVGKit 使用 Apple 自己的类来解析这些 URL,并且没有对它们进行额外处理。
所以......如果你得到一个 nil 图像,你可能破坏了 NSURL 自己的解析能力 - c.f. Apple 的文档。
但是...如果您运行 Xcode 调试器,在您正在使用的 SVGKit SVGKSourceXXXXX 类上设置断点,然后在设备上运行,您应该能够轻松地实时查看失败的原因和位置 - 我猜是 NSURL ,但您可以确认这一点。
【讨论】:
以上是关于SVGKit:如何使用 SVGKit 渲染引用 iOS 设备照片的 SVG XML 字符串的主要内容,如果未能解决你的问题,请参考以下文章
[react] 如何解决引用类型在pureComponent下修改值的时候,页面不渲染的问题?
引导 React 渲染器:如何在应用启动时获取对根视图的引用?
[react] 如何解决引用类型在pureComponent下修改值的时候,页面不渲染的问题?