¿Cómo puedo agregar un borde a una foto JPEG sin afectar la calidad?

24

Tengo una foto en formato JPEG con resolución 4680x3120. Quiero agregar un borde blanco alrededor de esta foto, convirtiéndola en una foto de 5200x3467 (por motivos de impresión).

Claramente, no estoy alterando o eliminando nada de la foto, simplemente estoy agregando algo. Por lo tanto, en principio este procedimiento puede ser sin pérdidas. Sin embargo, si tuviera que usar Paint para agregar este borde, el proceso de guardado de Paint comprimiría la foto nuevamente al formato JPEG, perdiendo así información y calidad.

¿Hay alguna forma (algún programa más profesional) de agregar algo a una foto JPEG, como un borde, sin afectar la parte original de la foto, sin reducir su calidad?

LBogaardt
fuente

Respuestas:

35

Aunque la respuesta de Philip es el mejor camino a seguir, es posible hacer lo que quieras por completo dentro de la esfera de JPEG.

JPEG funciona dividiendo su imagen en bloques llamados Unidades de codificación mínima (MCU), generalmente de 16 × 16 cada uno, y comprimiéndolos por separado. Puedes ver esto en imágenes cuando subes el nivel de compresión muy alto. A niveles de compresión más razonables, los bloques se mezclan tan suavemente que nunca se ven los bordes.

Podemos aprovechar este hecho para agregar sin pérdida un borde blanco simple a una imagen. Simplemente tenemos que crear una matriz hueca de bloques blancos igual al tamaño de la imagen de salida, luego colocar los bloques originales de MCU JPEG en el medio.

Hay una desventaja en esa técnica: solo funciona cuando los tamaños de imagen de entrada y salida son un múltiplo par del tamaño de MCU. Cuando ese no sea el caso, necesitamos volver a comprimir algunos de los bloques en el margen entre el borde blanco y los bordes de la imagen original. No verá esta diferencia en la salida si se queda lejos de los niveles excesivamente altos de compresión JPEG, lo que es todavía efectiva sin pérdidas.

No conozco ningún programa que solo haga esto. Lo más parecido que conozco es algo que hace la operación inversa: jpegtran tiene una función de recorte que corta sin pérdida partes de los bordes de la imagen.² Lo hace descartando las MCU recortadas a lo largo de los bordes de la imagen, dejándolas en el medio sin tocar.

La solución más simple ya preparada que conozco es el plugin Better JPEG Lossless Resave para Photoshop. Utiliza técnicas basadas en las ideas dadas anteriormente para copiar las MCU de la imagen original siempre que sea posible, a fin de evitar volver a crearlas desde la versión sin comprimir, como lo hace normalmente Photoshop.


Digresiones:

  1. Puede pensar que el borde resultante no será del todo blanco , ya que la pérdida de JPEG creará algún tipo de diferencia de color en la salida. Hice algunas pruebas, y en Photoshop, al menos, una imagen puramente blanca guardada a través del nivel 10 de JPEG para Save For Web (es decir, "baja") da como resultado una imagen decodificada que todavía es puramente blanca.

    Determiné esto con dos pruebas:

    Primero, cargué el JPEG como una capa en la parte superior del original, configuré el modo de fusión de la capa superior en Diferencia, luego agregué una capa de ajuste de Niveles encima para tratar de aumentar las diferencias. La imagen resultante permaneció en negro, lo que indica "no hay diferencia".

    En segundo lugar, cuando no pude ver las diferencias esperadas, solté la capa de ajuste y devolví la capa JPEG al modo de fusión Normal, tomé la herramienta Cuentagotas y busqué en toda la imagen un píxel que no se mostraba como RGB (255,255,255 ) en el panel de información. Nunca encontré uno. Esperaba ver los números parpadear un poco mientras revisaba la imagen, pero se mantuvieron firmes.

    Solo puedo concluir que este es un caso degenerado del algoritmo de codificación: los bloques blancos puros permanecen blancos a través de la transformada discreta del coseno .

    Curiosamente, esto no sucede con los bloques negros puros. Al menos con la implementación de Photoshop, se convierten en RGB (1,1,1) cuando se decodifican, no en RGB (0,0,0).

    En pocas palabras, no necesita preocuparse por los puntos salpicados en esta área del borde cuando imprima una imagen producida utilizando la técnica anterior.

  2. jpegtranes un programa de línea de comandos, pero también hay un programa GUI de Windows basado en el mismo código llamado jpegcrop.

  3. Por desgracia, este complemento es solo para Windows.

