una que para paginas optimizar optimizacion jpg imagenes imagen hacer fotografia formatos formato exportar cómo convertir como archivo php image image-processing image-compression

php - que - ¿Cómo guardar una imagen con un tamaño de archivo específico?



optimizar png (9)

Estoy construyendo un sistema PHP mediante el cual los usuarios pueden crear una imagen visualmente compleja que tiene el requisito final de ser de 50 kB o menos .

El usuario puede seleccionar que se imprima el texto en una de 37 imágenes de plantilla, por lo que el resultado es una sola imagen plana.

El texto puede ser de cualquier color y una de varias fuentes. Esto significa que la imagen final puede ser visualmente compleja e impredecible (con la excepción de las dimensiones de la imagen).

Luego tengo el requisito de tener un tamaño de archivo de imagen final no mayor a 50kB (este es un requisito externo y no se puede cambiar).

El último requisito (de nuevo, externo) es que el formato de la imagen debe ser .jpeg, .png o .gif .

Revisé la documentación de GraphicsMagick , pero no puedo encontrar ningún lugar que mencione la posibilidad de establecer el tamaño del archivo y hacer que la compresión se calcule automáticamente .

He considerado hacer esto programáticamente a través de un ciclo de compresión-> guardar-> prueba, sin embargo, me puedo imaginar que esto requeriría bastante del procesador, ya que no puedo calcular el tamaño de archivo basado en la compresión de antemano. Es por eso que estoy preguntando si el problema ya ha sido resuelto en GraphicsMagick.

Editar

Para tener claro por qué hay requisitos externos:

El usuario utilizará este sistema para crear una imagen plana, que luego guardará en su PC. Esta imagen se cargará luego a Adroll para su uso en una campaña de reorientación.

Estos son los requisitos de Adroll en la imagen. Mi sistema solo proporcionará los tamaños de imagen 728x90, 300x250 y 120x600.

Editar 27 de noviembre de 2010

Como esto no parece posible con GraphicsMagick, estoy dispuesto a buscar otras soluciones, como la interfaz directa con bibliotecas de compresión (libpng, etc.) que pueden proporcionar la funcionalidad.

Como último recurso, incluso podría ser factible mirar los algoritmos que pueden lograr esto e implementar uno yo mismo.

Como una analogía, para aquellos que están de esa manera inclinados:

Estoy buscando lo que A * es buscar: tiene un punto de inicio / final definido y encuentra la mejor ruta posible en el tiempo más rápido.

Lo que esperaba evitar es lo que primero es la profundidad / profundidad: buscar puntos de inicio / finalización definidos, pero es posible que no llegue a la solución óptima una vez que encuentre un mínimo local y que tenga el potencial de explotar completamente por medios informáticos.



Como no hay forma de comprimir a un tamaño objetivo que conozco, sugiero buscar una solución indirecta:

  1. Haga algunas estadísticas rápidas (posiblemente al comprimir muchas imágenes con diferentes factores de compresión JPEG) para averiguar cuál es el tamaño comprimido medio y su desviación estándar para un nivel de calidad dado.
  2. Al aceptar una imagen, intente comprimir con una calidad adecuada. Si el archivo resultante es demasiado grande, disminuya la calidad y vuelva a intentarlo. Opcionalmente, si resulta demasiado pequeño, también puede aumentar la calidad.
  3. Deténgase cuando la imagen resultante esté "cerca" de su tamaño objetivo, pero más pequeña.

Para elaborar un poco sobre las matemáticas en el paso 2:

Si elige su calidad inicial de modo que su tamaño medio calculado + 3 * desviación estándar <su tamaño objetivo, entonces el 99.7% de las compresiones dará como resultado un archivo adecuadamente pequeño en el primer intento (suponiendo una distribución normal de tamaños comprimidos).

Puede ajustar la calidad inicial y la lógica que la aumenta o disminuye según lo desee, equilibrando entre una menor carga del servidor y archivos más cercanos a su tamaño máximo ("hacer un mejor uso" de sus restricciones).



Entonces, si entiendo esto correctamente, estás construyendo un sistema que permite a los usuarios escribir texto en una de las imágenes de plantilla que proporcionas. Si eso es correcto, ¿por qué estás guardando la imagen? Puede eliminar fácilmente el límite de tamaño de 50 Kb guardando las acciones del usuario. Es posible que pueda hacer algo como guardar el texto (junto con sus propiedades y ubicación) y la plantilla en la que se encuentra.


Mientras que la opción programática de bucle hasta que se alcanza el tamaño del archivo de destino parece ser la respuesta popular, hay dos formas de hacer esto con la compresión .jpeg :

Existe un método patentado por Kuo, Chun-ming, por lo que no estoy seguro de la viabilidad comercial de su utilización:

Método y dispositivo electrónico para ajustar la relación de compresión de la imagen JPEG

Que se basa en esta fórmula:

log(NSF) = (log(SF1 / SF2) / log(FileSize1 / FileSize2)) * log(Target / FileSize1) + log(SF1)

Dónde

