I've accidentally switched the camera to reduced resolution and several hundreds of photographs have been stored this way.

There are RAWs for these so I can re-develop them to full resolution. Unfortunately, while original picture orientations are preserved, the in-camera JPEG cropping I've used is discarded and the JPEGs from RAWs are always in the sensor ratio 4:3 (or 3:4).

To sum up:

  • There's one set of pictures (IMG1234.JPG - IMG2345.JPG) in the reduced resolution and correct aspect ratios 3:2, 2:3, 4:3 and 3:4.
  • There's another set of pictures (IMG1234.JPG - IMG2345.JPG) in the full resolution and aspect ratios of 4:3 or 3:4.
  • I need the target set of pictures in the full resolution in correct aspect ratios of 3:2, 2:3, 4:3 and 3:4.

What's the recommended tool/chain to accomplish that? Thanks.

  • \$\begingroup\$ You say you have RAWs for the images but your question and your code only deal with the JPEGs. Is creating new JPEGs with the right crops from the RAWs out of the question? \$\endgroup\$
    – Aankhen
    Jul 22, 2018 at 14:27
  • \$\begingroup\$ It isn't but I don't know how to crop RAWs directly. \$\endgroup\$ Jul 22, 2018 at 14:28
  • \$\begingroup\$ Btw. I re-developed JPEGs from RAWs in the camera because none of RAW converters I have yields the same colours as the camera does. \$\endgroup\$ Jul 22, 2018 at 14:31
  • \$\begingroup\$ Okay. Can whatever tool you’re using in-camera to develop the JPEGs produce an uncompressed image, like TIFF or BMP? If so, you could export all your processed images in that uncompressed format, then adjust your code to crop it and save it as a JPEG. \$\endgroup\$
    – Aankhen
    Jul 22, 2018 at 14:32
  • \$\begingroup\$ No. The camera can only develop from RAWs to JPEGs. But IIRC there are tools for lossless JPEG cropping. (The XnView MP can do that in the interactive mode but it's too many pictures to crop them one by one). \$\endgroup\$ Jul 22, 2018 at 14:36

1 Answer 1


I've developed a solution in .NET Core which I'm not going to accept (still waiting for a better answer).

The problem with this solution is that cropping isn't lossless (JPEGs are re-compressed) and ImageSharp somehow damages image metadata - the Date Taken time is displayed as 00:00 in XNView - I had to fix it using ExifTool by copying metadata from camera JPEGs.

Otherwise, it does what I need.

Images are placed in subfolders of a path:
/S - camera JPEGs with reduced resolution
/L - re-developed JPEGs from RAWs with full resolution
/T - target folder for cropped full resolution images

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);
  • \$\begingroup\$ It's been a few months. I doubt you'll get any better (or even, other) solutions to your question. Would you mind accepting this as the answer to your question? Thanks. =) \$\endgroup\$
    – scottbb
    Oct 20, 2018 at 17:36
  • 1
    \$\begingroup\$ OK, thanks for the reminder. I've accepted this as I used this (while not perfect) solution for my problem. \$\endgroup\$ Oct 21, 2018 at 18:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.