Warren Young
fuente
1
He usado un programa llamado JPEG Wizard que proporcionó dicha funcionalidad. También tenía una capacidad muy buena para aplicar diferentes relaciones de compresión a diferentes partes de un JPEG. Por lo tanto, se puede usar una configuración de alta calidad para la cabeza y las manos de una persona, una calidad media para su ropa y una calidad inferior para el fondo, y así terminar con un archivo más pequeño pero una mejor calidad general que si se hubiera usado una calidad media para todo.
supercat
1
No tuve la oportunidad de probarlo, pero esta publicación de blog sugiere que jpegtranla función de recorte también se puede usar para extender. (Sin embargo, no estoy seguro de qué color terminan siendo los bordes extendidos.)
mattdm
44
@mattdm: Sí, jpegtrantambién puede ampliar la imagen, pero siempre se rellena con un gris medio codificado, RGB (128,128,128). Lo hace simplemente porque es la única opción fácil, ya que en el espacio de coeficiente DCT, puede hacerlo con una simple bzero()llamada. Intenté un truco salvaje para cambiar esto , lo que no funciona, pero debería darte una idea de la fealdad involucrada. levanta las manos frustrado
Warren Young
@WarrenYoung: para cambiar el color de los bloques de relleno, probablemente deba cambiar solo el primer coeficiente (DC) y dejar los otros en cero. Por supuesto, los coeficientes están comprimidos, así que ... de todos modos, debería ser factible, pero estoy de acuerdo en que no es tan trivial como podría parecer.
Ilmari Karonen
2
En cuanto a su último punto: la mayor cantidad de ahorro proviene de tirar la información de alta frecuencia. La ganancia de tirar la precisión sobre el color de un bloque sólido de píxeles no puede ser más que un byte o dos, por lo que nunca o casi nunca se hace. Si hay alguna pérdida de información, está en la conversión del espacio de color YUV <-> RGB.
hobbs
20

El punto a recordar aquí es que pierde calidad al guardar la foto en un formato de compresión con pérdida. Siempre que guarde la foto en un formato sin pérdidas (PSD, TIFF, etc.) después de agregar el borde, no perderá más datos de los que ya perdió al guardar la foto como JPEG en primer lugar.

Philip Kendall
fuente
1
Gracias. ¿Y esto es cierto incluso cuando se utiliza un programa 'malo' como Paint, cuando se guarda en, por ejemplo, TIFF?
LBogaardt
44
Al menos según mi prueba rápida, Paint usa el algoritmo de compresión LZW sin pérdidas al guardar TIFF para que se vea bien.
Philip Kendall
55
Tenga en cuenta que es probable que esto aumente significativamente el tamaño de la imagen ...
BlueRaja - Danny Pflughoeft
2
paint también es compatible con PNG, que también es un formato sin pérdida
phuclv
Haga clic en +1 para esto, ya que las respuestas que tratan sobre cómo guardar de nuevo en JPEG no son compatibles con todas las opciones de codificación JPEG.
James Snell
6

No es bastante sin pérdidas, pero se puede llegar muy cerca usando GIMP (o algún otro editor con una característica similar) y los dos siguientes trucos:

  1. Primero, asegúrese de que el borde que está agregando sea un múltiplo de 8 píxeles de ancho (y preferiblemente un múltiplo de 16 píxeles).

    Esto es importante porque el algoritmo de compresión JPEG divide la imagen en bloques de 8 × 8 píxeles *, comenzando desde la esquina superior izquierda, y aplica el algoritmo de compresión con pérdida independientemente a cada bloque. Por lo tanto, al menos en principio, puede rellenar sin pérdidas una imagen JPEG agregando bloques completos de 8 × 8 píxeles alrededor de los existentes. Sin embargo, si intenta agregar un borde que no tenga un número entero de bloques de ancho, los bloques en la imagen acolchada no se alinearían con los del original, y sería inevitable alguna pérdida de compresión.

    *) En realidad, la mayoría de las imágenes JPEG usan submuestreo de croma , lo que significa que solo la parte en escala de grises de la imagen se comprime en bloques de 8 × 8, mientras que los canales de croma se reducen en un 50% antes de la compresión, lo que hace que su tamaño de bloque efectivo sea 16 × 16 píxeles Por lo tanto, para obtener mejores resultados, el ancho de su borde debería ser realmente un múltiplo de 16 píxeles. Sin embargo, generalmente puede salirse con un borde de 8 (o 24 o 40, etc.) píxeles, ya que un poco de pérdida de compresión en el croma no es muy notable.

  2. La segunda parte del truco es, al guardar la imagen final, seleccionar la casilla de verificación "Usar la configuración de calidad de la imagen original" en el cuadro de diálogo Exportar imagen como JPEG (en Configuración avanzada). ¡Haga esto incluso si parece que resultaría en una calidad inferior a la que usaría normalmente!

    Esta configuración hace que GIMP reutilice exactamente la misma configuración de compresión que se usó para la imagen original, lo que generalmente elimina alrededor del 99% de las pérdidas de compresión, siempre que no haya editado la imagen demasiado, y en particular, que los bloques en el La nueva imagen todavía se alinea con las del original. (En ocasiones, todavía habrá algunas pérdidas debido a errores de redondeo, pero mucho menos de lo que habría de otra manera).


