Batch copying Stable Diffusion parameters from PNG to JPG

Started by innover, July 18, 2024, 04:07:13 PM

Previous topic - Next topic

innover

Hi, exiftool looks like probably the only thing that could solve my particular problem but I'm stuck trying to figure out the magical formula. I'll be honest that once I've got the solution to this problem, that'll probably be the one and only thing I'll ever need exiftool for. So the reason I'm asking here is that I've come to the point where I have to balance how invested I would ever be in learning the intricacies of exiftool vs. simply asking here and hopefully having someone who already knows all of this stuff just give me a one-liner and I'll be on my way.

AKA: I'm banging my head against a brick wall and I'll never get there, so here I am, cap in hand asking for a probably trivial to some little bit of help.

The Problem:

I've been using Stable Diffusion a lot and by default images are saved as PNG. In the beginning, I read somewhere that if you saved images as JPG, the metadata, including prompts, seeds and other crucial information, would not be saved. When I read that, either the person who wrote it was giving bad advice or their particular Stable Diffusion frontend did not at the time support writing metadata to JPG. I now know all of this and I generate new images in JPG which do indeed contain the metadata in the EXIF.

The problem now is that I still have a ton of PNGs which I'd like to convert to JPG, thereby saving a lot of disk space. Since the metadata is in the JPGs, I can always recreate the images should the need arise.

The Situation:

I've been reading, trying, testing... Whatever I do, I cannot find the exact syntax which will let me copy metadata from a PNG's extra:parameters to a JPG's EXIF:UserComment.

While the documentation for exiftool is very thorough, it's also information overload for someone like me. I've been reading so much information that at first glance looks relevant, but then after further reading I find it's irrelevant. I struggle with focus issues and I only get so far before zoning out. So I even end up re-reading a lot of stuff again when I don't need to. Indeed, even writing this is being done in batches in a note-taking app before I'll eventually copy/paste it into the forum.

Searching everywhere else, all I see is people saying  some variation of 'I asked ChatGPT and it gave me this script' - none of which have worked for me.

So I give up... Either I make do with lots of wasted storage or...

Some kind soul takes pity and gives me a single one-liner I can use that solves my problem in an instant.

The Files:

So I have directories full of PNGs, like the following:

2024-07-18_02-31-05-5-730370266.png
2024-07-18_02-31-16-6-730370267.png
2024-07-18_02-31-28-7-730370268.png
2024-07-18_02-33-00-1-2102683659.png
2024-07-18_02-33-12-2-2102683660.png
etc...

I can convert these to JPG, leaving the original PNGs intact, so then the directory will look like this:

2024-07-18_02-31-05-5-730370266.jpg
2024-07-18_02-31-05-5-730370266.png
2024-07-18_02-31-16-6-730370267.jpg
2024-07-18_02-31-16-6-730370267.png
2024-07-18_02-31-28-7-730370268.jpg
2024-07-18_02-31-28-7-730370268.png
2024-07-18_02-33-00-1-2102683659.jpg
2024-07-18_02-33-00-1-2102683659.png
2024-07-18_02-33-12-2-2102683660.jpg
2024-07-18_02-33-12-2-2102683660.png
etc...

So what I would like to do is to copy the metadata from every PNG into every JPG with a matching filename. Then I can check the JPGs to make sure before deleting the PNGs and freeing up tons of space.

I generated a couple of small test images - one PNG and one JPG to show what their metadata layouts look like:

2024-07-18_20-30-09-0-1512552530.png2024-07-18_20-30-40-0-794055115.jpg

Here is the output of exiftool for the PNG:
ExifTool Version Number         : 12.89
File Name                       : 2024-07-18_20-30-09-0-1512552530.png
Directory                       : .
File Size                       : 402 kB
File Modification Date/Time     : 2024:07:18 20:30:09+01:00
File Access Date/Time           : 2024:07:18 20:30:09+01:00
File Inode Change Date/Time     : 2024:07:18 20:31:18+01:00
File Permissions                : -rwxr-xr-x
File Type                       : PNG
File Type Extension             : png
MIME Type                       : image/png
Image Width                     : 512
Image Height                    : 512
Bit Depth                       : 8
Color Type                      : RGB
Compression                     : Deflate/Inflate
Filter                          : Adaptive
Interlace                       : Noninterlaced
Pixels Per Unit X               : 3780
Pixels Per Unit Y               : 3780
Pixel Units                     : meters
Parameters                      : {.  "sui_image_params": {.    "prompt": "a photo of an astronaut, ",.    "negativeprompt": "cartoon, ",.    "model": "sdxlhyper/sleipnirTLHTurbo_v27TLHFP16",.    "seed": 1512552530,.    "steps": 10,.    "cfgscale": 4.0,.    "aspectratio": "Custom",.    "width": 512,.    "height": 512,.    "sampler": "dpmpp_2s_ancestral",.    "scheduler": "karras",.    "nopreviews": true,.    "imageformat": "PNG",.    "automaticvae": true,.    "swarm_version": "0.9.1.1",.    "date": "2024-07-18",.    "generation_time": "0.01 (prep) and 3.48 (gen) seconds".  }.}
Image Size                      : 512x512
Megapixels                      : 0.262

