在本地HTML文件中加载图像 - UIWebView

4
我正在开发一款 iPhone 应用程序,需要打开远程 HTML 文件并使用本地图片。我找到了以下答案,它对我来说是完美的解决方案: iOS WebView remote html with local image files 但问题在于,当我尝试加载更多的图像时,这个解决方案只会加载第一张图片。
<html>
<body>
    <h1>we are loading a custom protocl</h1>
    <b>image?</b><br/>
    <img src="myapp://image1.png" />
<img src="myapp://image1.png" />
<img src="myapp://image2.png" />
<img src="myapp://image3.png" />
<body>
</html>

该页面将正确显示第一张图片,但其他图片将显示第一张图片的源。

你所发布的实现自定义协议的代码链接中,硬编码了从主包中加载“image1.png”的操作。你需要从请求URL中提取图像文件名并使用它来代替硬编码的文件名。 - XJones
@XJones 代码加载的是任意名称的第一张图片,而不仅仅是img1,这意味着该代码可以提取文件名。 - user1920678
我非常希望看到答案。 - HelmiB
3个回答

1
为什么要使用自定义协议实现在HTML文件中加载本地图片?
您可以轻松地将HTML的根目录设置为以下内容:
[webView loadHTMLString:htmlString baseURL:[[NSBundle mainBundle] bundleURL]];

这将从您的捆绑包中加载所有图像文件。
或者,您可以使用Webview委托覆盖加载调用,如下所示:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType

同时可以完全自定义文件的加载方式和位置。


0

WKWebView不允许直接从文件存储(文档目录)访问文件,要从文档目录访问文件,您必须使用loadFileURL:allowingReadAccessToURL:方法,以下是我的代码。

在ViewDidLoad中

//Get Document directory path
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsPath = [paths objectAtIndex:0]; //Get the docs directory

    //Get html from bundle and save it to document directory
    NSURL *url = [[NSBundle mainBundle] URLForResource: @"fileupload" withExtension: @"html"];
    NSData *data = [[NSData alloc] initWithContentsOfFile:[url path]];
    [data writeToFile:[documentsPath stringByAppendingPathComponent:@"fileupload.html"] atomically:YES];

    //Get image and save it to document directory
    UIImage *image = [UIImage imageNamed:@"yoga.png"];
    NSData *pngData = UIImagePNGRepresentation(image);
    filePath = [documentsPath stringByAppendingPathComponent:@"yoga.png"]; //Add the file name
    [pngData writeToFile:filePath atomically:YES]; //Write the file
    filePath = [self documentsPathForFileName:@"yoga.png"];
    NSLog(@"File path: %@", [self documentsPathForFileName:@"yoga.png"]);

    NSURL *fileurl = [NSURL fileURLWithPath:[documentsPath stringByAppendingPathComponent:@"fileupload.html"]];
    [webView loadFileURL:fileurl allowingReadAccessToURL:[NSURL fileURLWithPath:documentsPath]];

以上代码将一个图像从bundle保存到文档目录,同时它还保存了一个HTML文件(该文件将使用img标签来加载图像)。
下面是didFinishNavigation:
//Sending Path to javascript
    [webView evaluateJavaScript:[NSString stringWithFormat:@"upload('%@')", filePath] completionHandler:^(id _Nullable obj, NSError * _Nullable error) {
        NSLog(@"Java script called");
    }];

获取文件 URL 的实用方法

- (NSString *)documentsPathForFileName:(NSString *)name
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
    NSString *documentsPath = [paths objectAtIndex:0];

    NSURL *url = [NSURL fileURLWithPath:[documentsPath stringByAppendingPathComponent:name]];

    return [url absoluteString];
}

最后是包含从Webview获取路径和加载图像方法的HTML文件。
<html>
    <head><title>demo</title>
        <script>

            function upload(path)
            {
                alert(path);
                /*
                 var URI = "data:image/png;base64,"+path;
                 convertURIToImageData(URI).then(function(imageData) {
                 // Here you can use imageData
                 console.log(imageData);
                 });
                 */
                var img = document.createElement("IMG");
                img.src = path;//URI;
                img.border = 1;
                img.height = 750;
                img.width = 900;
                document.getElementById('imageDiv').appendChild(img);
            }

        function convertURIToImageData(URI) {
            return new Promise(function(resolve, reject) {
                               if (URI == null) return reject();
                               var canvas = document.createElement('canvas'),
                               context = canvas.getContext('2d'),
                               image = new Image();
                               image.addEventListener('load', function() {
                                                      canvas.width = image.width;
                                                      canvas.height = image.height;
                                                      context.drawImage(image, 0, 0, canvas.width, canvas.height);
                                                      resolve(context.getImageData(0, 0, canvas.width, canvas.height));
                                                      }, false);
                               image.src = URI;
                               });
        }
            </script>
    </head>
    <body>
        <p><h1>This is a Demo !!!</h1></p>
        <div id="imageDiv"></div>
    </body>
</html>

上述方法是我找到的从文档目录加载图像/文件的唯一方法。

您还可以将图像/文件以数据URL的形式发送,并将其传递给javascript方法(已在html文件中编写),只需将图像转换为NSData并进行基本编码即可,javascript将自行将数据URL转换为图像对象。

UIImage转数据URL转换:

UIImage *img = [UIImage imageNamed:@"yoga.png"];
NSData *data = UIImageJPEGRepresentation(img, 0.90);
data = [data base64EncodedDataWithOptions:0];
NSString *dataurl = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

干杯!!!


0

你可以使用相同的思路在iOS WebView远程HTML与本地图像文件中,但是为每个图像使用不同的自定义协议名称。例如

<html>
<body>
    <h1>we are loading a custom protocl</h1>
    <b>image?</b><br/>
    <img src="myapp://image1.png" />
<img src="myapp1://image1.png" />
<img src="myapp2://image2.png" />
<img src="myapp3://image3.png" />
<body>
</html>

然后询问在canInitWithRequest方法中使用了哪个协议名称,然后您就可以知道要在startLoading方法中加载哪个图像。

注意:由于canInitWithRequest是一个类方法,因此您可以声明一个静态变量来保存canInitWithRequest方法中的图像文件名。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接