Изменение src
От: DirectX  
Дата: 15.05.10 18:16
Оценка:
У меня возник следующий вопрос. Есть достаточно типичная задача — организация фотогалереи. Есть img, в котором нужно менять src. Так вот, возникла следующая проблема: при изменении данного свойства первые несколько раз изображение меняется, после чего исчезает. Поясню: речь идет о приложении для Windows Mobile, поэтому похоже, что заканчивается доступная память. Предыдущие src кешируются и не освобождаются. В пользу этого свидетельствует то, что на различных телефонах возможно различное количество смен свойства src. Как можно избежать расходования памяти на мобильных устройствах?
htmlayout картинки память
Re: Изменение src
От: c-smile Канада http://terrainformatica.com
Дата: 15.05.10 19:26
Оценка:
Здравствуйте, DirectX, Вы писали:

DX>У меня возник следующий вопрос. Есть достаточно типичная задача — организация фотогалереи. Есть img, в котором нужно менять src. Так вот, возникла следующая проблема: при изменении данного свойства первые несколько раз изображение меняется, после чего исчезает. Поясню: речь идет о приложении для Windows Mobile, поэтому похоже, что заканчивается доступная память. Предыдущие src кешируются и не освобождаются. В пользу этого свидетельствует то, что на различных телефонах возможно различное количество смен свойства src. Как можно избежать расходования памяти на мобильных устройствах?


1) Использовать <picture> элемент вместо <img>. <picture> не кеширует images, предазаначен именно для показа pictures.
2) Использовать <frame> и загружать в него "<html><body><img src=...></body></html>" через element::load_html() ...
Re[2]: Изменение src
От: DirectX  
Дата: 16.05.10 06:21
Оценка:
Большое спасибо за ответ!

Оба способа проверил, но пока что не получилось решить проблему

CS>1) Использовать <picture> элемент вместо <img>. <picture> не кеширует images, предазаначен именно для показа pictures.


После замены img на picture ситуация стала следующей. Если раньше на симуляторе можно было загрузить порядка 4 картинок (в сумме ~150 килобайт), после чего следующие были пустыми, а при возврате на предыдущие эти четыре показывались, то image, действительно, их не кеширует, и в этом случае повторно они не показываются.

Определение глобальной переменной:
dom::element g_photogalleryPicture;


Создание фрейма (однократно):
HELEMENT hPicture;
HTMLayoutCreateElement("picture", L"", &hPicture);
HTMLayoutSetAttributeByName(hPicture, "style", _T("width: 100%; height: auto;"));
HTMLayoutInsertElement(hPicture, g_parent, 0);
g_photogalleryPicture = hPicture;


Обновление картинки (периодическое действие):
wchar_t wImageLink[] = _T("..."); // Здесь из списка берется адрес очередной картинки
g_photogalleryPicture.set_attribute("src", wImageLink);
g_photogalleryPicture.update();


CS>2) Использовать <frame> и загружать в него "<html><body><img src=...></body></html>" через element::load_html() ...


Определение глобальной переменной:
dom::element g_photogalleryImageFrame;


Создание фрейма (однократно):
HELEMENT hFrame;
HTMLayoutCreateElement("frame", L"", &hFrame);
HTMLayoutSetAttributeByName(hFrame, "style", _T("width: 100%; height: 100%"));
HTMLayoutInsertElement(hFrame, g_parent, 0);
g_photogalleryImageFrame = hFrame;


Обновление картинки (периодическое действие):
wchar_t wImageLink[] = _T("..."); // Здесь из списка берется адрес очередной картинки
wchar_t buff[1024];
wsprintf(buff, _T("<html><body><picture src='%ls'/></body></html>"), wImageLink);
w2utf utfBuff = w2utf(buff);
g_photogalleryImageFrame.set_html(utfBuff, utfBuff.length());


Эффект аналогичный. Может быть я неверно применяю дескрипторы и смартпоинтеры? Но ведь по идее в первом варианте меняется лишь атрибут.

Кроме этих способов пробовал и другие:

