Как обрезать набор изображений на основе другого набора изображений

Я случайно переключил камеру на уменьшенное разрешение, и таким образом сохранилось несколько сотен фотографий.

Для них есть RAW, так что я могу переработать их в полном разрешении. К сожалению, в то время как исходная ориентация изображения сохраняется, кадрирование JPEG в камере, которое я использовал, отбрасывается, а JPEG из RAW всегда имеют соотношение сенсора 4: 3 (или 3: 4).

Подводить итоги:

  • Есть один набор картинок (IMG1234.JPG - IMG2345.JPG) в уменьшенном разрешении и правильных соотношениях сторон 3:2, 2:3, 4:3 и 3:4.
  • Есть еще набор картинок (IMG1234.JPG - IMG2345.JPG) в полном разрешении и соотношениях сторон 4:3 или 3:4.
  • Мне нужен целевой набор изображений в полном разрешении с правильным соотношением сторон 3:2, 2:3, 4:3 и 3:4.

Какой рекомендуемый инструмент/цепочка для этого? Спасибо.

Вы говорите, что у вас есть RAW для изображений, но ваш вопрос и ваш код касаются только JPEG. О создании новых JPEG с правильным кадрированием из RAW не может быть и речи?
Это не так, но я не знаю, как напрямую обрезать RAW.
Кстати. Я переработал JPEG из RAW в камере, потому что ни один из конвертеров RAW, которые у меня есть, не дает тех же цветов, что и камера.
Хорошо. Может ли какой-либо инструмент, который вы используете в камере для разработки файлов JPEG, создавать несжатое изображение, такое как TIFF или BMP? Если это так, вы можете экспортировать все обработанные изображения в этот несжатый формат, а затем изменить свой код, чтобы обрезать его и сохранить в формате JPEG.
Нет. Камера может переходить только из RAW в JPEG. Но у IIRC есть инструменты для обрезки JPEG без потерь. (XnView MP может сделать это в интерактивном режиме, но это слишком много изображений, чтобы обрезать их по одному).
Я понимаю. Возможно, вы могли бы сделать это, используя jpegtran в своем коде: ben.com/jpeg

Ответы (1)

Я разработал решение в .NET Core, которое я не собираюсь принимать (все еще жду лучшего ответа).

Проблема с этим решением заключается в том, что кадрирование не происходит без потерь (JPEG повторно сжимаются), а ImageSharp каким-то образом повреждает метаданные изображения — время даты и времени отображается как 00:00 в XNView — мне пришлось исправить это с помощью ExifTool, скопировав метаданные из камеры в формате JPEG.

В противном случае он делает то, что мне нужно.

Изображения помещаются в подпапки пути:
/S - JPEG-файлы камеры с уменьшенным разрешением
/L - переработанные JPEG-файлы из RAW с полным разрешением
/T - целевая папка для обрезанных изображений с полным разрешением

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);
                        }
                    }
                }
            }
        }           
    }
}
Прошло несколько месяцев. Я сомневаюсь, что вы получите лучшее (или даже другое ) решение вашего вопроса. Не могли бы вы принять это как ответ на ваш вопрос? Спасибо. "="
Хорошо, спасибо за напоминание. Я принял это, поскольку использовал это (хотя и не идеальное) решение для своей проблемы.