Декодирование BMP в JavaScript и рисование в Explorer Canvas

Мне нужно загрузить BMP с JavaScript и отобразить его на экране в Internet Explorer. Во-первых, да, я знаю, что это безумие, я не буду объяснять почему, давайте просто примем на мгновение, что img src не работает из-за ограничений безопасности, но запрос ajax с надлежащей аутентификацией в сообщении будет оттянуть изображение. Этот пример обходит все меры безопасности ради простоты и просто доказывает, что мы можем что-то визуализировать.

Лучшая идея, которую я мог придумать, заключалась в том, чтобы получить поток через ajax, декодировать растровое изображение, а затем отобразить его с помощью холста. Internet Explorer, очевидно, не поддерживает холст, но, к счастью, Google предоставил обертку для SVG под названием excanvas, которую я могу использовать для этого.

Мой код (код отрисовки работает, декодирование bmp не очень)

http://gist.github.com/614328

Возможна будущая поддержка других изображений, помимо BMP, и из-за того, как работает холст, проще всего рисовать пиксели в RGBA. Texture2D, по сути, является классом-оболочкой для массива байтов RGBA, а также кодом рисования. ByteStream немного упрощает работу с массивом байтов, а BitmapDecoder содержит метод преобразования формата BGR в формат RGBA texture2d для рисования.

Возможно ли, что байты неправильно переводятся по пути, или что-то не так с моей логикой декодирования?

К вашему сведению, я получил спецификацию файла из Википедии:

http://en.wikipedia.org/wiki/BMP_file_format#Bitmap_Information_.28DIB_header.29

Есть идеи, что происходит в логике декодирования или логике рисования, из-за чего мой BMP рисуется неправильно?


person slf    schedule 07.10.2010    source источник
comment
excanvas на самом деле является оболочкой для VML, потому что IE не поддерживает SVG. Это, вероятно, не важно для вашего приложения, но стоит знать, если вы хотите манипулировать полученным DOM.   -  person C-Mo    schedule 07.10.2010


Ответы (3)


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

По крайней мере, в Firefox есть способ специально получить двоичные данные, как описано здесь: Обработка двоичных данные.

person casablanca    schedule 07.10.2010
comment
Это выглядит очень полезным, возможно, я смогу подключиться к TechNet или чему-то еще, чтобы попробовать те же самые методы бинарной проводки с IE. Я думаю, что что-то определенно неправильно переводится по проводам. Я помню, как во времена FTP я забывал включить двоичный режим перед выполнением get, и я получал те же результаты, что-то о знаковом бите, используемом в качестве контрольной суммы, но я не могу вспомнить подробности. - person slf; 07.10.2010

Вот гораздо более простой (и гораздо более производительный) подход: base64 кодирует данные BMP (вы можете сделать это либо на сервере, либо на клиенте), а затем встраиваете их в страницу с помощью файла URI данных:

<script type="text/javascript">
  function fetchBmp() {
    $.get('http://localhost:3168/experimental/imgrender/beta.bmp', function (data) {
      var base64Data = $.base64.encode(data); // *

      $('#my-image').attr('src', 'data:image/bmp;base64,' + base64Data);
    });
  }

  // * Lots of plugins for this, e.g. http://github.com/carlo/jquery-base64
</script>    

<img id="my-image" />

Все современные браузеры поддерживают URI данных (включая IE8 и выше — существуют обходные пути для IE7), а также формат BMP.

Как указывает casablanca, могут возникнуть проблемы с загрузкой двоичных данных через Ajax, поэтому вам, возможно, придется поискать обходные пути в Google.

person Jordan Running    schedule 07.10.2010
comment
На самом деле я начал с base64, но когда он не работал, переключился на попытку отрендерить его самостоятельно, и таким образом я добился большего прогресса. Кажется, у base64 есть много ограничений, в частности размер. Для очень маленьких изображений это нормально, но как только вы попадаете в значки аватара размера профиля / головы, он разваливается. Я попробовал этот код, но я получил ошибку в декодере, все еще исследуя - person slf; 07.10.2010

Исправление было комбинацией двух вещей

  1. немного VBScript для чтения необработанных байтов responseBody
  2. при правильном декодировании байтовых данных каждый пиксель не дополняется, как предполагает статья в Википедии, на самом деле каждая строка сканирования дополняется до размера двойного слова.

Рабочий код:

http://gist.github.com/616240

person slf    schedule 08.10.2010