SF1 is a first compression parameter SF2 is a second compression parameter FileSize1 is the size of the image compressed with SF1 FileSize2 is the size of the image compressed with SF2 Target is the target file size NSF is the target compression parameter.

No está claro si SF1, SF2 y NSF están en el rango 0-1, o 0-100, etc., y si FileSize1, FileSize2 y Target están en Bytes, KiloBytes, etc. Experimente con la combinación correcta aquí para encontrar las unidades correctas.

El segundo método proviene de Ricky D. Nguyen en MIT:

Control de tasa y asignaciones de bit para transcodificación JPEG

Él sugiere variar los datos que se utilizan para la compresión mientras está sucediendo. Esta opción puede no ser tan factible de implementar, ya que requiere modificaciones en el código de compresión real.

De estos dos ejemplos, sin duda es posible guardar un archivo .jpeg con un determinado tamaño de archivo de destino.


No sé de una manera de determinar automáticamente el tamaño de archivo resultante de una imagen, esa es la tarea de la biblioteca que genera la imagen. A menos que implemente la compresión usted mismo, no puede precalcular el tamaño resultante.

Lo que podría hacer es recopilar datos estadísticos (altura y ancho de la imagen y tamaño de archivo frente a diferentes opciones de compresión) y hacer sus estimaciones en base a esos datos para nuevas imágenes.

Ejemplo:

  • 50k jpg, 100x200 está comprimido 30k
  • 100k jpg, 100x200 está comprimido 60k

-> cuando obtienes una imagen de 100x202px con 59k, el tamaño comprimido se estimará aproximadamente en 35k.


Pruebe primero .png de 24 bits. Si eso le queda será de la mejor calidad, y listo. Alternativamente, podría probar algunas imágenes típicas y, si ninguna de ellas se ajusta, podría eliminar por completo el formato.

Para .gif y .jpg necesitarás buscar el que mejor se adapte; ninguno puede predecirse con suficiente certeza, y ninguno de los algoritmos es adecuado para la codificación de tasa de bits constante. Puede usar una búsqueda binaria para encontrar la mejor opción. Puede elegir factores de compresión de una lista predeterminada para limitar el número de compresiones de prueba que necesita hacer; por ejemplo, si su lista de factores de compresión .jpg es 4, 6, 8, 12, 18, 27, 44, 66, tendría que hacer 4 compresiones de prueba como máximo.

.gif y paletted .png son lo suficientemente similares como para que solo tengas que elegir uno y olvidarte del otro.

Será difícil elegir entre .gif / .png y .jpg en función de los resultados de la compresión; los artefactos introducidos por cada proceso son completamente diferentes. Nuevamente, es mejor que compres una cantidad de imágenes de prueba para tu tamaño objetivo y elimines un formato u otro en función de las pruebas oculares.


Quizás esté viendo el problema desde el ángulo equivocado. Al seleccionar usar PNG y minimizar los metadatos almacenados en la imagen, minimizará el tamaño del archivo. Esto se debe a que PNG es una estructura de mapa de bits. Siempre que GMagick no almacene el texto como metadatos, no tendrá impacto en el tamaño del archivo. Solo la profundidad de color (que también puede controlar) afectará el tamaño del archivo. Los no entrelazados sin filtrar el tamaño del archivo deben ser esencialmente los mismos que el tamaño de la plantilla. Siempre que las plantillas tengan menos de 50 Kb, deberías estar bien.


Solo hay tres formas de reducir el tamaño final de una imagen dada:

  1. reducir la resolución
  2. reducir la profundidad de color
  3. reducir la complejidad de la imagen

Los primeros dos están bajo tu control. Si la imagen cargada sale con un tamaño de archivo por encima del límite, puede intentar reducirla al siguiente tamaño más pequeño disponible y ver si encaja en eso. Dado que solo tienes 3 resoluciones de objetivos, esto no sería demasiado caro. Pero si necesita que el tamaño "grande" esté disponible, entonces se queda con la opción 3.

Reducir la complejidad de la imagen es una bestia desagradable. Puede intentar reducir el "ruido" interpíxel para producir áreas más grandes del mismo color, que se comprimirán en imágenes GIF / PNG muy bien. Un simple filtro de desenfoque podría lograr esto, pero también podría destruir la legibilidad de cualquier texto o letra pequeña dentro de la imagen. Para un objetivo JPG, puede intentar reducir la calidad de la compresión, pero nuevamente, esto puede dañar las imágenes si baja demasiado la calidad. Si las transformaciones simples del lado del servidor no pueden manejar esto, la imagen tendría que ser rehecha por el artista que la creó en primer lugar.

El único método práctico que puedo ver para automatizar esto es el ciclo comprimir-guardar-prueba que mencionas. Dado que las imágenes finales son relativamente pequeñas, esta no será una gran carga para el servidor. Guardar un gif / png es una operación ligera. La compresión JPG requiere más potencia de la CPU, pero de nuevo, con imágenes pequeñas, un servidor moderno no debería tener problemas para hacer 10 o 20 imágenes de prueba en uno o dos segundos.