2014-02-19 5 views
0

У нас есть двоичный файл на клиенте. Это отсканированная страница из книги, которая приходит к клиенту как-то сжатой. У нас есть декодер (на клиенте), который выводит TypedArray, который содержит файл данных BMP. Мы должны сделать это как можно быстрее. Размер BMP составляет около 3000000 байт (после декодирования длина возвращаемого typedArray). Мы пробовали много решений, но на медленных ПК это не сработало. Например, самый быстрый способ, который мы нашли: Мы создаем blob из TypedArray. Создайте URL-адрес этого блоба и укажите его как атрибут src для источника изображения. Для рендеринга 20 страниц потребовалось около 22000 мс. Также мы попытались отобразить его в base64 с данными: URL-адрес, указанный в теге src, также (34000мс). Мы попытались сделать это на холсте. Но есть такие проблемы, как использование drawImage на холсте, для которого требуется загруженный объект изображения. Может быть, как мы можем сделать это с помощью WebGL с аппаратным ускорением?Самый быстрый способ рендеринга bmp-файла

PS В указанное время время декодирования одинаково во всех случаях.

PS Я могу приложить образцы кода, которые мы пробовали.

+0

Если файл такой большой, и вы хотите его полностью загрузить, я не думаю, что есть что делать. Возможно, вы могли бы попытаться изменить подход к проблеме с помощью чего-то вроде [Zoomify] (https://github.com/turban/Leaflet.Zoomify) – MarcoL

+0

Черно-белые страницы. Я не уверен в данных о цвете, но могу проверить заголовок bmp, если это очень важно. –

+0

MarcoCI, Возможно, я смогу перестроить его с низким разрешением? Но я боюсь, что это будет слишком медленно. Потому что нам нужно делать все на клиенте. –

ответ

2

Я не уверен, что вы подразумеваете под BMP-файлом, пока не имеете в виду Microsoft BMP format.

Я не знаю всех деталей этого формата, но если вы декодируете его вручную в пикселях в JavaScript, вы можете отображать декодированные данные напрямую, загружая их в текстуру в WebGL, а затем представляя квадрант с текстуры.

Есть примеры по всей сети о том, как визуализировать текстурированный квадратик в WebGL.Here's one

Вы хотите загрузить свои данные в текстуру с

gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 
       widthOfImageInPixels, heightOfImagePixels, 0 
       gl.RGBA, gl.UNSIGNED_BYTE, someUint8ArrayWithWidthByHeightPixels); 

Обратите внимание, что если ваши пиксели не RGB или RGBA, подобно говорят, что они YUV или something you can create a shader to display them directly, а не конвертировать их в JavaScript для RGB/RGBA

2

Законы физики всегда применяются:

Большие изображения займет больше времени для загрузки, чем маленькие изображения.

Как обходной путь, как насчет «старомодного» подхода.

Внутри показать «потерю» версию вашей книжной страницы (возможно, небольшую .jpg).

var imgJPG=new Image(); 
imgJPG.onload=start; 
imgJPG.src="yourBookPage.JPG"; 

function start(){ 
    context.drawImage(imgJPG,0,0); 
} 

В то же время начать асинхронную загрузку вашего большого .bmp

var imgPNG=new Image(); 
imgPNG.onload=start; 
imgPNG.src="yourBookPage.bmp"; 

Когда большое изображение полностью загрузится, замените .jpg изображение с .bmp изображения

function start(){ 
    context.clearRect(0,0,canvas.width,canvas.height); 
    context.drawImage(imgPNG,0,0); 
} 

Если пользователь добавляет рисунки перед загрузкой .bmp, вы могут позволить им нарисовать на отдельном холсте прямо поверх холста .jpg. Затем, когда .bmp загружен вы можете объединить существующие рисунки на вершине вновь загружаемая .bmp

context.clearRect(0,0,canvas.width,canvas.height); 

// draw the .png in the background 

context.drawImage(imgPNG,0,0); 

// add any user drawings on top 

context.drawImage(theTempDrawingCanvasWithManyUserDrawings,0,0); 

Удачи с проектом!

+0

Мне не нужен файл для скачивания. Он уже скачал (визуализируется на клиенте в Blob, проблема в том, как быстро его отобразить). В вашем примере вы используете drawImage на холсте. Есть несколько вопросов, которые мы находим. (Плохое изменение размера, нам нужно дождаться загрузки img-объекта в любом случае и т. Д.) Может быть, мы можем добавить img в DOM? Почему мы должны использовать drawImage? Это быстрее? без рендеринга в холсте? И я хочу добавить, что у нас уже есть BMP в объекте Blob. Нам не нужно его загружать, потому что мы загружаемся в определенном формате и декодируем его на клиентской машине в Blob. –

+0

Но ваш ответ был очень полезным в любом случае! поэтому голосуют. –

+0

Формат изображения, который пришел к клиенту, - это фрагмент DJVU, мы декодируем его в BMP через javascript на клиентской машине в браузере. Таким образом, в сети нет проблем. Мы попытались указать src как данные: uri. И многие другие способы, как вы предложили. Но этот метод требует кодирования BMP в base64, который требует времени. Требуется загрузка объекта изображения. Вопрос в том, что, может быть, существуют некоторые методы для ускорения рисования изображения? Например, в холсте без загрузки img-объекта? (Который, конечно, взял некоторую память) –

Смежные вопросы