Como una demostración rápida, tomé esta imagen de prueba JPEG de Wikimedia Commons , originalmente guardada con una configuración de calidad bastante baja de 50, y agregué un elegante (tipo de) borde blanco y negro de 8px usando el método descrito anteriormente:

Imagen de prueba con borde de 8 píxeles, en su mayoría sin pérdidas

Aquí está la diferencia entre el original (15.1 kB) y la imagen editada (16.7 kB), que se muestra usando el modo de capa "Extracto de grano" de GIMP:

Diferencia entre imagen acolchada y original

Puede ver algunos errores de croma muy leves, causados ​​por el ancho del borde que no es un múltiplo de 16, y (si mira de cerca) algunos bloques donde también hubo pérdidas menores en el canal luma debido al redondeo. Aún así, visualmente, el original y la imagen acolchada son casi indistinguibles, incluso con un aumento de 2x y volteándose alternativamente entre ellos.

En particular, contraste esto con el resultado de aumentar la calidad JPEG de 50 a 60 antes de guardar la imagen acolchada, lo que produce la siguiente imagen de 17,6 kB:

Imagen de prueba con borde de 8px, calidad elevada de 50 a 60

Con un aumento alto, definitivamente puede ver que la imagen editada es notablemente más borrosa en algunos lugares que la original, y tomar la diferencia con el extracto de grano confirma esto:

Diferencia entre imagen acolchada (en q60) y original

Ilmari Karonen
fuente
"seleccionar esta casilla de verificación no parece afectar la configuración" Progresiva "". No es un error, ya que la codificación progresiva es una configuración de codificación, no una configuración de calidad. Jpegtran puede convertir imágenes hacia y desde progresivo sin pérdida.
Damian Yerrick
@tepples: Tienes razón; He eliminado ese párrafo. Por alguna razón, tenía la impresión de que alternar el modo progresivo haría que la configuración de calidad no coincidiera, pero una prueba rápida parece confirmar que estaba equivocado al respecto.
Ilmari Karonen
1
@thomasrutter: No puedo rechazar un comentario, así que solo te señalaré la publicación original del foro que describe la característica y, en particular, esta cita: " Si solo has hecho algunos cambios en la imagen, entonces el uso de las mismas tablas de cuantificación le dará casi la misma calidad y tamaño de archivo que la imagen original. Esto minimizará las pérdidas causadas por el paso de cuantización, en comparación con lo que sucedería si usara diferentes tablas de cuantización " .
Ilmari Karonen
1
Solo para comparar, aquí hay otro ejemplo en una respuesta a una pregunta diferente. Mi comprensión en teoría concuerda con Ilmari, pero al menos en mi ejemplo, la práctica parece estar mucho más con lo que dice Thomas, al menos cuando se comienza con una imagen muy degradada. (Creo que la lápida es un mal ejemplo para este propósito, porque la pérdida de detalles en la piedra es menos obvia que en la piel humana.)
mattdm
1
@mattdm: Parece ser bastante dependiente del software; Intenté reproducir sus resultados de esa respuesta en GIMP, y parece que GIMP (v2.8.10, al menos) es bastante mejor para preservar la calidad JPEG que ImageMagick (cualquier versión que haya probado). Su primera imagen, guardada una vez en q75, tiene un PSNR de 34.0298, mientras que la que se guardó dos veces en q75 tiene una de solo 32.8169 (y la que se volvió a guardar 8 veces tiene una PSNR de 32.6459). En comparación, guardar la misma imagen de origen una vez en GIMP a q75 da un PSNR de 36.4560; abrirlo y volver a guardarlo con la misma calidad lo reduce ligeramente, a 36.3295.
Ilmari Karonen
3

Lo siento si esto no es exactamente lo que querías pero ...

Parece que agrega un borde blanco como ayuda para posicionar su imagen al imprimir. ¿Por qué no enfocarse en aprender las interfaces de impresión correctamente y evitar trucos poco fiables como este? El otro problema que esto plantea es si permite que el programa de impresión cambie el tamaño de su imagen 4680x3120 para que se ajuste a la resolución / DPI correcta. Esto podría tener un efecto más severo que volver a guardar un archivo JPEG.

aaaaargZombis
fuente
Ambos puntos válidos, gracias. Sin embargo, cargué mi foto en una de esas tiendas de impresión en línea, por lo que no tengo control sobre la impresora real.
LBogaardt
1

