From 60db19bc70b4dcd1486030129c95cfff8e91b11d Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Wed, 25 Mar 2026 13:34:43 +0200 Subject: photo-enhance: add RAW file support (RAF, CR2, CR3, NEF, ARW, DNG, RW2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ImageMagick's LibRaw delegate can decode all major RAW formats. ComfyUI's LoadImage node cannot read RAW directly, so auto_orient_tempfile now decodes RAW → 16-bit TIFF before upload (magick already does this in one pass with -auto-orient). RAW inputs always produce _e.jpg output — there is no enhanced RAW format. EXIF copy (exiftool -TagsFromFile) reads metadata directly from the original RAW file, so capture time, camera/lens info, and GPS are preserved. Co-Authored-By: Claude Sonnet 4.6 --- photo-enhance.rb | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/photo-enhance.rb b/photo-enhance.rb index 7b75600..0715e05 100755 --- a/photo-enhance.rb +++ b/photo-enhance.rb @@ -253,7 +253,8 @@ end # --------------------------------------------------------------------------- class PhotoEnhancer - SUPPORTED_EXTENSIONS = %w[.jpg .jpeg .png .webp].freeze + SUPPORTED_EXTENSIONS = %w[.jpg .jpeg .png .webp .raf .cr2 .cr3 .nef .arw .dng .rw2].freeze + RAW_EXTENSIONS = %w[.raf .cr2 .cr3 .nef .arw .dng .rw2].freeze # No colour corrections — pure AI output from Real-ESRGAN is used as-is. # ImageMagick is only used to bake EXIF rotation and convert PNG→JPEG. @@ -287,7 +288,7 @@ class PhotoEnhancer Dir.glob(File.join(@indir, '*')) .select { |f| File.file?(f) && SUPPORTED_EXTENSIONS.include?(File.extname(f).downcase) } .reject { |f| File.basename(f, '.*').end_with?('_e') } - .reject { |f| File.basename(f).include?('.orient.') } + .reject { |f| File.basename(f).include?('.orient.') } # temp decode files (.orient.tiff etc.) .reject { |f| @manifest.processed?(f) } .sort end @@ -295,7 +296,9 @@ class PhotoEnhancer def enhance_one(src_path) ext = File.extname(src_path).downcase basename = File.basename(src_path, File.extname(src_path)) - dest_path = File.join(File.dirname(src_path), "#{basename}_e#{ext}") + # RAW files are always output as JPEG — there is no enhanced RAW format. + out_ext = RAW_EXTENSIONS.include?(ext) ? '.jpg' : ext + dest_path = File.join(File.dirname(src_path), "#{basename}_e#{out_ext}") @out.puts "[#{Time.now.strftime('%H:%M:%S')}] #{File.basename(src_path)}" @@ -322,10 +325,10 @@ class PhotoEnhancer raise end - # ComfyUI outputs PNG; download then convert to original format. + # ComfyUI outputs PNG; download then convert to output format. tmp_png = "#{dest_path}.tmp.png" @client.download_output(filenames.first, tmp_png) - save_with_corrections(tmp_png, dest_path, ext) + save_with_corrections(tmp_png, dest_path, out_ext) File.delete(tmp_png) if File.exist?(tmp_png) File.delete(upload_path) if upload_path != src_path && File.exist?(upload_path) @@ -349,11 +352,16 @@ class PhotoEnhancer @out.puts " ERROR #{File.basename(src_path)}: #{e.message}" end - # Run magick -auto-orient into a temp file so EXIF rotation is baked in. + # Decode and orient the source image into a temp file suitable for ComfyUI upload. + # RAW files (RAF, CR2, NEF…) are decoded to 16-bit TIFF via ImageMagick's LibRaw + # delegate — ComfyUI's LoadImage cannot read RAW formats directly. + # JPEG/PNG inputs are just auto-oriented in place. # Falls back to the original path if magick is unavailable. def auto_orient_tempfile(src_path) - ext = File.extname(src_path) - tmp = "#{src_path}.orient#{ext}" + ext = File.extname(src_path).downcase + # RAW → TIFF so ComfyUI can load it; JPEG/PNG → same extension with rotation baked in. + out_ext = RAW_EXTENSIONS.include?(ext) ? '.tiff' : ext + tmp = "#{src_path}.orient#{out_ext}" return tmp if system('magick', src_path, '-auto-orient', tmp) && File.exist?(tmp) @out.puts " Warning: auto-orient failed, uploading original" -- cgit v1.2.3