Here is the output of exiftool for the JPG:
ExifTool Version Number         : 12.89
File Name                       : 2024-07-18_20-30-40-0-794055115.jpg
Directory                       : .
File Size                       : 66 kB
File Modification Date/Time     : 2024:07:18 20:30:40+01:00
File Access Date/Time           : 2024:07:18 20:30:40+01:00
File Inode Change Date/Time     : 2024:07:18 20:31:18+01:00
File Permissions                : -rwxr-xr-x
File Type                       : JPEG
File Type Extension             : jpg
MIME Type                       : image/jpeg
JFIF Version                    : 1.01
Resolution Unit                 : inches
X Resolution                    : 96
Y Resolution                    : 96
Exif Byte Order                 : Little-endian (Intel, II)
User Comment                    : {.  "sui_image_params": {.    "prompt": "a photo of an astronaut, ",.    "negativeprompt": "cartoon, ",.    "model": "sdxlhyper/sleipnirTLHTurbo_v27TLHFP16",.    "seed": 794055115,.    "steps": 10,.    "cfgscale": 4.0,.    "aspectratio": "Custom",.    "width": 512,.    "height": 512,.    "sampler": "dpmpp_2s_ancestral",.    "scheduler": "karras",.    "nopreviews": true,.    "automaticvae": true,.    "swarm_version": "0.9.1.1",.    "date": "2024-07-18",.    "generation_time": "0.01 (prep) and 3.51 (gen) seconds".  }.}
Image Width                     : 512
Image Height                    : 512
Encoding Process                : Baseline DCT, Huffman coding
Bits Per Sample                 : 8
Color Components                : 3
Y Cb Cr Sub Sampling            : YCbCr4:2:0 (2 2)
Image Size                      : 512x512
Megapixels                      : 0.262

So all I need is to copy the metadata from PNG:parameters to JPG: User Comment for every PNG in the directory with a matching JPG.

That's it! That's all I want! And I can't figure it out.

I am on Linux but I would imagine that shouldn't matter but I thought I'd mention it anyway.

Also, because I've posted a short novella with a bunch of relevant keywords that should show up in a search engine, anyone else in the future who's in my situation can then easily find this. I know I've come across a bunch of people asking the exact same question with no real answers.

StarGeek

Your command should be something like
exiftool -ext jpg -TagsFromFile %d%f.png "-UserComment<Parameters" /path/to/files/

The -ext (-extension) option is used to limit processing to only jpegs, as you don't want to edit the PNGs.

-TagsFromFile %d%f.png This tells exiftool you want to copy tags from files in the same directory %d with the same base filename %f, but with a .png extension instead of the jpeg. Basically, for every jpeg exiftool finds, it will look for a file with the same name but a .png extension instead of .jpg

"-UserComment<Parameters" This will copy the Parameters from the source PNG file, into the UserComment tag in the target JPEG file.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

StarGeek

Quote from: innover on July 18, 2024, 04:07:13 PMAKA: I'm banging my head against a brick wall and I'll never get there, so here I am, cap in hand asking for a probably trivial to some little bit of help.

Never bang your head too long with an exiftool question. While it is always rewarding to figure things out yourself, it's always best to come here and ask if you're not making any headway. I check back here often and when I don't, the forum sends me an email notification that there's something new. I often check because this forum is my version of a Sudoku, always giving me puzzles to work through.

QuoteSearching everywhere else, all I see is people saying  some variation of 'I asked ChatGPT and it gave me this script' - none of which have worked for me.

For what it's worth, ChatGPT gave me a correct answer (it often doesn't with exiftool questions), but then, I also knew the right words to use, which isn't always the case for someone new to image metadata. It did forget putting quotes around the < part to avoid file redirection. But this command would probably work on Windows Powershell, as PS somehow figures out that you're not doing redirection.

Trying out ChatGPT's link feature
"using exiftool, I want to copy the Parameters tag from all png file, into the UserComment tag of all jpeg files with the same name"

The one thing it brought up that I didn't is the -overwrite_original option, as normally exiftool will create a "_Original" backup file when it edits a file. This option suppresses the creation of backup files.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

innover

That works fantastically well! Thanks so much!

I'm very happy with this result but this one little thing would make it perfect:

Can it change the JPG modified time to be the same as the PNG?

It's not crucial but an OCD thing.

Also, I did look for a code button for the exiftool output. But as much as I did look, I couldn't find one. I'm using the dark theme and those buttons are hard to see, but I did try.

The ChatGPT thing... I read responses from others and even tried it myself but all it wanted to do most of the time was to help me convert from PNG to JPG, which... Not what I was asking for.

And yeah, I use Linux so I've had my fair share of learning tons of new syntax just to do one seemingly simple thing only to never need to do it again. I don't normally ask anywhere but this time... Got so say - fantastic support!

StarGeek

I'm assuming you mean the file system time stamp, which would be FileModifyDate. You could add it after the .png
-TagsFromFile %d%f.png -FileModifyDate
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

innover

Awesome! You are indeed a Star, StarGeek!

I've settled on:

exiftool -ext jpg -overwrite_original -TagsFromFile %d%f.png -FileModifyDate "-UserComment<Parameters" '/path/to/directory'

This is perfect. Thanks again!