So schneiden Sie eine Reihe von Bildern basierend auf einer anderen Reihe von Bildern zu

Ich habe die Kamera versehentlich auf reduzierte Auflösung geschaltet und mehrere hundert Fotos wurden auf diese Weise gespeichert.

Dafür gibt es RAWs, damit ich sie in voller Auflösung neu entwickeln kann. Während die ursprüngliche Bildausrichtung erhalten bleibt, wird das von mir verwendete JPEG-Zuschneiden in der Kamera leider verworfen, und die JPEGs von RAWs haben immer das Sensorverhältnis 4: 3 (oder 3: 4).

Um zusammenzufassen:

  • Es gibt einen Satz Bilder (IMG1234.JPG - IMG2345.JPG) in reduzierter Auflösung und korrekten Seitenverhältnissen 3:2, 2:3, 4:3 und 3:4.
  • Es gibt noch eine Reihe von Bildern (IMG1234.JPG - IMG2345.JPG) in voller Auflösung und Seitenverhältnissen von 4:3 oder 3:4.
  • Ich benötige die Zielbilder in voller Auflösung in korrekten Seitenverhältnissen von 3:2, 2:3, 4:3 und 3:4.

Was ist das empfohlene Tool / die empfohlene Kette, um dies zu erreichen? Danke.

Sie sagen, Sie haben RAWs für die Bilder, aber Ihre Frage und Ihr Code befassen sich nur mit den JPEGs. Kommt es nicht in Frage, neue JPEGs mit den richtigen Ausschnitten aus den RAWs zu erstellen?
Es ist nicht, aber ich weiß nicht, wie man RAWs direkt zuschneidet.
Übrigens. Ich habe JPEGs aus RAWs in der Kamera neu entwickelt, weil keiner der RAW-Konverter, die ich habe, die gleichen Farben liefert wie die Kamera.
Okay. Kann das Tool, das Sie in der Kamera verwenden, um die JPEGs zu entwickeln, ein unkomprimiertes Bild wie TIFF oder BMP erzeugen? Wenn ja, könnten Sie alle Ihre verarbeiteten Bilder in diesem unkomprimierten Format exportieren, dann Ihren Code anpassen, um ihn zuzuschneiden und als JPEG zu speichern.
Nein. Die Kamera kann nur von RAWs zu JPEGs entwickeln. Aber IIRC gibt es Tools zum verlustfreien JPEG-Zuschneiden. (Der XnView MP kann das im interaktiven Modus, aber es sind zu viele Bilder, um sie einzeln zuzuschneiden).
Ich verstehe. Vielleicht könnten Sie es tun, indem Sie jpegtran in Ihrem Code verwenden: ben.com/jpeg

Antworten (1)

Ich habe eine Lösung in .NET Core entwickelt, die ich nicht akzeptieren werde (warte immer noch auf eine bessere Antwort).

Das Problem bei dieser Lösung ist, dass das Zuschneiden nicht verlustfrei ist (JPEGs werden neu komprimiert) und ImageSharp Bildmetadaten irgendwie beschädigt - die Uhrzeit des Aufnahmedatums wird in XNView als 00:00 angezeigt - ich musste es mit ExifTool beheben, indem ich Metadaten aus kopierte Kamera-JPEGs.

Ansonsten macht es was ich brauche.

Bilder werden in Unterordnern eines Pfades abgelegt:
/S - Kamera-JPEGs mit reduzierter Auflösung
/L - neu entwickelte JPEGs aus RAWs mit voller Auflösung
/T - Zielordner für beschnittene Bilder mit voller Auflösung

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);
                        }
                    }
                }
            }
        }           
    }
}
Es ist ein paar Monate her. Ich bezweifle, dass Sie bessere (oder sogar andere ) Lösungen für Ihre Frage finden werden. Würde es Ihnen etwas ausmachen, dies als Antwort auf Ihre Frage zu akzeptieren? Danke. =)
Okay, danke für die Erinnerung. Ich habe dies akzeptiert, da ich diese (wenn auch nicht perfekte) Lösung für mein Problem verwendet habe.