iOS借用WKWebView将svg转码为png

#import "WKSVGConvert.h"
#import <WebKit/WebKit.h>

@interface WKSVGConvert ()
<WKNavigationDelegate>

@property (nonatomic, strong) WKWebView *webView;
@property (nonatomic, copy) WKSVGConvertDataCallback waitCallback;

@end

@implementation WKSVGConvert

- (instancetype)init {
    self = [super init];
    if (self) {
        self.webView = [WKWebView new];
        self.webView.navigationDelegate = self;
    }
    return self;
}

- (void)doCallback:(NSError *)error imageDataArray:(NSArray<NSData *> *)imageDataArray {
    [self callback:self.waitCallback error:error imageDataArray:imageDataArray];
}

- (void)callback:(WKSVGConvertDataCallback)callback error:(NSError *)error imageDataArray:(NSArray<NSData *> *)imageDataArray {
    WKSVGConvertDataCallback aCallback = callback;
    if (aCallback) {
        dispatch_async(dispatch_get_main_queue(), ^{
            aCallback(error, imageDataArray);
        });
    }
}

- (void)convertSvgData2Png:(NSArray<NSData *> *)svgDataArray complete:(WKSVGConvertImageCallback)complete {
    [self convertSvgData:svgDataArray complete:complete ? ^(NSError * _Nullable error, NSArray<NSData *> * _Nonnull pictureDataArray) {
        if (error) {
            complete(error, nil);
        } else {
            NSMutableArray<UIImage *> *imageArray = [NSMutableArray array];
            for (NSData *data in pictureDataArray) {
                UIImage *image = [UIImage imageWithData:data];
                [imageArray addObject:image ?: [UIImage new]];
            }
            complete(nil, imageArray);
        }
    } : nil];
}
- (void)convertSvgData:(NSArray<NSData *> *)svgDataArray complete:(WKSVGConvertDataCallback)complete {
    WKSVGConvertDataCallback callback = self.waitCallback;
    NSString *htmlString = [self urlStringForLoadingSvgData:svgDataArray];
    self.waitCallback = complete;
    [self.webView loadHTMLString:htmlString baseURL:nil];
    [self callback:callback error:[NSError errorWithDomain:@"Canceled" code:kCFURLErrorCancelled userInfo:nil] imageDataArray:nil];
}

- (NSString *)urlStringForLoadingSvgData:(NSArray<NSData *> *)svgDataArray {
    NSMutableString *htmlString = [NSMutableString stringWithString:@" \
    <html> \
    <head> \
    </head> \
    <body>"];
    for (NSData *svgData in svgDataArray) {
        NSString *base64Svg = [svgData base64EncodedStringWithOptions:kNilOptions];
        [htmlString appendFormat:@" \
         <img src='data:image/svg+xml;base64,%@'> \
         ", base64Svg];
    }
    [htmlString appendString:@"\
     </body> \
     </html> \
    "];
    return htmlString.copy;
}

- (NSString *)javaScriptForRequestPngData {
    return @"\
           function imagePngData() { \
              var imageArray = document.getElementsByTagName('img'); \
              var pngArray = new Array(); \
              for (var index =0; index < imageArray.length; index++) { \
                  var image = imageArray[index]; \
                  var canvas = document.createElement('canvas'); \
                  canvas.width = image.width; \
                  canvas.height = image.height; \
                  var context = canvas.getContext('2d'); \
                  context.drawImage(image, 0, 0); \
                  pngArray.push(canvas.toDataURL('image/png')) \
              } \
              return pngArray; \
           } \
           imagePngData()";
}

- (void)requestSvg2PngDataByJavaScript {
    __weak typeof(self) weakSelf = self;
    [self.webView evaluateJavaScript:[self javaScriptForRequestPngData] completionHandler:^(id _Nullable result, NSError * _Nullable error) {
        __strong typeof(weakSelf) strongSelf = weakSelf;
        if (error) {
            [strongSelf doCallback:error imageDataArray:nil];
            return;
        }
        if (!result || ![result isKindOfClass:[NSArray class]]) {
            [strongSelf doCallback:[NSError errorWithDomain:@"Bad Response" code:kCFURLErrorBadServerResponse userInfo:nil] imageDataArray:nil];
            return;
        }
        NSString *pngPrefix = @"data:image/png;base64,";
        NSMutableArray<NSData *> *pngDataArray = [NSMutableArray array];
        for (NSString *pngBase64 in result) {
            if (![pngBase64 hasPrefix:pngPrefix]) {
                [pngDataArray addObject:[NSData data]];
            } else {
                NSString *base64String = [pngBase64 stringByReplacingCharactersInRange:NSMakeRange(0, pngPrefix.length) withString:@""];
                NSData *data = [[NSData alloc] initWithBase64EncodedString:base64String options:kNilOptions];
                [pngDataArray addObject:data ?: [NSData data]];
            }
        }
        [strongSelf doCallback:nil imageDataArray:pngDataArray];
    }];
}

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
    [self requestSvg2PngDataByJavaScript];
}

- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error {
    [self doCallback:error imageDataArray:nil];
}


@end

 

posted @ 2023-03-20 12:06  雨筱逸悠  阅读(65)  评论(0编辑  收藏  举报