png save openlayers libpng processing-efficiency

escribe png rĂ¡pidamente



save openlayers (2)

Resumen

Quiero escribir un archivo .png lo más rápido posible, sin preocuparme por la compresión. Es decir, no me importa mucho el tamaño del archivo, pero sí me importa que la escritura se realice lo más rápido posible.

Motivación

Estoy creando una aplicación de mapas basada en web utilizando OpenLayers en el lado del cliente y python / C ++ en el back-end. La aplicación debe poder dibujar contenido dinámico rápidamente a medida que el usuario se desplaza por el mapa. Tengo versiones tanto basadas en mosaico (mosaico 256x256) como basadas en una sola imagen ("mosaico único") que funcionan, pero en ambos casos la parte más lenta del render del back-end en realidad está guardando la imagen como un archivo png (ya sea en -disco o en memoria). Por ejemplo, es posible que pueda generar una versión "en bruto", "tga" o "tiff" de una vista determinada en aproximadamente 200 ms, pero se necesitan más de 1,2 segundos para generar la versión .png solo porque el .png guardar tarda casi un segundo completo, mientras que el tiempo para guardar realmente los otros formatos es de 100 ms o menos (y aunque el archivo "sin procesar" es cinco veces el tamaño del archivo .png). Y este tiempo de ahorro de archivo también es significativamente más que el tiempo para transferir la imagen resultante del servidor al cliente. (Una propiedad importante de mi aplicación es que, en general, el "back-end" se ejecutará en la misma máquina que el navegador, por lo que los tiempos de transferencia son insignificantes, incluso para archivos grandes).

Pensé que podría hacer que las escrituras .png sean rápidas (cuando se usa libpng desde C ++) llamando

png_set_compression_level( png_ptr, 0 );

antes de llamar a cualquier función png_write_... Sin embargo, aunque parece que la llamada no impide que libpng comprima el archivo (el archivo resultante tiene aproximadamente el mismo tamaño que el archivo .raw), no hace que guardar el archivo .png sea notablemente más rápido.

Por favor ayuda

Necesito usar .png para estas imágenes, porque las necesito para que sean superposiciones transparentes en la parte superior del mapa base, y necesito más de los 256 colores que ofrece GIF. OpenLayers simplemente usa etiquetas img html, por lo que entiendo que solo puedo usar formatos img válidos.

Pensaría que habría una forma de escribir un archivo .png rápidamente si no se realiza ninguna compresión real (entiendo que .png está "siempre comprimido" pero me imaginé que esto podría incluir "compresión nula"). Parece que deberías poder escribir como un simple encabezado fijo, seguido de los datos sin comprimir, seguido de un pie de página fijo. O tal vez esa misma idea, pero en una línea por línea. El punto es que puedo hacer todo tipo de bucles a través de estos 2.5 MB de datos en bruto en memoria en C ++ muy rápidamente, y puedo volcarlo en varios formatos de archivo muy rápidamente, por lo que parece que debería poder volcarlo de forma fija , formato .png sin comprimir rápidamente también.

¿Eso suena bien? ¿Sabes dónde puedo encontrar ejemplos de código que hace eso?


La compresión speeed para PNG está influenciada principalmente por dos parámetros:

  1. Nivel de compresión de compresión ZLIB. png_set_compression_level 0, con png_set_compression_level esencialmente inhabilitar esta compresión.

  2. Filtrado de píxeles. Esto puede variar para cada línea, y la elección a menudo se realiza mediante una heurística, que puede ser eficiente para el tamaño, pero puede llevar mucho tiempo. Consulte png_set_filter y png_set_filter_heuristics Si la velocidad es la preocupación principal (y, más al punto, si la compresión ZLIB está desactivada), debe seleccionar un solo filtro: PNG_FILTER_NONE

Hay poco más que hacer para optimizar la velocidad, creo. En comparación con un formato "en bruto" como BMP o TGA, un PNG no comprimido seguirá teniendo la carga (pequeña) de calcular el CRC32 para cada fragmento, más el CRC interno de Adler para ZLIB. Y eso es prácticamente todo.

(Para el registro, he codificado un codificador / codificador Java completamente puro que se esfuerza por lograr PNGJ y eficiencia de la CPU: PNGJ )


Lo que quieres es una implementación que sea especializada para tu propósito; Vas a tener que escribir tu propio codificador. En realidad no es demasiado difícil y las especificaciones son gratuitas.

el formato no es demasiado complejo y debería ser fácil de implementar un codificador

Nota: todos los valores están sin firmar. Los enteros de múltiples bytes están en "orden de bytes de red" (el byte más significativo primero).

El formato está compuesto de chunks . estructura de trozo:

  • Longitud de los contenidos del fragmento, 4 bytes.
  • identificador de trozo (ASCII), 4 bytes
  • Contenidos de trozos, "Longitud de los contenidos de trozos" bytes
  • CRC del identificador y el contenido (es decir, excluyendo la longitud), 4 bytes

su implementación solo debería necesitar el número mágico y tres chunks :

diseño detallado:

  • {137, 80, 78, 71, 13, 10, 26, 10} (número mágico), 8 bytes
  • Longitud de byte del fragmento IHDR, 4 bytes (valor: 13)
  • {73, 72, 68, 82} ("IHDR"), 4 bytes
  • ancho, 4 bytes
  • altura, 4 bytes
  • Profundidad de bits (por color) , 1 byte (8 = 24/32 bits de color)
  • tipo de color , 1 byte (2 = RGB)
  • Método de compresión , 1 byte (0 = DEFLATE algo que no permite compresión)
  • método de filtro , 1 byte (0 = sin filtro)
  • método de entrelazado, 1 byte (0 = sin entrelazado)
  • CRC del trozo IHDR , 4 bytes
  • Longitud de bytes del contenido del fragmento IDAT, 4 bytes
  • {73, 68, 65, 84} ("IDAT"), 4 bytes
  • datos de imagen en bruto con DEFLATE algo envoltorio, "longitud de bytes del contenido del fragmento IDAT" bytes
  • CRC del fragmento IDAT , 4 bytes
  • Longitud de byte del fragmento IEND, 4 bytes (valor: 0)
  • {73, 69, 78, 68} ("IEND"), 4 bytes
  • CRC del fragmento IEND , 4 bytes (puede ser precomputado)

DEFLATE sin compresión

Sus datos se dividirán en trozos de 65535 bytes. El formato es simple:

  • primeros X trozos
    • encabezado, 1 byte (valor: 0)
    • datos, 65535 bytes
  • pedazo final
    • encabezado, 1 byte (valor: 1)
    • datos, 65535 bytes o menos

Eso es

así es como haces un archivo png rápido