2010-08-13 72 views
8

我們正在爲脫機工作的iPhone構建Web應用程序。但是我們在緩存動態圖像方面遇到困難。請繼續閱讀,我將通過示例正確顯示我的意思以及迄今爲止所做的工作。HTML5 iPhone動態緩存圖片

例如,假設我們正在構建一個簡單的列表應用程序,只有1頁。該應用程序的唯一目的是列出5個項目,每個項目包含一些文本和1個圖像。

該應用程序有一個簡單的標誌和一些單獨的JavaScript和CSS代碼。這些靜態資源使用緩存清單文件進行緩存。

有2個場景的:

場景1:我在線上,我打開了Web應用程序

當我加載在Safari瀏覽器列表中的應用程序將獲取5個新的隨機物品出來的一個包含1000個項目的數據庫。這些都通過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對象存儲在本地存儲。

現在,這5個項目使用JavaScript注入HTML(使用CSS樣式)呈現,沒有什麼奇特的。包含指向圖像資源的文本和圖像標籤的跨度標籤被創建等。

在在線模式下,這一切都很好。

場景2:我是離線,我打開了Web應用程序

該頁面加載(顯示徽標,因爲它用的是緩存清單緩存爲靜態資源),一些JavaScript檢測我們確實處於離線狀態,因此應用程序不會嘗試聯繫後端。相反,它從本地存儲中讀取先前存儲的JSON對象,並開始渲染這5個項目。如預期的那樣。

文本顯示正常,但這次不顯示圖像,原因很簡單,圖像標記指向的圖像資源不可用。所以它顯示那個小圖片不可用的圖標。


現在我的問題是,有什麼辦法來緩存這些圖像資源?所以下次我們需要它們時,它們將從緩存中獲取。

這是我已經試過:

  • Base64編碼的圖像,並通過JSON提供給他們。這工作,但它大大增加了提取和渲染時間(我們正在談論增加30秒,非常緩慢)
  • 某些緩存清單黑客入侵/試驗和錯誤..找不到任何工作(理想情況下需要,它的緩存域的所有資源,因爲他們被要求「政策,但是據我所知,這並不存在)

我從字面上花在這個時間和可找不到解決方案......有人有線索嗎?我知道這是可能的,因爲如果您查看iPhone的Google Mail HTML5應用程序,他們可以以某種方式緩存附件,即使在離線狀態下也可以檢索它們。

我們還沒有嘗試過的一件事是使用Safari支持的SQLite數據庫...也許我可以將圖像作爲BLOB存儲(仍然意味着從提要中獲取並因此緩慢?),然後以某種方式神奇地轉換成屏幕上的圖像....但我不知道如何做到這一點。

任何幫助表示讚賞,謝謝。

回答

1

我建議你看看是否可以使用畫布來保存圖像,因爲它們具有獲取/插入圖像像素數據的某些屬性,例如像素值的CSV(0-255)。

來源:http://developer.apple.com/safari/library/documentation/appleapplications/conceptual/SafariJSProgTopics/Tasks/Canvas.html

林不知道,如果你可以使用動態圖像源成畫布,但如果你能,你應該能夠從圖像傳輸CSVV數據到一個數據庫,反之亦然。

希望能帶你到某個地方。

報價

的Safari 4.0及更高版本支持畫布像素的直接操作。您可以使用getImageData()函數獲取畫布的原始像素數據,並使用createImageData()函數爲操作像素創建新的緩衝區。


更新:

我發現這個鏈接,您還可能有興趣在

http://wecreategames.com/blog/?p=210

http://wecreategames.com/blog/?p=219 //還要注意用帆布系列化:)

+0

感謝您的答覆 - 你做的很對我沒想到這樣做。我對畫布元素很熟悉,所以我應該能夠儘快嘗試。現在我們只希望iPhone上的多個畫布的表現可以接受。我稍後會在這裏報告結果。 – 2010-08-13 13:15:38

+0

我更新了我的文章以及其他一些關於此的信息。 – RobertPitt 2010-08-14 13:12:39

+0

謝謝,第二個鏈接正是我想要的...看起來他們通過生成一個base64表示來存儲序列化的canvas元素。爲了顯示高速緩存的圖像,他們創建一個Image對象,指向base64字符串(來自數據庫),由「data:base64」預先固定,然後將該Image對象繪製到畫布上。再次感謝您的幫助。 – 2010-08-14 15:31:06

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

有了這個TECHNIC你可以寫一個localStorage的緩存。

的_arrayBufferToBase64就是從這裏提取: ArrayBuffer to base64 encoded string

+0

Uint8Array 3年前在主流網頁瀏覽器中從未存在過,但是對於更現代化的網頁瀏覽器來說卻是不錯的解決方案:) – 2013-06-05 10:34:14