我们正在为离线工作的iPhone构建Web应用程序。但是我们在缓存动态图像时遇到了困难。请继续阅读,我会举例说明我的意思和迄今为止我们所做的工作。
例如,假设我们正在构建一个只有1页的简单列表应用程序。该应用程序的唯一目的是列出5个项目,每个项目包含一些文本和1个图像。
该应用程序有一个简单的徽标和一些单独的JavaScript和CSS代码。使用缓存清单文件缓存这些静态资源。
有两种情况:
场景1:我在线,我打开了网络应用程序
当我在Safari中加载列表应用程序时,它将从包含1000个项目的数据库中获取5个新的随机项目。这些都是由简单的后端通过AJAX调用(JSON格式)提供的。
包含5个项目的整个JSON对象会立即存储在HTML5本地存储中并缓存以供离线使用。
JSON对象的结构有点像这样:
{
"0" : {
id: "3",
text: "Some text about item #3",
image_url: "http://www.domain.com/image22341.png"
},
"1" : {
id: "23",
text: "Some text about item #23",
image_url: "http://www.domain.com/image442321.png"
},
"2" : {
id: "4",
text: "Some text about item #4",
image_url: "http://www.domain.com/image2321.png"
},
"3" : {
id: "432",
text: "Some text about item #432",
image_url: "http://www.domain.com/image2441.png"
},
"4" : {
id: "43",
text: "Some text about item #43",
image_url: "http://www.domain.com/image221.png"
}
}
如您所见,非常简单(可能是JSON中的一些错误),整个JSON对象存储在本地存储中。
现在使用JavaScript注入HTML(使用CSS设置样式)呈现5个项目,没什么特别的。包含指向图像资源的文本和图像标记的跨度标记等。
在线模式下,一切都很有效。
场景2:我离线并打开网络应用程序
页面加载(显示徽标是因为它使用缓存清单缓存为静态资源),一些JavaScript检测到我们确实脱机,因此应用程序不会尝试联系后端。相反,它从本地存储读取先前存储的JSON对象,并开始渲染5个项目。一切如预期。
文本显示正常,但这次没有显示图像,原因很简单,图像标签指向不可用的图像资源。因此,它显示小图像不可用图标。
现在我的问题是,有没有办法以某种方式缓存这些图像资源?因此,下次我们需要它们时,它们将从缓存中获取。
这是我尝试过的:
我真的花了几个小时才找到解决方案......有没有人有线索?我知道这是可能的,因为如果您查看iPhone的Google Mail HTML5应用程序,他们可以以某种方式缓存附件,即使在离线时也可以检索它们。
我们还没有尝试过的一件事是使用Safari支持的SQLite数据库...也许我可以将图像存储为BLOB(仍然意味着从源中获取它因此慢?)然后以某种方式神奇地将其转换为屏幕上的图像....但我不知道如何做到这一点。
感谢任何帮助,谢谢。
答案 0 :(得分:2)
这是一个从AJAX下载图像并将其转换为base64字符串的代码。使用此字符串,您可以将其保存到localStorage并将其分配给离线的img的src属性。
function _arrayBufferToBase64( buffer ) {
var binary = '';
var bytes = new Uint8Array( buffer );
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode( bytes[ i ] );
}
return window.btoa( binary );
}
var xhr = new XMLHttpRequest();
xhr.open('GET', 'an_image.png', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
if (this.status == 200) {
var string_with_bas64_image = _arrayBufferToBase64(this.response);
// You can save this string to local storag or set it to an img elemment this way
document.getElementById("img").src = "data:image/png;base64," + string_with_bas64_image;
}
};
xhr.send();
您可以在此处进行测试:http://jsbin.com/ivifiy/1/edit
使用此技术,您可以编写localStorage缓存。
从这里提取_arrayBufferToBase64: ArrayBuffer to base64 encoded string
答案 1 :(得分:1)
我建议你去看看你是否可以使用画布来保存你的图像,因为它们具有获取/插入图像像素数据的某些属性,例如像素值的CSV(0-255)。 / p>
我不确定您是否可以动态地将图像源用于画布,但如果可以的话,您应该能够将CSVV数据从图像传输到数据库,反之亦然。
引用
Safari 4.0及更高版本支持直接操作画布的像素。您可以使用getImageData()函数获取画布的原始像素数据,并使用createImageData()函数为受操纵的像素创建新的缓冲区。
更新
我找到了您可能也感兴趣的链接。
http://wecreategames.com/blog/?p=210
http://wecreategames.com/blog/?p=219 //还要注意画布序列化的想法:)