【问题标题】:How to store and retrieve image to localStorage?如何将图像存储和检索到localStorage?
【发布时间】:2013-09-26 00:31:31
【问题描述】:

以为我有这个,但没有。目标:拍一张照片(保险卡),将其保存在本地,稍后再检索。

// Get a reference to the image element
var elephant = document.getElementById("SnapIt_mobileimage_5");

var imgCanvas = document.createElement("canvas"),
imgContext = imgCanvas.getContext("2d");

// Make sure canvas is as big as the picture
imgCanvas.width = elephant.width;
imgCanvas.height = elephant.height;

// Draw image into canvas element

imgContext.drawImage(elephant, 0, 0, elephant.width, elephant.height );
 console.log( 'Did that' );
// Get canvas contents as a data URL
var imgAsDataURL = imgCanvas.toDataURL("data:image/jpg;base64,");

// Save image into localStorage
try {
localStorage.setItem("elephant", imgAsDataURL);
}
catch (e) {
console.log("Storage failed: " + e);
}; 

//Did it work?
var pic = localStorage.getItem("elephant");

console.log( elephant );
console.log( pic );

每一步成功,最终输出为:

<img id="SnapIt_mobileimage_5" class=" SnapIt_mobileimage_5" name="mobileimage_5" dsid="mobileimage_5" src="files/views/assets/image/IMG_0590.JPG">
 data:image/png;base64,iVBORw0KGgoAAAANSUhEUgA

在新页面上,当我询问时

var policy_shot = localStorage.getItem( 'elephant' );
console.log( policy_shot );

$('#TestScreen_mobileimage_1').src = policy_shot ;

它记录二进制文件:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUg ....

但是图片没有出现。

  1. 有没有更简单的方法?
  2. 为什么getItem(二进制)前面是data:image/png;而不是 data:image/jpg ?
  3. 这是它不显示的原因,还是我做错了什么?

【问题讨论】:

  • 您绘制的图像是从同一台服务器加载的还是驻留在另一台服务器上?
  • 它是用手机相机拍摄的。这是一个移动应用程序。
  • 如果您使用本地引用路径浏览器将阻止加载图像。请看我的回答。您可以通过将完整的字符串作为 url 粘贴到新选项卡中并按 Enter 来测试 data-uri。现在您可以检查是否有空图像或是否获得实际图像。

标签: javascript cordova jquery-mobile canvas html5-canvas


【解决方案1】:

1) 这是您可以在本地将图像转换为字符串的唯一方法(使用FileReader 加载的文件除外,见下文)。 (可选)您需要使用服务器来执行此操作。

2) 要获取 JPEG 图像,您需要使用如下参数:

var datauri = imgCanvas.toDataURL("image/jpeg", 0.5); //0.5 = optional quality

不要在参数中使用data:...,因为这将是无效的,它会生成默认的PNG,正如您在结果中看到的那样。 toDataURL() 只能接受一个类型,即。 image/pngimage/jpeg

3)

外部文件

如果您的图像是从不同的来源(方案、服务器...)或使用本地引用的文件(file:///my/path/ 等)加载的,CORS 会启动并阻止您创建 data-uri ,即:图像将为空(因此不可见)。

对于外部服务器,您可以通过提供crossOrigin 属性来请求跨域使用图像的权限:

<img src="http://extrernalserver/...." crossOrigin="anonymous" />

或在设置src之前通过代码(img.crossOrigin = 'anonymous';)。

但是,允许或拒绝请求取决于服务器。

如果仍然无法正常工作,您将需要通过代理加载您的图片(例如,您服务器上可以加载的页面以及外部图片并从您自己的服务器提供图片)。

或者,如果您有权访问服务器的配置,则可以添加特殊的访问允许标头(Access-Control-Allow-Origin: *,有关详细信息,请参阅下面的链接)。

CORS (Cross-Origin Resource Sharing) 是一种安全机制,只能通过这些方式解决。

本地文件

对于本地文件,您将需要使用FileReader - 这可能是一个优势,因为FileReader 带有一个方便的方法:readAsDataURL()。这使您可以直接将图像文件“上传”为数据 uri,而无需通过画布。

在此处查看示例:
https://developer.mozilla.org/en-US/docs/Web/API/FileReader

不幸的是,您不能只从代码中选择文件 - 您需要提供输入元素或拖放区,以便用户可以选择他想要存储的文件。

结论

如果所有这些步骤都完成到您确实获得了图像的程度,那么问题可能出在另一端,被截断的字符串太长而无法存储。

可以通过检查存储字符串前后的长度来验证是否被截断:

console.log(imgAsDataURL.length);
... set / get ...
console.log(pic.length);

其他可能性:

  • 图像元素未正确定义。
  • 浏览器中的一个错误
  • 框架中的一个错误

(我想我涵盖了大部分典型的陷阱?)

更新(错过了一个,有点……;-p)

OP 在框架中找到了一个特定的内容,我将在此处包含以供将来参考:

最后,问题出在$('#TestScreen_mobileimage_1').src = policy_shot ; 我正在使用 Appery.io,但他们不支持 .src

我是$('#TestScreen_mobileimage_1').attr("src", policy_shot ) ;

最后一点:localStorage 在存储图像方面非常有限。典型存储空间为 2.5 - 5 mb。存储的每个字符占用 2 个字节,存储编码为 base-64 的数据 uri 比原始数据大 33% - 因此空间将稀缺。查看 Indexed DB、Web SQL 或 File API 寻找好的替代方案。

【讨论】:

  • 谢谢!我更改了 toDataUrl 参数,它产生: data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODd 然后我添加了跨域,但仍然没有显示。 $('#TestScreen_mobileimage_1').crossOrigin = '匿名'; $('#TestScreen_mobileimage_1').src = policy_shot ;
  • 是的,将字符串粘贴到新选项卡中会生成图像。 ;-)
  • @EdJones 我使用 FileReader API 使用可能的解决方法更新了我的答案。这将使您能够直接将文件“上传”为 data-uris。缺点是用户需要通过选择文件来指定文件,因为您需要提供输入元素或拖放区才能使其工作。
  • 我希望它对用户来说非常简单;两个按钮:“拍照”和“保存照片”。
  • 长度均为 20203。?
【解决方案2】:

这里是使用 File Api 的完整解决方案

【讨论】:

    猜你喜欢
    • 2017-04-27
    • 1970-01-01
    • 2015-03-01
    • 2016-06-17
    • 2015-03-16
    相关资源
    最近更新 更多