1. Создавать все картинки галереи сразу, делая видимой в каждый момент времени одну из них. Как показала практика, грузиться начинают сразу все картинки, даже изначально невидимые. Поэтому чтобы расставить точки над i display: none везде поубирал, чтобы просто взглянуть на загрузку галереи как будто просто нужно загрузить все указанные картинки. В результате из, допустим, 15 картинок фактически отобразились около тех же 4. Если не на симуляторе, а на современном телефоне посмотреть, то около 7 картинок — поэтому похоже что дело в памяти.

2. Эксперименторовал с картинками в css, назначая их на дивы. Тоже безрезультатно, несколько кешируются, после этого не грузятся.

3. Пробовал при смене картинки выкидывать из DOM предыдущий элемент и вставлять новый. Тоже не помогло.

Единственное что еще не попробовал — подставлять картинки в base64, но не думаю что это особо хорошая идея

Version language : Русский (Россия)
CompanyName : Terra Informatica Software. Inc.
FileDescription : htmlayout: h-smile core, Windows Mobile wrapper
FileVersion : 3, 3, 2, 1
Re[3]: Изменение src
От: Аноним  
Дата: 16.05.10 09:04
Оценка:
Подозрительно сие — 150 килобайт картинки это ерунда для эмулятора и современного телефона.
Попробуйте это в sciter сделать или дайте пример проекта.

/ yarus23
Re[4]: Изменение src
От: DirectX  
Дата: 16.05.10 10:13
Оценка:
Всем спасибо за ответы, вроде бы нащупал откуда грабли.

Прежде всего сделал простейший проект, с простейшим документом:
<html><body><picture style='width: 100%; height: auto;' /></body></html>

Далее записал интересующие проблемные линки в массив:
wchar_t* images[] = { _T("..."), _T("...") };
int imagesCount = sizeof(images) / sizeof(wchar_t*);
int currentImage = 0;

// Обычным образом назначаются после создания документа
dom::element root;
dom::element picture;

и сделал смену картинки по меню (вместо About в простейшем WinMobile приложении):
if (currentImage < imagesCount - 1)
{
    wchar_t* link = images[++currentImage];
    picture.set_attribute("src", link);
    picture.update();
}


Результат — даже на минимальном приложении глюк хорошо воспроизводится — показ нескольких изображений из моей подборки (каждое изображение около 35 килобайт, редко больше!) вызывает залипание дальнейшей смены картинок.

Пошёл дальше: залез на Яндекс.Фотки, выбрал там RSS-поток и покопировал ссылки из него в свой массив. Получилось вроде такого:

wchar_t* images[] = { _T("http://img-fotki.yandex.ru/getx/10000/photohistory.2010.5/16_M"),
    _T("http://img-fotki.yandex.ru/getx/10000/photohistory.2010.5/15_M"),
    _T("http://img-fotki.yandex.ru/getx/10000/photohistory.2010.5/14_M"),
    ... }
};


И, о чудо, стало все работать как надо

После такого успеха поменял суффиксы в данных ссылках на XL, чтобы изображение бралось в максимальном качестве. При этом средняя картинка стала около 130 килобайт (каждая). Результат — всё так же работает.

Осталось две версии:

1. Хостинг.
2. Формат файла.

Сейчас разбираюсь в деталях.

Здесь нужно заметить, что хостинг уже был причиной глюков в работе приложения на HTMLayout. Но в тот раз у меня закралось подозрение, что виной тому использованный было по началу gzip. Сейчас получается что не только это. Самое интересное, что сервер, на котором расположены картинки далеко не детский, и в браузере они грузятся чуть быстрее, чем моментально. Любая!

Ладно, настроил на другом сервере (выделенный) каталог с теми же картинками. Что характерно, после этого ситуация значительно улучшилась. Можно просматривать серии из 20 картинок и все ОК.

Но до конца вопрос не решился — в некоторых галереях затыки стабильно происходят, но не 100% детерминированно. Поэтому продолжаю изыскания. Не исключено, что и с форматом файлов что-то не то. А возможно имеет значение порядок следования файлов (чередование соотношений сторон, например). Буду делать серверное перекодирование через Python Image Library. Поэкспериментирую также и с серверами (lighttpd, nginx). Сейчас на скорую руку все крутится из-под Апача.

Как удастся локализовать причину, напишу.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.