2010-08-13 3 views
8

Google은 오프라인으로 작동하는 iPhone 용 웹 응용 프로그램을 제작하고 있습니다. 그러나 우리는 동적 인 이미지를 캐싱하는데 어려움을 겪고있다. 계속해서 읽으십시오. 그러면 제가 예전에 말한 것과 정확히 지금까지 한 것을 보여 드리겠습니다.HTML5 iPhone 동적 이미지 캐싱

예를 들어 한 페이지만으로 간단한 목록 응용 프로그램을 작성한다고 가정 해 보겠습니다. 응용 프로그램의 유일한 목적은 5 개의 항목을 나열하는 것입니다. 각 항목에는 텍스트와 1 개의 이미지가 있습니다.

응용 프로그램에는 간단한 로고와 별도의 JavaScript 및 CSS 코드가 있습니다. 이러한 정적 리소스은 캐시 매니페스트 파일을 사용하여 캐시됩니다.

시나리오 1 :

은이 시나리오의가 있습니다 나는 온라인 그리고 난 사파리의 목록 응용 프로그램을로드 할 때 나는 그것을 밖으로 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 : 나는 오프라인과 나는

페이지로드 (이 매니페스트 캐시를 사용하여 정적 자원으로 캐시 되었기 때문에 로고가 표시)가 일부 자바 스크립트를 감지 웹 응용 프로그램을 엽니 다 우리는 실제로 오프라인 상태이며 결과적으로 응용 프로그램은 백엔드에 연락하지 않습니다. 대신 로컬 저장 공간에서 이전에 저장된 JSON 객체를 읽고 5 개 항목 렌더링을 시작합니다. 모두 예상대로.

텍스트가 잘 표시되지만 이번에는 이미지가 표시되지 않습니다. 그 이유는 간단합니다. 이미지 태그가 사용할 수없는 이미지 리소스를 가리키고 있습니다. 그래서 그 작은 이미지를 사용할 수없는 아이콘이 표시됩니다.


내 질문은 어떻게 든 이미지 리소스를 캐시 할 수있는 방법이 있습니까? 그래서 우리는 다음에 필요할 때마다 캐시에서 가져옵니다.

이 내가 무엇을 시도했다입니다 :

  • Base64로 이미지를 인코딩 및 JSON을 통해 공급하고 있습니다. 이것은 작동하지만 가져 오기 및 렌더링 시간이 크게 증가합니다 (약 30 초 증가, 매우 느림)
  • 일부 캐시 매니페스트 해킹/시행 착오입니다.아무것도 작동하지 않습니다 (이상적으로 도메인의 모든 리소스를 요청할 때 캐시하는 정책이 필요하지만 내 지식은 존재하지 않습니다)

해결책을 찾지 못했습니다 ... 아무도 단서가 있습니까? iPhone 용 Google Mail HTML5 애플리케이션을 보면 첨부 파일을 캐시 할 수 있고 오프라인 일 때도 가져올 수 있기 때문에 이것이 가능하다는 사실을 알고 있습니다.

Safari에서 지원하는 SQLite 데이터베이스를 사용해 본 적이 없는데 이미지를 BLOB로 저장할 수 있습니다 (여전히 피드에서 가져 와서 느린 것을 의미합니까?) 그리고 어떻게 든 마술처럼 화면에 이미지로 변환 ....하지만 난이 일을하는 방법에 대한 생각이 없습니다.

감사합니다. 감사합니다.

답변

1

픽셀 값 (0-255)의 CSV와 같은 이미지 픽셀 데이터를 가져오고/삽입 할 수있는 특정 속성을 가지고 있기 때문에 캔버스를 사용하여 이미지를 저장할 수 있는지 살펴 보는 것이 좋습니다.

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

메신저 당신이 비자 마찬가지 DB에 이미지에서 CSVV 데이터를 전송하고 할 수 있어야 할 수있는 경우 동적 캔버스에 이미지 소스를 사용하지만 수 있는지 확실하지 않습니다.

희망은 당신을 어딘가로 인도합니다.

견적

사파리 4.0 이상 캔버스의 화소의 직접 조작을 지원한다. getImageData() 함수를 사용하여 캔버스의 원시 픽셀 데이터를 가져올 수 있으며 createImageData() 함수를 사용하여 조작 된 픽셀에 대한 새 버퍼를 만들 수 있습니다.


업데이트 :. 나는이 당신은 또한에 관심이있을 수 있습니다 링크 발견

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

http://wecreategames.com/blog/?p=219 // 또한 캔버스 직렬화 :

+0

감사합니다 - 당신은 내가 그 일을 생각하지 않았다가 좋은 지적을합니다. 나는 캔버스 요소에 익숙하므로 곧이 문제를 해결할 수 있어야합니다. 이제 여러 캔버스가 iPhone에서 제대로 작동하기를 바랍니다. 나중에 결과를보고하겠다. –

+0

ive 님이 내 게시물을 다른 정보와 함께 업데이트했습니다. – RobertPitt

+0

감사합니다. 두 번째 링크는 내가 원했던 것입니다 ...base64 표현을 생성하여 직렬화 된 캔버스 요소를 저장하는 것처럼 보입니다. 캐싱 된 이미지를 표시하기 위해 "data : base64"로 미리 고정 된 base64 문자열 (DB에서)을 가리키는 Image 객체를 만들고이 이미지 객체를 캔버스에 그립니다. 도움을 많이 주셔서 다시 한 번 감사드립니다. –

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

를 사용하면 로컬 스토리지 캐시를 작성할 수 있습니다.

_arrayBufferToBase64

여기에서 추출됩니다 답장을 보내 ArrayBuffer to base64 encoded string

+0

Uint8Array는 3 년 전의 주요 웹 브라우저에서는 존재하지 않았지만,보다 현대적인 웹 브라우저를위한 훌륭한 솔루션이었습니다. :) –