Подтвердить что ты не робот

Быстро писать png

Резюме

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

Мотивация

Я делаю веб-приложение карты с использованием OpenLayers на стороне клиента и python/С++ на задней панели. Приложение должно иметь возможность быстро нарисовать динамический контент, когда пользователь перемещается по карте. У меня есть как на основе плитки (256x256 плитка), так и на одном изображении ( "одиночная плитка" ), но в обоих случаях самая медленная часть фонового рендеринга фактически сохраняет изображение в виде файла png (на -disk или in-memory). Например, я могу сгенерировать версию "raw", "tga" или "tiff" определенного вида примерно за 200 мс, но для генерации версии .png требуется больше, чем 1,2 секунды, потому что .png сохранение занимает почти полную секунду, тогда как время для фактического сохранения других форматов составляет 100 мс или меньше (и хотя "необработанный" файл в пять раз превышает размер файла .png). И это время сохранения файла также значительно больше, чем время для передачи полученного изображения с сервера клиенту. (Одним из важных свойств моего приложения является то, что в целом "back end" будет работать на той же машине, что и браузер, поэтому время передачи незначительно даже для больших файлов.)

Я думал, что могу сделать .png быстро писать (при использовании libpng из С++), вызывая

    png_set_compression_level( png_ptr, 0 );

перед вызовом любых png_write_... функций. Однако, хотя этот вызов действительно, кажется, останавливает libpng от сжатия файла (результирующий файл примерно того же размера, что и файл .raw), он не делает сохранение .png заметно быстрее.

Помогите

Мне нужно использовать .png для этого изображения, потому что мне нужно, чтобы они были прозрачными наложениями поверх базовой карты, и мне нужно больше 256 цветов, предлагаемых GIF. OpenLayers просто использует теги html img, поэтому я понимаю, что могу использовать только допустимые форматы img.

Я бы подумал, что был бы способ быстро записать файл .png, не делая реального сжатия (я понимаю, что .png "всегда сжимается", но я думал, что это может включать "нулевое сжатие" ). Похоже, вы должны писать как простой фиксированный заголовок, за которым следуют несжатые данные, а затем фиксированный нижний колонтитул. Или, может быть, эта же идея, но по-разному. Дело в том, что я могу очень быстро перебирать эти 2,5 МБ необработанных данных в памяти на С++ и очень быстро выгружать их в различные форматы файлов, поэтому мне кажется, что я могу сэкономить его в фиксированном, также несжатый формат .png.

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

4b9b3361

Ответ 1

то, что вы хотите, - это реализация, которая специализирована для вашей цели; вам придется написать собственный кодер. это на самом деле не слишком сложно, и спецификации бесплатны.

формат не слишком сложный и должен быть легко реализован кодировщик

Примечание: значения все не определены. Многобайтные целые числа находятся в "байтовом порядке сети" (сначала самый старший байт).


формат состоит из chunks. структура блока:

  • длина содержимого фрагмента, 4 байта
  • идентификатор канала (ASCII), 4 байта
  • содержимое фрагмента, "длина содержимого фрагмента" байты
  • CRC идентификатора и содержимого (т.е. исключая длину), 4 байта

для вашей реализации потребуется только магическое число и три chunks:


подробный макет:

  • {137, 80, 78, 71, 13, 10, 26, 10} (магическое число), 8 байт
  • длина байта блока IHDR, 4 байта (значение: 13)
  • {73, 72, 68, 82} ( "IHDR" ), 4 байта.
  • ширина, 4 байта
  • высота, 4 байта
  • битовая глубина (для каждого цвета), 1 байт (8 = 24/32 бит цвета)
  • цветной тип, 1 байт (2 = RGB)
  • метод сжатия, 1 байт (0 = DEFLATE, который позволяет без сжатия)
  • метод фильтрации, 1 байт (0 = нет фильтра)
  • метод чередования, 1 байт (0 = без чередования)
  • CRC фрагмента IHDR, 4 байта
  • длина байта содержимого фрагмента IDAT, 4 байта
  • {73, 68, 65, 84} ( "IDAT" ), 4 байта
  • данные необработанного изображения с оберткой из списка DEFLATE, "длина байта содержимого блока IDAT" байты
  • CRC фрагмента IDAT, 4 байта
  • длина байта блока IEND, 4 байта (значение: 0)
  • {73, 69, 78, 68} ( "IEND" ), 4 байта.
  • CRC блока IEND, 4 байта (может быть предварительно вычислено)

Кодирование данных DEFLATE без сжатия

ваши данные будут разделены на куски 65535 байт формат прост:

  • первые фрагменты X
    • заголовок, 1 байт (значение: 0)
    • 65535 байт
  • окончательный фрагмент
    • заголовок, 1 байт (значение: 1)
    • 65535 байт или менее

что он


так вы создаете быстрый файл png

Ответ 2

Сжатие, переданное для PNG, зависит главным образом от двух параметров:

  • Уровень сжатия сжатия ZLIB. Установка этого параметра на 0, при png_set_compression_level в настоящее время составляет отказ от этого сжатия.

  • Пиксельная фильтрация. Это может варьироваться для каждой строки, и выбор часто выполняется с помощью некоторой эвристики, которая может быть эффективной для размера, но может занять много времени. См. png_set_filter и png_set_filter_heuristics Если скорость является основной проблемой (и, более того, если сжатие ZLIB отключено), вы должны выбрать один фильтр: PNG_FILTER_NONE

Думаю, что для оптимизации скорости немного больше нужно сделать. По сравнению с "сырым" форматом, таким как BMP или TGA, несжатый PNG будет по-прежнему иметь (небольшую) нагрузку на вычисление CRC32 для каждого фрагмента, а также внутренний CRC Adler для ZLIB. И это почти все.

(Для записи я закодировал полностью чистый Java-кодер/кодировщик, который стремится к -memory и эффективности процессора: PNGJ)