使用PhoneGap从imageURI获取Base64。
使用PhoneGap从imageURI获取Base64。
我正在尝试从手机相册中选择的图片获取Base64编码,但是我无法使其工作:\n我尝试了以下代码:\n
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSystem) { console.log("0"); fileSystem.root.getFile(imageURI, null, function(fileEntry) { console.log("1"); fileEntry.file(function(file) { console.log("2"); var reader = new FileReader(); reader.onloadend = function(evt) { console.log("读取完成!"); image64.value = Base64.encode(evt.target.result); }; reader.readAsText(file); }, failFile); }, failFile); }, failSystem);
\n尽管图片显示正确,但我从该函数中收到了一个错误:\n
fileSystem.root.getFile(imageURI, null, function(fileEntry)
\n错误信息为:FileError.ENCODING_ERR\n我知道这段代码看起来不太好看。但我不知道如何从imageURI获取Base64编码。
问题的出现原因:cordova-plugin-file插件实现了HTML5 File API,并使用回调API。但是,作者更喜欢使用promises,所以使用了$q库对方法进行了重写。
解决方法:重写的方法名为getContentAsBase64,接收一个fileUrl参数。该方法通过调用window.resolveLocalFileSystemURL函数来解析本地文件系统的URL,如果解析成功,则调用fileResolved函数,如果解析失败,则调用fail函数。
在fileResolved函数中,如果成功解析文件路径,则通过调用fileEntry.file方法来获取文件,并将获取成功的文件传递给fileSuccess函数。
在fileSuccess函数中,通过创建一个FileReader对象,并将文件传递给它的readAsDataURL方法来读取文件内容。当读取操作完成时,会触发loadend事件,此时result属性包含以base64编码的字符串形式表示的文件数据。然后,使用deferred.resolve方法将这个base64字符串传递给promise。
最后,getContentAsBase64方法返回deferred.promise,即一个promise对象。
使用方法:使用getContentAsBase64方法来获取文件的base64编码字符串,将其赋值给imageData变量。
参考链接:[docs.angularjs.org/api/ng/service/$q](https://docs.angularjs.org/api/ng/service/$q)
问题的原因是想要从imageURI中获取Base64编码的字符串,并将其保存到sqlite中。解决方法是使用PhoneGap提供的resolveLocalFileSystemURI方法来获取文件的入口,然后使用FileReader来读取文件并进行Base64编码。
解决方法中的代码如下:
var gotFileEntry = function(fileEntry) { console.log("got image file entry: " + fileEntry.fullPath); fileEntry.file( function(file) { var reader = new FileReader(); reader.onloadend = function(evt) { console.log("Read complete!"); image64.value = Base64.encode(evt.target.result); }; reader.readAsText(file); }, failFile); }; window.resolveLocalFileSystemURI(imageURI, gotFileEntry, failSystem);
这段代码首先定义了一个回调函数gotFileEntry,该函数用于处理获取到的文件入口。在该函数中,首先打印出文件的路径,然后使用FileReader来读取文件。读取完成后,将读取到的内容进行Base64编码,并将结果赋值给image64的value属性。
需要注意的是,读取一个普通的5MPixel图片需要大约20秒的时间,然后再花费10-15秒进行Base64编码。
对于如何使用image64.value,可以参考stackoverflow上的一个问题,链接如下:
http://stackoverflow.com/questions/1207190
问题的原因是代码中使用了错误的方法来获取图片的Base64编码。解决方法是将代码中的reader.readAsText(file);
改为reader.readAsDataURL(file);
。这样可以直接从evt.target.result
中提取出图片的Base64编码。
以下是修改后的代码:
reader.readAsDataURL(file); // 移除以下代码 // image64.value = Base64.encode(evt.target.result); // 直接提取Base64编码 image64.value = evt.target.result;
通过以上修改,我们可以正确地从imageURI中获取Base64编码。