Cómo recortar un conjunto de imágenes basado en otro conjunto de imágenes

Accidentalmente cambié la cámara a resolución reducida y varios cientos de fotografías se almacenaron de esta manera.

Hay RAW para estos, así que puedo volver a desarrollarlos a resolución completa. Desafortunadamente, si bien se conservan las orientaciones originales de la imagen, el recorte de JPEG en la cámara que he usado se descarta y los archivos JPEG de RAW siempre tienen una relación de sensor de 4:3 (o 3:4).

Para resumir:

  • Hay un conjunto de imágenes (IMG1234.JPG - IMG2345.JPG) en resolución reducida y relaciones de aspecto correctas 3:2, 2:3, 4:3 y 3:4.
  • Hay otro conjunto de imágenes (IMG1234.JPG - IMG2345.JPG) en resolución completa y relaciones de aspecto de 4:3 o 3:4.
  • Necesito el conjunto objetivo de imágenes en resolución completa en relaciones de aspecto correctas de 3:2, 2:3, 4:3 y 3:4.

¿Cuál es la herramienta/cadena recomendada para lograr eso? Gracias.

Usted dice que tiene archivos RAW para las imágenes, pero su pregunta y su código solo se ocupan de los archivos JPEG. ¿Está fuera de discusión la creación de nuevos archivos JPEG con los recortes correctos de los RAW?
No lo es, pero no sé cómo recortar archivos RAW directamente.
Por cierto. Volví a desarrollar archivos JPEG a partir de RAW en la cámara porque ninguno de los convertidores RAW que tengo produce los mismos colores que la cámara.
Bueno. ¿Puede cualquier herramienta que esté utilizando en la cámara para desarrollar los archivos JPEG producir una imagen sin comprimir, como TIFF o BMP? Si es así, podría exportar todas sus imágenes procesadas en ese formato sin comprimir, luego ajustar su código para recortarlo y guardarlo como JPEG.
No. La cámara solo puede revelar de RAW a JPEG. Pero IIRC hay herramientas para recortar JPEG sin pérdidas. (El XnView MP puede hacer eso en el modo interactivo, pero son demasiadas imágenes para recortarlas una por una).
Veo. Tal vez podrías hacerlo usando jpegtran en tu código: ben.com/jpeg

Respuestas (1)

Desarrollé una solución en .NET Core que no voy a aceptar (todavía estoy esperando una mejor respuesta).

El problema con esta solución es que el recorte no tiene pérdidas (los archivos JPEG se vuelven a comprimir) e ImageSharp de alguna manera daña los metadatos de la imagen: la hora de la fecha tomada se muestra como 00:00 en XNView. JPEG de la cámara.

De lo contrario, hace lo que necesito.

Las imágenes se colocan en subcarpetas de una ruta:
/S - JPEG de la cámara con resolución reducida
/L - JPEG re-desarrollados a partir de RAW con resolución completa
/T - carpeta de destino para imágenes recortadas de resolución completa

using System;
using System.IO;
using System.Linq;
using ImageSharp;
using SixLabors.Primitives;

namespace fix
{
    class Program
    {
        static void Main(string[] args)
        {
            var smalls = Directory.GetFiles("path/S").OrderBy(p => p);
            var tPath = "path/T/";            

            foreach (var path in smalls)
            {
                using (FileStream sStream = File.OpenRead(path))
                // change path to full resolution JPEGs from RAWs
                using (FileStream lStream = File.OpenRead(path.Replace("/S/", "/L/")))
                {
                    var small = Image.Load(sStream);
                    var large = Image.Load(lStream);
                    Rectangle rect = new Rectangle();

                    // image height of the reduced resolution image with in-camera cropping
                    // it's always height, the portrait (2:3) mode is only in EXIF
                    if (small.Height == 1360)
                    {
                        // crop rectangle on the full resolution image (see above)
                        rect = new Rectangle(0, 168, 4000, 2664);
                    }

                    // this file has been cropped
                    if (rect.Width != 0)
                    {
                        using (FileStream tStream = File.OpenWrite(string.Format("{0}{1}", tPath, Path.GetFileName(path))))
                        {
                            var encoder = new ImageSharp.Formats.JpegEncoder();
                            encoder.Quality = 98; // as desired
                            large.Crop(rect).Save(tStream, encoder);
                        }
                    }
                }
            }
        }           
    }
}
Han pasado unos meses. Dudo que obtenga mejores (o incluso otras ) soluciones a su pregunta. ¿Le importaría aceptar esto como la respuesta a su pregunta? Gracias. =)
Bien, gracias por el recordatorio. Acepté esto ya que usé esta solución (aunque no perfecta) para mi problema.