SVGKit:如何使用SVGKit呈现引用iOS设备照片的SVG XML String

时间:2016-10-03 22:27:56

标签: ios objective-c svg svgkit phassetslibrary

所以,我的基本问题是:

iOS上是否有办法使用SVGKit渲染包含对本地图像的引用的SVG?

血腥细节

我的应用程序需要生成和呈现SVG(NSString中的XML)。 XML将引用设备上的图像URL(在相机胶卷中)。我在iOS上使用SVGKit。我可以使用以下内容从图像PHAssets获取URL(请参阅:StackOverflow: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" width="2175px" height="1537px" viewBox="0 0 2175 1537" style="background-color:#ffffff">

<defs>
    <clipPath id="my-uuid" clipPathUnits="userSpaceOnUse">  <rect x="1062" y="-1" width="1111" height="1538"/>
    </clipPath>
</defs>

<g clip-path="url(#my-uuid)">
    <image overflow="hidden" transform="translate(1062, -64.58393285371704) rotate(0, 555, 832)" x="0" y="0" width="1111" height="1665.167865707434" 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 ,但这会返回本地图片网址的空白图片(远程网址引用工作正常)。通过&#34;空白图像&#34;,我的意思是一个非零的对象,其大小,但没有图像内容。

// 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];
}

我强烈怀疑它不喜欢设备网址引用。我知道从PHAsset获取通用URL存在问题。模拟器上的URL适用于Safari模拟器。但我在真实设备上看到的URL(看起来像#34;文件:///var/mobile/Media/DCIM/102APPLE/IMG_2405.JPG")却无法在设备的Safari上运行应用程序。我也尝试将PHAsset转换为ALAssetURL ..(参见StackOverflow:how-to-get-an-alasset-url-from-a-phasset),但这也没有用。这也会返回一个空白图像。

版本细节

  • iOS版本:10.0.2(真实设备),sim上的各种版本(8.4,9.3,10.0)
  • SVGKit版本:pod&#39; SVGKit&#39;,:git =&gt; &#39; https://github.com/SVGKit/SVGKit.git&#39;,:branch =&gt; &#39; 2.x的&#39;

1 个答案:

答案 0 :(得分:0)

SVGKit使用Apple自己的类来解析这些URL,并对它们执行 no 的其他处理。

所以...如果你得到一个nil图像,你可能打破了NSURL自己的解析功能 - c.f. Apple的文档。

但是......如果您运行Xcode调试器,在您正在使用的SVGKit SVGKSourceXXXXX类上设置断点,并在设备上运行,您应该能够轻松实时查看失败的地方和地点 - 我的猜测是NSURL ,但你可以证实这一点。