photoprism / photoprism

AI-Powered Photos App for the Decentralized Web 🌈💎✨
https://www.photoprism.app
Other
35.42k stars 1.97k forks source link

RAW: `PHOTOPRISM_JPEG_SIZE` is ignored when converting RAW with `RawTherapee` #2446

Open Rolf-Smit opened 2 years ago

Rolf-Smit commented 2 years ago

I noticed that some of my NEF files (Nikon Raw) where being converted into super small sidecar images 160x120. This is probably a limitation of Darktable, so as a simple fix I tried switching to RawTherapee as the converter for NEF files, using:

PHOTOPRISM_DARKTABLE_BLACKLIST: "nef,raf,cr3"

I'm also using:

PHOTOPRISM_JPEG_SIZE=2048

In the indexing logs I can now see:

convert: DSC_7558.NEF.jpg created in 10.258455267s (rawtherapee-cli)

Result: However after checking the generated sidecar file, it shows a resolution of 4636x3076 which is the original resolution of the NEF file.

Expectation: The generated sidecar file should have a maximum height and width not exceeding the set PHOTOPRISM_JPEG_SIZE (in this case 2048)

Reproduce:

Maybe this all makes sense and this is expected behavior because I currently don't see a size limit being used while converting with RawTherapee? https://github.com/photoprism/photoprism/blob/6cbb6610a8991ccfe26dee6b3a9427243367f0e7/internal/photoprism/convert_jpeg.go#L132

lastzero commented 2 years ago

From what I remember, there is no such parameter for the rawtherapee CLI command:

https://github.com/photoprism/photoprism/blob/6cbb6610a8991ccfe26dee6b3a9427243367f0e7/internal/photoprism/convert_jpeg.go#L174

Instead, you may be able to limit the size and also change many other parameters using profile files. The default profile is located in assets/profiles/raw.pp3.

If there is no easy way to change this other than creating dynamic profiles (which is too much work right now), you are welcome to send a PR to add information on this to our Known Issues page in the docs:

https://docs.photoprism.app/getting-started/troubleshooting/known-issues/

Rolf-Smit commented 2 years ago

@lastzero I tried searching for an easy way to do this with RawTherapee but like you mentioned this doesn't seem to be possible right now. I may dive deeper into profile files to see if maybe those could help, but for now I at least updated the known-issues.md file in the documentation repository (see PR).

aseanwatson commented 1 year ago

@Rolf-Smit

I may dive deeper into profile files to see if maybe those could help,

Have a look at the [Resize] group in rtengine/procparams.cc lines 9411-9429

        if (keyFile.has_group("Resize")) {
            assignFromKeyfile(keyFile, "Resize", "Enabled", pedited, resize.enabled, pedited->resize.enabled);
            assignFromKeyfile(keyFile, "Resize", "Scale", pedited, resize.scale, pedited->resize.scale);
            assignFromKeyfile(keyFile, "Resize", "AppliesTo", pedited, resize.appliesTo, pedited->resize.appliesTo);
            assignFromKeyfile(keyFile, "Resize", "Method", pedited, resize.method, pedited->resize.method);
            assignFromKeyfile(keyFile, "Resize", "DataSpecified", pedited, resize.dataspec, pedited->resize.dataspec);
            assignFromKeyfile(keyFile, "Resize", "Width", pedited, resize.width, pedited->resize.width);
            assignFromKeyfile(keyFile, "Resize", "Height", pedited, resize.height, pedited->resize.height);
            assignFromKeyfile(keyFile, "Resize", "LongEdge", pedited, resize.longedge, pedited->resize.longedge);
            assignFromKeyfile(keyFile, "Resize", "ShortEdge", pedited, resize.shortedge, pedited->resize.shortedge);
            if (ppVersion >= 339) {
                assignFromKeyfile(keyFile, "Resize", "AllowUpscaling", pedited, resize.allowUpscaling, pedited->resize.allowUpscaling);
            } else {
                resize.allowUpscaling = false;
                if (pedited) {
                    pedited->resize.allowUpscaling = true;
                }
            }
        }

I'm guessing you could do something like this (forgive me, I've never coded in golang, so the following is pseudo code):

resizeRawTherappeePath := path.Join(conf.TempPath(), "rtResize")
// Create temp directory.
if err = os.MkdirAll(zipPath, 0700); err != nil {
    // TODO: handle error
    return
}

resizeRawTherappeeFile := path.Join(resizeRawTherappeePath, fmt.Sprintf("%s.pp3", maxSize))

if !fs.FileExists(resizeRawTherappeeFile) {
    // REVIEW: handle race condition by:
    // 1. using os.CreateTemp,
    // 2. writing the content, 
    // 3. using os.Link to make the resizeRawTherappeeFile (expecting an error in a race condition), and then
    // 4. using os.Remove to get rid of the temp file
    f, err := os.Create(resizeRawTherappeeFile)
    // TODO: handle error
   f.WriteString( fmt.Sprintf("[Resize]\nEnabled=true\nAppliesTo=Full image\nMethod=Nearest\nDataSpecified =4\nLongEdge=%s\n", maxSize))
   f.Close()  
}

And then, later:

-           args := []string{"-o", jpegName, "-p", profile, "-s", "-d", jpegQuality, "-js3", "-b8", "-c", f.FileName()}
+           args := []string{"-o", jpegName, "-p", resizeRawTherappeeFile, "-p", profile, "-s", "-d", jpegQuality, "-js3", "-b8", "-c", f.FileName()}

You could also ask the RawTherappee maintainers to merge PR adding a command line argument to scale the output file.

Should be straightforward to add logic similar to this block except:

Obviously, you'd need to check to see if the RawTherapee maintainers are amenable to a new parameter.