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

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 ni 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á la foto nuevamente en el 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?

Respuestas (7)

Aunque la respuesta de Philip es la mejor manera de hacerlo, es posible hacer lo que quieras completamente dentro de la esfera de JPEG.

JPEG funciona al dividir su imagen en bloques llamados Unidades mínimas de codificación (MCU), generalmente de 16 × 16 cada uno, y comprimiéndolos por separado. Puede ver esto en las imágenes cuando aumenta 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érdidas un borde blanco simple a una imagen. Simplemente tenemos que crear una matriz hueca de bloques blancos iguales al tamaño de la imagen de salida, luego soltar los bloques JPEG MCU originales en el medio.¹

Hay una desventaja en esa técnica: solo funciona cuando los tamaños de imagen de entrada y salida son múltiplos pares del tamaño de MCU. Cuando ese no es 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 mantiene alejado de los niveles de compresión JPEG excesivamente altos, por lo que sigue 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érdidas 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 intacto.

La solución lista para usar más simple que conozco es el complemento Better JPEG Lossless Resave para Photoshop. Utiliza técnicas basadas en las ideas anteriores para copiar MCU de la imagen original siempre que sea posible, con el fin de evitar volver a crearlas a partir de la versión sin comprimir, como suele hacer 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 al menos en Photoshop, una imagen puramente blanca guardada a través del nivel 10 de JPEG de Save For Web (es decir, calidad "baja") da como resultado una imagen decodificada que sigue siendo puramente blanca.

    Lo determiné con dos pruebas:

    Primero, cargué el JPEG como una capa encima 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 magnificar las diferencias. La imagen resultante permaneció negra, lo que indica que "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 Información. Nunca encontré uno. Esperaba ver los números parpadear un poco mientras frotaba 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 de coseno discreta .

    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 pulverizados en esta área del borde al imprimir una imagen producida con 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.

Utilicé un programa llamado JPEG Wizard que proporcionó dicha funcionalidad. También tenía una muy buena capacidad para aplicar diferentes relaciones de compresión a diferentes partes de un archivo JPEG. Por lo tanto, uno podría 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 más baja para el fondo, y así terminar con un archivo más pequeño pero de mejor calidad general que si hubiera usado una calidad media para todo.
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: Sí, jpegtrantambién puede extender 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 , que no funciona, pero debería darle una idea de la fealdad involucrada. levanta las manos con frustración
@WarrenYoung: para cambiar el color de los bloques de relleno, presumiblemente necesitaría cambiar solo el primer coeficiente (DC) y dejar los demás 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 parece.
@IlmariKaronen: Eso suena plausible. Otro problema con mi parche es que falla en el programa; Supongo que estoy malinterpretando el tamaño de esas JBLOCKmatrices 2D, por lo que estoy escribiendo en un espacio de memoria que no me pertenece. Siéntase libre de hacer su propio parche o un riff en el mío. Creo que perseguí a este conejo tan lejos como pude por el agujero.
En cuanto a su último punto, la mayor cantidad de ahorro proviene de desechar información de alta frecuencia. La ganancia de desperdiciar la precisión en el color de un bloque sólido de píxeles no podría ser más de un byte o dos, por lo que nunca o casi nunca se hace. Si hay alguna pérdida de información, es en la conversión del espacio de color YUV<->RGB.
(Cómo) ¿Funciona esto si el borde no es un múltiplo de 16 píxeles de grosor? Supongo que rompes el formato si lo haces a mano en el nivel binario.
@Raphael: Creo que si tuviera que escribir un programa para hacer esto como su propósito principal, redondearía los tamaños de los bordes superior e izquierdo al múltiplo más cercano de 16, independientemente de la entrada del usuario. A 240 ppp para impresión, eso crea un error máximo de desplazamiento en la página de 1,6 mm. Probablemente pueda obtener un error tan grande debido al deslizamiento del papel cuando ingresa a los rodillos de alimentación. Luego, a la derecha y en la parte inferior, terminaría con hasta 15 px de la imagen o el borde que requieren una nueva codificación antes de poder volver a los bloques de píxeles blancos "limpios" para terminar ese borde.

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.

