-
-
Save marcan/d537c81efc6d0ff57d54273edd6765fd to your computer and use it in GitHub Desktop.
#!/bin/sh | |
# PNG Gamma trick (by @marcan42 / [email protected]) | |
# | |
# This script implements an improved version of the gamma trick used to make | |
# thumbnail images on reddit/4chan look different from the full-size image. | |
# | |
# Sample output (SFW; images by @Miluda): | |
# https://mrcn.st/t/homura_gamma_trick.png | |
# https://www.reddit.com/r/test/comments/6edthw/ (click for fullsize) | |
# https://twitter.com/marcan42/status/869855956842143744 | |
# | |
# Some backstory, explanation and example (slightly NSFW): | |
# https://www.reddit.com/r/touhou/comments/6e6lga/a/di83t02/ | |
# | |
# No idea who came up with the concept; this is an old trick, but past | |
# implementations I've seen were less correct than this one :-) | |
# | |
# This trick works on at least Reddit, 4chan and similar imageboards, Google | |
# Drive, Slack, and probably many others. It does not work on Twitter, as | |
# Twitter always preprocesses PNG images and strips the gAMA chunk. It does, | |
# however, work with e.g. imgur embed previews on Twitter. | |
# | |
# *Different* one-liner trick that works on Twitter (for grayscale images): | |
# https://twitter.com/marcan42/status/869858577116086272 | |
# | |
# License: public domain | |
high="$1" # High image (full-size original view) | |
low="$2" # Low image (thumbnail) (should be the same size) | |
output="output.png" | |
if [ ! -z "$3" ]; then | |
output="$3" # Output image | |
fi | |
size=$(convert "$high" -format "%wx%h" info:) | |
# Give a slight brightness boost to the high source, then apply the gamma. | |
# This ensures that the pixels look mostly white. | |
convert "$high" -alpha off +level 3.5%,100% -gamma 20 high_gamma.png | |
# Since the low image will be washed out, use gamma to darken it a bit, then | |
# reduce its brightness to ensure that its pixels become black after PNG gamma. | |
# 77% brightness gets crushed down to 0x00 or 0x01, enough for our purposes. | |
low_gamma="-alpha off -gamma 0.8 +level 0%,77%" | |
# To get rid of the slight "halo" of the high image, we're going to cancel it | |
# out from the low image. The equation that we need is: | |
# output = ¾low + ¼ (what we want, for high = white) | |
# output = ¾output_low + ¼high (what we get) | |
# Solve for output_low: | |
# ¾output_low + ¼high = ¾low + ¼ | |
# ¾output_low = ¾low + ¼ - ¼high | |
# output_low = low + ⅓ - ⅓high | |
# This assumes "dumb" resizing (not gamma-correct). For gamma-correct resizing, | |
# or for viewing at 1:1 (which is equivalent to gamma-correct resizing, because | |
# physics, assuming your monitor isn't mangling things), this operation would | |
# have to be done in a linear colorspace. In practice, the vast majority of | |
# resizing implementations are not gamma-correct, so this works. | |
convert \( "$low" $low_gamma \) high_gamma.png \ | |
-compose Mathematics -define compose:args='0,-0.33,1,0.33' \ | |
-composite low_adjusted.png | |
# Now compose both images together using the mask, then set the gamma metadata. | |
# Note that the typical display gamma is 2.2 and image gamma is the reciprocal | |
# 1/2.2. Since we're adding a gamma of 20, we need 1/2.2/20 = 0.022727. | |
# We also force the PNG encoder to include the gAMA chunk (and no other | |
# spurious metadata). | |
convert low_adjusted.png high_gamma.png -size $size pattern:gray25 -composite \ | |
-set gamma 0.022727 -define png:include-chunk=none,gAMA "$output" |
How can I use this? already wasted an hour searching on google but found nothing
For those who still don't know how to use it:
- You need a POSIX-compliant shell (like bash)
It's something that will be present on pretty much all Linux distributions and many other UNIX-like systems like BSD or MacOS.
On Windows it won't come pre-installed so you need to either use WSL (Windows Subsystem for Linux, which is a compatibility layer allowing you to execute Linux programs) and install some distro like Ubuntu (which will allow you to execute it just fine), or you need to download some port of bash for Windows, like for example Git Bash. You can probably just search how to get bash on windows on google and you'll find some tutorials. - If you're on a UNIX-like system and downloaded the script, you can move to a directory containing the script you just downloaded using
cd
(change directory) command and running
- 'bash gamma-trick.sh image1.png image2.png output.png` (replace the file names in the command)
- or first running
chmod +x gamma-trick.sh
(to make the file executable) and then./gamma-trick.sh image1.png image2.png output.png
(./ just means the current directory, it has to be before the file you want to execute so that the shell doesn't interpret it as a command, if the file is not in your current directory you can dofolder/gamma-trick.sh
to run it and it'll work just fine)
If you're on Windows and are using WSL then it's basically the same as the process described before and if you're using something like Git Bash you can probably just omit thechmod +x
thing, but I'm not sure, either way doingbash gamma-trick.sh
should work.
Oh yeah, you'll also wanna make sure you have imagemagick installed, which with Linux or WSL you can probably do with your package manager, by running apt install imagemagick
(might differ depending on distro), I suppose you can also install it with Homebrew on MacOS.
When I was running the script I encountered some problems and I had to also use exiftool to set the gAMA tag, so you might also want to install that and add exiftool -overwrite_original -gamma="44" "$output"
at the end of the file.
For those who still don't know how to use it:
- You need a POSIX-compliant shell (like bash)
It's something that will be present on pretty much all Linux distributions and many other UNIX-like systems like BSD or MacOS.
On Windows it won't come pre-installed so you need to either use WSL (Windows Subsystem for Linux, which is a compatibility layer allowing you to execute Linux programs) and install some distro like Ubuntu (which will allow you to execute it just fine), or you need to download some port of bash for Windows, like for example Git Bash. You can probably just search how to get bash on windows on google and you'll find some tutorials.- If you're on a UNIX-like system and downloaded the script, you can move to a directory containing the script you just downloaded using
cd
(change directory) command and running
- 'bash gamma-trick.sh image1.png image2.png output.png` (replace the file names in the command)
- or first running
chmod +x gamma-trick.sh
(to make the file executable) and then./gamma-trick.sh image1.png image2.png output.png
(./ just means the current directory, it has to be before the file you want to execute so that the shell doesn't interpret it as a command, if the file is not in your current directory you can dofolder/gamma-trick.sh
to run it and it'll work just fine)
If you're on Windows and are using WSL then it's basically the same as the process described before and if you're using something like Git Bash you can probably just omit thechmod +x
thing, but I'm not sure, either way doingbash gamma-trick.sh
should work.Oh yeah, you'll also wanna make sure you have imagemagick installed, which with Linux or WSL you can probably do with your package manager, by running
apt install imagemagick
(might differ depending on distro), I suppose you can also install it with Homebrew on MacOS.When I was running the script I encountered some problems and I had to also use exiftool to set the gAMA tag, so you might also want to install that and add
exiftool -overwrite_original -gamma="44" "$output"
at the end of the file.
ive done everything and it says
Invalid Parameter - -format
Invalid Parameter - -alpha
Invalid Parameter - 2.png
would you know on how to fix this
ive done everything and it says
Invalid Parameter - -format Invalid Parameter - -alpha Invalid Parameter - 2.png
would you know on how to fix this
Sounds like the script is using Windows' built-in convert
command which is different from the command from ImageMagick that is meant to be used, although they share the same name.
Make sure you have downloaded ImageMagick before you run the script, and that you've enabled both "Add application directory to system PATH" and "Install legacy utilities (e.g. convert)" during setup, and after that restarted your terminal.
To further debug, you can write where convert
in your terminal, and the output should be something like this:
C:\Program Files\ImageMagick-7.1.1-Q16-HDRI\convert.exe
C:\Windows\System32\convert.exe
Note that it finds two programs, one from ImageMagick and the other from Windows' system folder. The one that shows up first (which in this case is ImageMagick) is the one that will be executed when you type convert
in your terminal.
ive done everything and it says
Invalid Parameter - -format Invalid Parameter - -alpha Invalid Parameter - 2.png
would you know on how to fix thisSounds like the script is using Windows' built-in
convert
command which is different from the command from ImageMagick that is meant to be used, although they share the same name.Make sure you have downloaded ImageMagick before you run the script, and that you've enabled both "Add application directory to system PATH" and "Install legacy utilities (e.g. convert)" during setup, and after that restarted your terminal.
To further debug, you can write
where convert
in your terminal, and the output should be something like this:C:\Program Files\ImageMagick-7.1.1-Q16-HDRI\convert.exe C:\Windows\System32\convert.exe
Note that it finds two programs, one from ImageMagick and the other from Windows' system folder. The one that shows up first (which in this case is ImageMagick) is the one that will be executed when you type
convert
in your terminal.
For those who still don't know how to use it:
- You need a POSIX-compliant shell (like bash)
It's something that will be present on pretty much all Linux distributions and many other UNIX-like systems like BSD or MacOS.
On Windows it won't come pre-installed so you need to either use WSL (Windows Subsystem for Linux, which is a compatibility layer allowing you to execute Linux programs) and install some distro like Ubuntu (which will allow you to execute it just fine), or you need to download some port of bash for Windows, like for example Git Bash. You can probably just search how to get bash on windows on google and you'll find some tutorials.- If you're on a UNIX-like system and downloaded the script, you can move to a directory containing the script you just downloaded using
cd
(change directory) command and running
- 'bash gamma-trick.sh image1.png image2.png output.png` (replace the file names in the command)
- or first running
chmod +x gamma-trick.sh
(to make the file executable) and then./gamma-trick.sh image1.png image2.png output.png
(./ just means the current directory, it has to be before the file you want to execute so that the shell doesn't interpret it as a command, if the file is not in your current directory you can dofolder/gamma-trick.sh
to run it and it'll work just fine)
If you're on Windows and are using WSL then it's basically the same as the process described before and if you're using something like Git Bash you can probably just omit thechmod +x
thing, but I'm not sure, either way doingbash gamma-trick.sh
should work.Oh yeah, you'll also wanna make sure you have imagemagick installed, which with Linux or WSL you can probably do with your package manager, by running
apt install imagemagick
(might differ depending on distro), I suppose you can also install it with Homebrew on MacOS.When I was running the script I encountered some problems and I had to also use exiftool to set the gAMA tag, so you might also want to install that and add
exiftool -overwrite_original -gamma="44" "$output"
at the end of the file.
after running the 'bash gamma-trick.sh image1.png image2.png output.png' in git bash, i get 2 photos. The 'output.png' is one photo and the other photo is called 'high_gamma.png'
What do I do to like join them?
after running the 'bash gamma-trick.sh image1.png image2.png output.png' in git bash, i get 2 photos. The 'output.png' is one photo and the other photo is called 'high_gamma.png'
What do I do to like join them?
The output.png file should be the final result
after running the 'bash gamma-trick.sh image1.png image2.png output.png' in git bash, i get 2 photos. The 'output.png' is one photo and the other photo is called 'high_gamma.png'
What do I do to like join them?The output.png file should be the final result
Why when i send it to discord it stays the same even if u click it? like ive seen just now some pictures that can be resized when clicked
can you help me
the image generated with the script does not have a gAMA chunk in its metadata and doesnt work
do you know why ?
i tried both imagemagick legacy and the new version
ive done everything and it says
Invalid Parameter - -format Invalid Parameter - -alpha Invalid Parameter - 2.png
would you know on how to fix thisSounds like the script is using Windows' built-in
convert
command which is different from the command from ImageMagick that is meant to be used, although they share the same name.Make sure you have downloaded ImageMagick before you run the script, and that you've enabled both "Add application directory to system PATH" and "Install legacy utilities (e.g. convert)" during setup, and after that restarted your terminal.
To further debug, you can write
where convert
in your terminal, and the output should be something like this:C:\Program Files\ImageMagick-7.1.1-Q16-HDRI\convert.exe C:\Windows\System32\convert.exe
Note that it finds two programs, one from ImageMagick and the other from Windows' system folder. The one that shows up first (which in this case is ImageMagick) is the one that will be executed when you type
convert
in your terminal.
According to this issue Magick convert was removed from the "Install legacy utilities" so the script no longer works.
What would I have to do to make it work with the new Magick?
According to this ImageMagick/ImageMagick#7608 (comment) Magick convert was removed from the "Install legacy utilities" so the script no longer works.
What would I have to do to make it work with the new Magick?
Replace convert
with magick
everywhere in the script and it should work
Could not get this to work with ImageMagick 7.1.1 (after converting convert commands to magick), the full-screen image as displayed by the browser looked mostly like the thumbnail image and the gAMA chunk didn't seem to be getting added to the header. Using identify -verbose output.png did not show any png:gAMA chunk, and the file gamma was listed as 0.454545. I downgraded to ImageMagick 6.9.13-21 (and also grabbed the 8-bit version instead of the 16-bit version, not sure which fixed the issue) and now it's closer to working. - the gamma is now correctly listed as 0.02273 in identify, and the png:gAMA header is present (with a matching gamma).
When used in Slack, the original full-screen image is never seen - the thumbnail generated when attaching images, the in-chat embed and full screen, and even the "View in Browser" all show the thumbnail image (mixed with the nearly-white full screen image). You can very briefly see the full-screen image as a thumbnail (when it's uploading the attachment), but once uploaded it seems to lose the gAMA header and the trick no longer works.
When used in Discord, I get mixed results. On Desktop, I see the "thumbnail" image both inline in chat, "fullscreen" in chat, and only once I click "Open in Browser" to show it in Chrome do I see the original full-screen image, instead of a version of the thumbnail. The same image when viewed on Discord mobile app (Android) shows the full-screen image (with a moire pattern) all the time, and never the thumbnail version.
Here is a version of the bash file converted to windows .bat (via ChatGPT with some fixes);
@echo off
rem PNG Gamma trick (by @marcan42 / [email protected])
rem This script implements an improved version of the gamma trick used to make
rem thumbnail images on reddit/4chan look different from the full-size image.
rem Replaced "convert" with "magick.exe" for Image Magick 7+.
rem High image (full-size original view)
set high=%1
rem Low image (thumbnail) (should be the same size)
set low=%2
rem Output image
set output=output.png
if not "%3"=="" set output=%3
rem Get the image size (Width x Height)
for /f "delims=" %%a in ('magick identify -format "%%wx%%h" "%high%"') do set size=%%a
rem Give a slight brightness boost to the high source, then apply the gamma.
rem This ensures that the pixels look mostly white.
magick "%high%" -alpha off +level 3.5%,100% -gamma 20 high_gamma.png
rem Since the low image will be washed out, use gamma to darken it a bit, then
rem reduce its brightness to ensure that its pixels become black after PNG gamma.
rem 77% brightness gets crushed down to 0x00 or 0x01, enough for our purposes.
set low_gamma=-alpha off -gamma 0.8 +level 0%%,77%%
rem To get rid of the slight "halo" of the high image, we're going to cancel it
rem out from the low image. The equation that we need is:
rem output = ¾low + ¼ (what we want, for high = white)
rem output = ¾output_low + ¼high (what we get)
rem Solve for output_low:
rem ¾output_low + ¼high = ¾low + ¼
rem ¾output_low = ¾low + ¼ - ¼high
rem output_low = low + ⅓ - ⅓high
rem This assumes "dumb" resizing (not gamma-correct). For gamma-correct resizing,
rem or for viewing at 1:1 (which is equivalent to gamma-correct resizing, because
rem physics, assuming your monitor isn't mangling things), this operation would
rem have to be done in a linear colorspace. In practice, the vast majority of
rem resizing implementations are not gamma-correct, so this works.
magick "%low%" %low_gamma% high_gamma.png ^
-compose Mathematics -define compose:args="0,-0.33,1,0.33" ^
-composite low_adjusted.png
rem Now compose both images together using the mask, then set the gamma metadata.
rem Note that the typical display gamma is 2.2 and image gamma is the reciprocal
rem 1/2.2. Since we're adding a gamma of 20, we need 1/2.2/20 = 0.022727.
rem We also force the PNG encoder to include the gAMA chunk (and no other
rem spurious metadata).
magick low_adjusted.png high_gamma.png -size %size% pattern:gray25 -composite ^
-set gamma 0.022727 -define png:include-chunk=none,gAMA "%output%"
echo Done! Output saved as %output%.
pause
Usage is still the same - thumbnail_encode.bat <full_image.png> <thumb_image.png> <output.png>
Having any transparency on the thumbnail image seems to produce very incorrect thumbnails. Both images should be the same dimensions.
is there a way i can do it in a regular image editing program without this tool?
How do I use this?