View difference between Paste ID: ZWpUbNRy and ymCTLrA2
SHOW: | | - or go back to the newest paste.
1
#!/bin/bash
2
# Create a png with a false thumbnail;
3
# looks different when you view it full res.
4
#
5
# PNG Gamma trick (by @marcan42 / [email protected])
6
#
7
# This script implements an improved version of the gamma trick used to make
8
# thumbnail images on reddit/4chan look different from the full-size image.
9
#
10
# Sample output (SFW; images by @Miluda):
11
#  https://mrcn.st/t/homura_gamma_trick.png
12
#  https://www.reddit.com/r/test/comments/6edthw/ (click for fullsize)
13
#  https://twitter.com/marcan42/status/869855956842143744
14
#
15
# Some backstory, explanation and example (slightly NSFW):
16
#  https://www.reddit.com/r/touhou/comments/6e6lga/a/di83t02/
17
#
18
# No idea who came up with the concept; this is an old trick, but past
19
# implementations I've seen were less correct than this one :-)
20
#
21
# This trick works on at least Reddit, 4chan and similar imageboards, Google
22
# Drive, Slack, and probably many others. It does not work on Twitter, as
23
# Twitter always preprocesses PNG images and strips the gAMA chunk. It does,
24
# however, work with e.g. imgur embed previews on Twitter.
25
#
26
# *Different* one-liner trick that works on Twitter (for grayscale images):
27
#  https://twitter.com/marcan42/status/869858577116086272
28
#
29
# License: public domain
30
31
high="$1" # High image (full-size original view)
32
low="$2" # Low image (thumbnail) (should be the same size)
33
34
output="output.png"
35
[ ! -z "$3" ] && output="$3" # Output image
36
37
size=$(convert "$high" -format "%wx%h" info:)
38
39
# Give a slight brightness boost to the high source, then apply the gamma.
40
# This ensures that the pixels look mostly white.
41
convert "$high" -alpha off +level 3.5%,100% -gamma 20 high_gamma.png
42
43
# Since the low image will be washed out, use gamma to darken it a bit, then
44
# reduce its brightness to ensure that its pixels become black after PNG gamma.
45
# 77% brightness gets crushed down to 0x00 or 0x01, enough for our purposes.
46
low_gamma="-alpha off -gamma 0.8 +level 0%,77%"
47
48
# To get rid of the slight "halo" of the high image, we're going to cancel it
49
# out from the low image. The equation that we need is:
50
#   output = ¾low + ¼                (what we want, for high = white)
51
#   output = ¾output_low + ¼high     (what we get)
52
# Solve for output_low:
53
#   ¾output_low + ¼high = ¾low + ¼
54
#   ¾output_low = ¾low + ¼ - ¼high
55
#   output_low = low + ⅓ - ⅓high
56
# This assumes "dumb" resizing (not gamma-correct). For gamma-correct resizing,
57
# or for viewing at 1:1 (which is equivalent to gamma-correct resizing, because
58
# physics, assuming your monitor isn't mangling things), this operation would
59
# have to be done in a linear colorspace. In practice, the vast majority of
60
# resizing implementations are not gamma-correct, so this works.
61
convert \( "$low" $low_gamma \) high_gamma.png \
62
           -compose Mathematics -define compose:args='0,-0.33,1,0.33' \
63
           -composite low_adjusted.png
64
65
# Now compose both images together using the mask, then set the gamma metadata.
66
# Note that the typical display gamma is 2.2 and image gamma is the reciprocal
67
# 1/2.2. Since we're adding a gamma of 20, we need 1/2.2/20 = 0.022727.
68
# We also force the PNG encoder to include the gAMA chunk (and no other
69
# spurious metadata).
70
convert low_adjusted.png high_gamma.png -size $size pattern:gray25 -composite \
71
        -set gamma 0.022727 -define png:include-chunk=none,gAMA "$output"
72
73
rm high_gamma.png low_adjusted.png