Gracias. ¿Y esto es cierto incluso cuando se usa un programa "de mierda" como Paint, al guardarlo, por ejemplo, en TIFF?
Al menos según mi prueba rápida, Paint usa el algoritmo de compresión LZW sin pérdidas al guardar archivos TIFF para que se vea bien.
Tenga en cuenta que es probable que esto aumente significativamente el tamaño de la imagen...
paint también es compatible con PNG, que también es un formato sin pérdidas
+1 por esto, ya que las respuestas que discuten guardar de nuevo en jpeg no son compatibles con todas las opciones de codificación de jpeg.

No es del todo sin pérdidas, pero puedes acercarte bastante usando GIMP (o algún otro editor con una función similar) y los siguientes dos 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 de forma independiente 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 intentara agregar un borde que no tuviera un número entero de bloques de ancho, los bloques de la imagen rellenada no se alinearían con los del original y sería inevitable cierta pérdida de compresión.

    *) En realidad, la mayoría de las imágenes JPEG utilizan submuestreo de croma , lo que significa que solo la parte de 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 de 16×. 16 píxeles Por lo tanto, para obtener los mejores resultados, el ancho de su borde debería ser realmente un múltiplo de 16 píxeles. Sin embargo, normalmente puede salirse con la suya con un borde de 8 (o 24 o 40, etc.) píxeles, ya que no se nota mucho una pequeña pérdida de compresión en el croma.

  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 normalmente usaría!

    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 demasiado la imagen y, en particular, que los bloques en el la nueva imagen aún se alinea con las del original. (Ocasionalmente 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 le agregué un elegante (más o menos) borde en blanco y negro de 8px usando el método descrito anteriormente:

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

Aquí está la diferencia entre la imagen original (15,1 kB) y la imagen editada (16,7 kB), que se muestra usando el modo de capa "Extracción de grano" de GIMP:

Diferencia entre imagen rellenada 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 observa detenidamente) algunos bloques en los que también hubo pérdidas menores en el canal luma debido al redondeo. Aún así, visualmente, la imagen original y la rellenada son prácticamente indistinguibles, incluso con un aumento de 2x y alternando entre ellas.

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

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

Con un gran aumento, definitivamente puede ver que la imagen editada es notablemente más borrosa en algunos lugares que la original, y tomar la diferencia con Grain extract lo confirma:

Diferencia entre imagen rellenada (en q60) y original

