Невозможно кэшировать данные изображения с холста

Итак, у меня есть функция, которая преобразует изображение в оттенки серого. Он принимает URL-адрес исходного изображения и выходной холст для вывода. Функция работает очень быстро в большинстве браузеров, но очень медленно в мобильных браузерах (~3-4 секунды для изображения 700x700). По этой причине я хочу кэшировать (на клиенте) данные изображения в градациях серого, а затем, когда запрос на изображение поступает несколько раз, я хочу обслуживать кэшированные данные в градациях серого и не пересчитывать их.

Я сделал тест на jsfiddle. Вот он: http://jsfiddle.net/RCkDX/4/ На тестовой странице я показываю исходное изображение вверху, я вывожу холст, который используется для выполнения вычислений внизу, и два холста посередине, они должны выводить то же, что и нижнее изображение (за исключением кэшированных данных).

На данный момент я получаю «Uncaught TypeError: Type error», я думаю, это потому, что ему не нравятся данные кеша, я пытался перемещать вещи, пробуя разные методы, но безуспешно.

Важно, чтобы я не использовал dataurls для кэширования, так как мобильный браузер Android, который я использую, в данный момент будет отображать маленький синий значок вопросительного знака (неправильные данные на холсте), поэтому любой вариант без dataurls будет работать.


person Josh Mc    schedule 29.05.2012    source источник
comment
Вы уверены, что потеря скорости на мобильных устройствах происходит из-за того, что функция преобразования оттенков серого работает медленно. Может быть, вы потеряли скорость из-за того, что скорость мобильного подключения может быть ниже, чем у настольного?   -  person Andrew D.    schedule 29.05.2012
comment
Это определенно не скорость загрузки изображений, поскольку у меня даже есть изображения, кэшированные с использованием заголовка Expires на стороне сервера.   -  person Josh Mc    schedule 29.05.2012
comment
См. обновленный код: jsfiddle.net/RCkDX/5 Возможно, это поможет вам.   -  person Andrew D.    schedule 29.05.2012
comment
Потрясающе! Большое спасибо! Опубликуйте это как ответ, и я соглашусь. Для меня не очевидно, в чем разница, которая заставляет эту работу работать, не могли бы вы указать на это? Также я вижу, что в вашей версии нет тайм-аутов, причина, по которой я это сделал, заключается в том, чтобы пользовательский интерфейс не зависал во время обработки, это таймеры, которые мешают работе моего исходного кода?   -  person Josh Mc    schedule 30.05.2012


Ответы (1)


@jezternz, я думаю, что 'Uncaught TypeError: Type error' в вашем коде происходит потому, что readyCanvas функция вызывается из returnFunc каждый раз (без разницы, есть кеш или нет); а внутри readyCanvas grayscaleCache[src] может вернуть undefined, если кэша нет. В моем примере кода (jsfiddle.net/RCkDX/5) readyCanvas вызывается из returnFunc, только если grayscaleCache [src] определяется (кеш создается и сохраняется). Из моего кода удалено setTimeout. Основная причина: для упрощения примера.

Если вам нужно создать код без страницы блокировки (без блокировки пользовательского интерфейса), вы должны предоставить более сложный код для управления кешем. Например:

  • grayscaleCache[src] имеет значение undefined, что означает "нет кеша и кеш не строится по какому-либо предыдущему запросу" - вам нужно запустить процедуру кеширования ;
  • grayscaleCache[src] равно null, что означает "кэш создается по предыдущему запросу" - вам не нужно запускать процедуру кэширования, вы должны ждать (проверить с помощью setTimeout), когда кеш будет готов;
  • grayscaleCache[src] не undefined и не null«кэш готов» — использовать кеш.
person Andrew D.    schedule 30.05.2012