Las respuestas anteriores son muy buenas.

Solo agregaré algunos "aspectos psicológicos" del formato jpg.

Si un jpg está bien preparado, pierde solo alrededor del 0,5% de información. Eso es en la gran mayoría de los casos algo que el ojo humano no puede ver. Necesita un programa para hacer un análisis y ver las diferencias (como el análisis que acaba de hacer Ilmari).

"Buena calidad" es un proceso, no solo la forma en que un formato de archivo guarda la imagen. Sí, recomprimiste el archivo con jpg una vez más porque realmente lo necesitabas. Si está en una situación controlada, está bien hacerlo.

Usted realmente necesita que implica que no se puede utilizar otro formato sin pérdida, usted tiene necesidades de almacenamiento o de software muy específico, o un flujo de trabajo muy apretado.

Si está realmente preocupado por la calidad, probablemente no estaría usando Paint. El formato JPG tiene algunas configuraciones que no puedes controlar en Paint.

Aquí está mi lista de programas gratuitos donde realmente puede controlar la compresión jpg, y la opción que necesita seleccionar. (Todos ellos en el diálogo de guardar jpg)

Irfanview: active Desactivar submuestreo de color de croma.

FastStone Image Viewer - Submuestreo de color: ninguno.

Gimp - Submuestreo 4: 4: 4

Conclusión. No uses pintura.

Una cosa que aún no he comprobado. Si todos estos programas mantienen el perfil de color incrustado. Editaré mi publicación más tarde.

Rafael
fuente
Alguien votó -1 en esta respuesta. Normalmente no me importa porque sé que puedo decir algo tonto. En este caso específico, ¿qué parte de la respuesta está mal?
Rafael
No voté (arriba o abajo), pero es posible que desee trabajar en su ortografía y gramática para dar una mejor primera impresión (y también, sinceramente, para que su respuesta sea más fácil de leer). Además, esta pregunta ya tiene varias respuestas (y la mía, especialmente, resultó bastante larga); en algún momento, algunas personas pueden comenzar a rechazar (o al menos no votar) las respuestas que claramente no agregan algo nuevo a las existentes. Además, trate de estructurar su respuesta para que los bits importantes se destaquen de un vistazo; en este caso, la única parte que ha resaltado en negrita es una nota al pie sin importancia.
Ilmari Karonen
Gracias por tu comentario Ilmari. Me cuesta pensar en inglés, ya que no es mi lengua materna. Buscaré una herramienta de ortografía. No estoy seguro si hay una gramática. - Para la segunda parte del comentario, entiendo que la lógica detrás de StackExchange es responder la pregunta de forma independiente, porque el flujo de las respuestas no es fijo, porque pueden cambiar el orden o ser editados. Voy a echar un vistazo a eso. (Eliminé el texto en negrita) Gracias de nuevo. : o)
Rafael
1
"pierde solo alrededor del 0.5% de información" [cita requerida] :)
Warren Young
Hola Warren, aquí está: otake.com.mx/Apuntes/PruebasDeCompresion2/… Está en español, por favor use el traductor de Google por ahora, y necesito actualizarlo. De hecho, es inferior al 0.392% :)
Rafael
0

IrfanView funciona bien para mí para conjuntos de imágenes. Aquí hay algunas notas prácticas

Aquí está mi procedimiento almacenado para la inserción del borde - Procedimiento Infran para agregar un borde

  1. Haga clic con el botón derecho en la imagen, 'Abrir con' -> 'InfranView'
  2. Presione 'b'
  3. Marque 'Usar opciones avanzadas' en la esquina superior izquierda, presione 'Avanzado'
  4. Marque 'Tamaño del lienzo', presione 'Configuración'
  5. Ingrese cada ancho de borde (lado izquierdo, lado derecho, lado superior, lado inferior)
  6. Presiona OK'
  7. Seleccione 'Sobrescribir archivos existentes'
  8. Presiona OK'
  9. Ingrese el directorio de salida 'Directorio de salida para archivos de resultados:'
  10. Navegue y haga doble clic en la imagen para agregar borde en la lista superior. Esto lo agrega a la lista 'archivos de entrada:' en la lista inferior
  11. Presione 'Iniciar lote'
J-Dizzle
fuente
1
¿Podría explicar qué tiene de especial ese método para que cumpla con los requisitos del póster de no reducir la calidad de la imagen? En la primera lectura, esto parecería enviar el JPEG a través de todo el ciclo de descompresión-recompresión que el póster está tratando de evitar.
Philip Kendall
hmmm, traes un punto interesante con respecto al ciclo de vida de la imagen a través del proceso que enumero aquí, no pensé en eso. Puede tener razón, si desea que elimine o modifique mi publicación, ¡hágamelo saber :)!
J-Dizzle