"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 progresivas sin pérdidas.
@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.
Esta respuesta no comprende lo que hace la configuración "Usar la configuración de calidad de la imagen original". Esto no intenta conservar mejor una imagen recodificada, sino aplicar aproximadamente la misma degradación (los mismos cuantificadores) a la imagen que se aplicó la última vez. Después de volver a guardar, la imagen se degradará aproximadamente el doble que la original, ya que se degradará una segunda vez en la misma cantidad que la primera vez que se guardó. Esta configuración no es útil para conservar la calidad; solo si quieres ahorrar bytes volviendo a comprimir una imagen que ya estaba bastante degradada y no te importa.
@thomasrutter: No puedo rechazar un comentario, así que solo lo señalaré a la publicación original del foro que describe la función y, en particular, esta cita: " Si solo ha realizado algunos cambios en la imagen, entonces re- usar 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 cuantificación, en comparación con lo que sucedería si usara diferentes tablas de cuantificación " .
@thomasrutter: Además, si no cree en esa publicación, ¿por qué no la prueba usted mismo (o mira las imágenes de prueba que incluí en mi respuesta)? Es bastante fácil verificar que abrir una imagen JPEG en GIMP y volver a guardarla con "Usar la configuración de calidad de la imagen original" causa solo una degradación mínima (aunque, por desgracia, no siempre cero), mientras que cambiar la configuración de calidad (incluso ligeramente ¡hacia arriba!) generalmente conduce a pérdidas de cuantización significativamente más altas.
Esa descripción es incorrecta; la única forma de minimizar las pérdidas en la cuantificación es reducir la cuantificación; volver a guardar con una calidad muy alta (cuantificación baja) será mucho más efectivo para acercarse a la misma calidad que la fuente, que volver a guardar con los mismos cuantificadores que la última vez. Hay mucha información errónea sobre esta característica en la web y la gente piensa que es una forma mágica de mejorar la calidad.
"cambiar la configuración de calidad (¡incluso hacia arriba!) generalmente conduce a pérdidas de cuantización considerables". Esto no sucederá, no es así como funciona la cuantización, desafortunadamente muchas fuentes insinúan o afirman abiertamente que este es el caso. Realice pruebas con PSNR o SSIM o alguna otra métrica común que demuestre que este es el caso (cambiar la calidad hacia arriba da como resultado una calidad más pobre que los cuantificadores iguales) y me corregiré, pero básicamente no es cierto.
@thomasrutter: Está bien, está bien. Descargue esta imagen JPEG , ábrala en GIMP y vuelva a guardarla dos veces: una con "Usar la configuración de calidad de la imagen original" y otra con una calidad elevada a 40. Compare cada JPEG con la imagen base sin comprimir . Usando ImageMagickcompare , obtengo un PSNR de 34.5826 para el JPEG original, 34.5752 para la copia guardada con la misma configuración de calidad y 34.3653 para la guardada en q40. ¿Suficientemente bueno?
Bueno, eso es interesante. ¿Es un máximo local? ¿Hasta dónde sube la escala de calidad hasta que el PSNR es más alto que el mismo resultado Q? ¿Es más alto en Q 41? P 39? O se necesita mas por ejemplo Q 50?
@thomasrutter: No sé; esa es solo la primera imagen de prueba y la primera configuración que probé. Me vinculé a todas las herramientas e imágenes de origen que utilicé para que pudieras reproducir los resultados tú mismo; Me tomó menos de 15 minutos hacer esta prueba rápida, incluida la búsqueda de "PSNR" en Google, la lectura del artículo de Wikipedia y la búsqueda de la página de ayuda de ImageMagick, por lo que debería poder reproducirla en cinco como máximo. Usted es el que tiene ideas extrañas (y demostrablemente contrafactuales) sobre cómo funciona la compresión JPEG aquí, por lo que diría que depende de usted probarlas y no solo esperar que le proporcionen datos.
PD. Estoy bastante a menudo en el chat , si prefiere continuar esta discusión allí.
Solo para comparar, aquí hay otro ejemplo en una respuesta a una pregunta diferente. Mi comprensión en teoría está de acuerdo con Ilmari, pero al menos en mi ejemplo, la práctica parece ser 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: parece depender bastante 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 (cualquiera que sea la versión que haya probado). Tu primera imagen, guardada una vez en q75, tiene un PSNR de 34,0298, mientras que la que se guardó dos veces en q75 tiene uno de solo 32,8169 (y la que se volvió a guardar 8 veces tiene un PSNR de 32,6459). En comparación, guardar la misma imagen de origen una vez en GIMP en q75 da un PSNR de 36,4560; abrirlo y volver a guardarlo con la misma calidad lo reduce solo ligeramente, a 36.3295.
@IlmariKaronen Genial: es bueno saberlo, porque en la mayoría de los casos en los que me importa, es Gimp lo que estoy usando.
@mattdm: Sal. Parece haber una diferencia entre volver a guardar el JPEG directamente con "Usar la configuración de calidad de la imagen original" y copiarlo y pegarlo en una nueva ventana de imagen y guardarlo desde allí (nuevamente en q75); este último da un PSNR de 36.2973, ligeramente peor que volver a guardar directamente (pero aún mucho mejor que con ImageMagick). Supongo que se debe a que el paso de copiar y pegar hace que GIMP olvide cualquier configuración de compresión que guardó como metadatos internos cuando se abrió el JPEG.
¿Podría esa discrepancia en particular estar relacionada con el modo de submuestreo de croma utilizado? "Usar la configuración de calidad de la imagen original" también configura el submuestreo de croma para que coincida con el original, no solo Q. Aunque es posible que ya lo estés haciendo.
@thomasrutter: utilicé submuestreo 4:2:0 para todas mis pruebas, ya que IME es la configuración más común de uso general (y dado que, para la tarea de borde original, es la peor situación). También es lo que usaron las imágenes de prueba que descargué de Wikipedia, por lo que no hay diferencia allí. No puedo decir con 100% de certeza qué usó mattdm, ya que convirtió todas sus imágenes a PNG, pero también parece 4:2:0.

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

Parece que está agregando un borde blanco como ayuda para posicionar su imagen al imprimir. ¿Por qué no centrarse 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 de 4680x3120 para que se ajuste a la resolución/DPI correcta. Esto podría tener un efecto más grave que volver a guardar un jpeg.

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

Las respuestas anteriores son muy buenas.

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

Si un jpg está bien preparado, solo pierde alrededor de un 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 algunos 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.

Realmente lo necesitabas implica que no puedes usar otro formato sin pérdidas, tienes necesidades de almacenamiento o software muy específicas, o un flujo de trabajo muy ajustado.

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

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

Irfanview: active Deshabilitar el submuestreo de color de croma.

Visor de imágenes FastStone - Submuestreo de color: ninguno.

Gimp - Submuestreo 4:4:4

Conclusión. No uses pintura.

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

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 es incorrecta?
No voté (ni a favor ni en contra), 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, en especial, resultó bastante larga); en algún momento, algunas personas pueden comenzar a rechazar (o al menos no votar a favor) las respuestas que claramente no agregan algo nuevo a las existentes. Además, trate de estructurar su respuesta para que las partes importantes se destaquen de un vistazo; en este caso, la única parte que ha resaltado en negrita es una nota al pie sin importancia.
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 de si hay uno de 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 de orden o ser editadas. Voy a echar un vistazo a eso. (Quité el texto en negrita) Gracias de nuevo. :u)
"pierde solo alrededor del 0,5% de información" [cita requerida] :)
Hola Warren, aquí está: otake.com.mx/Apuntes/PruebasDeCompresion2/… Está en español, por ahora usa el traductor de Google y necesito actualizarlo. De hecho, es menos del 0.392% :)

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

Aquí está mi procedimiento almacenado para la inserción de bordes - 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 parte superior izquierda, presione 'Avanzado'
  4. Verifique 'Tamaño del lienzo', presione 'Configuración'
  5. Ingrese el ancho de cada 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 un borde en la lista superior. Esto lo agrega a la lista de 'archivos de entrada:' en la lista inferior
  11. Presione 'Iniciar lote'
¿Podría explicar qué tiene de especial ese método para que cumpla con los requisitos del cartel de no bajar 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 cartel está tratando de evitar.
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 que tenga razón, si desea que elimine o modifique mi publicación, ¡hágamelo saber :)!

¡Puedes hacer esto gratis usando Adobe Acrobat! Haga clic derecho en su foto, luego haga clic en Abrir con Adobe Acrobat. En Adobe, haga clic en Editar PDF. Seleccione la imagen completa (Ctrl A) y luego hágala un poco más pequeña para que haya un borde blanco alrededor. Luego haga clic en Exportar como y seleccione el formato deseado (JPEG, PNG, etc.).

¿Podría explicar cómo evita esto la pérdida de calidad del ciclo de descompresión/recompresión JPEG?