Last active
August 31, 2015 00:28
-
-
Save lelandbatey/056ecb4b2e437e926bb3 to your computer and use it in GitHub Desktop.
Recompresses a jpeg many times over to destroy quality
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env python | |
from __future__ import print_function | |
import random | |
import sys | |
import os | |
# This code reads like a basketball (it doesn't). In my defense, I wrote this a | |
# long time ago, and I wrote it in one hazy evening out of rage just to spite | |
# people who re-compress jpegs so aggressively. I publish this only because | |
# there's some stuff I need to not forget (e.g. how to add grain to an image | |
# via imagemagick) | |
def run_command(cmd): | |
os.system(cmd) | |
def add_noise(input_img, out_img): | |
return "convert {} {}".format(input_img, out_img) | |
rand_num = int(random.random()*100) | |
rand_dir = "./TEMPFRAME.{rand_num}".format(rand_num=rand_num) | |
return """ | |
mkdir {rand_dir} | |
convert -quiet {input_img} +repage {rand_dir}/init.mpc | |
convert {input_img} -fill 'gray(50%)' -colorize 100% {rand_dir}/only_grey.mpc | |
convert {rand_dir}/init.mpc \ | |
\( {rand_dir}/only_grey.mpc -attenuate 1 -seed 100 +noise gaussian -set colorspace RGB -channel G -separate +channel -blur 0x0.5 \) \ | |
\( -clone 0 -clone 1 -compose overlay -composite \) \ | |
\( {rand_dir}/only_grey.mpc -attenuate 0.5 -seed 200 +noise gaussian -set colorspace RGB -channel G -separate +channel -blur 0x0.5 \) \ | |
\( -clone 2 -clone 3 -compose overlay -composite \) \ | |
-delete 0-3 {out_img} | |
rm -rf {rand_dir}""".format(input_img=input_img, out_img=out_img, rand_dir=rand_dir) | |
def quality_rand(initquality, x): | |
return min(100, int(random.random()*10) + initquality-5) | |
def quality_magic(initquality, x): | |
magic = [4, -5, 2, 4, -2, -3, 2, -5, 1, -1, 1, -4, -4, 4, -3, 2, -3, 2, -5, -3, 2, -4, 3, -5, 3, 3, 1, -1, 0, -4, -1, -1, -1, 2, -4, 2, -5, -2, -2, 4, -1, -5, -5, 2, -2, 1, -5, 4, 4, 3, -4, -4, 2, -4, 3, 3, 1, 1, 2, -4, -1, 1, -4, -4, 1, -3, 0, 3, 2, 4, -5, 3, 0, -4, -4, -1, -5, -4, 2, -5, -5, -1, 0, -3, 3, 3, 4, 2, 1, -5, 4, 1, 0, 1, -1, 1, -1, 2, -5, 3, -5, -2, -3, 4, 1, 1, -1, -2, 4, 0, -5, 2, 3, -4, 3, -5, 4, -2, 1, 4, -4, 3, -1, -2, 3, 1, 1, 3, -1, 0, -2, 1, 0, 4, -2, -1, -1, 0, 0, -1, 1, 0, -3, -2, 0, 2, -1, -5, -2, -4, -5, 0, 2, -5, 0, 1, 0, -2, -5, -2, 3, 0, 3, -4, -5, 2, 0, -2, 0, -1, -1, 0, 1, 2, -5, -2, -3, 3, 3, 1, -3, -2, -3, -2, 3, -2, 3, 3, -1, 4, -3, -3, 0, -3, 2, -1, -2, 2, -4] | |
return initquality + magic[(x-1)%len(magic)] | |
def expand(prev, cur_raw): | |
large_cmd = "mogrify -sample 125% {prev}" | |
run_command(large_cmd.format(prev=prev)) | |
return 'expanded' | |
def shrink(prev, cur_raw): | |
large_cmd = "mogrify -sample 80% {prev}" | |
run_command(large_cmd.format(prev=prev)) | |
return 'normal' | |
def img_converter(startimg, count, initquality=95, q_source="rand"): | |
cmds = [] | |
state = 'normal' | |
prevjpg = "wrecked_working_image.jpg" | |
cur_raw = "wrecked_working_raw_image.ppm" | |
run_command(add_noise(startimg, prevjpg)) | |
quality_sources = { | |
"rand": quality_rand, | |
"magic": quality_magic | |
} | |
quality_func = quality_sources[q_source] | |
quality = initquality | |
for x in xrange(0, count+1): | |
quality = quality_func(initquality, x) | |
if x and not (x%50): | |
if state == 'normal': | |
state = expand(prevjpg, cur_raw) | |
elif state == 'expanded': | |
state = shrink(prevjpg, cur_raw) | |
if not (x%10): | |
print("\r{:>2.2f}% completed".format(float(x)/count*100), end="", file=sys.stderr) | |
run_command("convert {prevjpg} {cur_raw} && convert {cur_raw} -quality {quality}% {prevjpg}".format( | |
prevjpg=prevjpg, | |
cur_raw=cur_raw, | |
quality=quality | |
)) | |
run_command("rm -f {cur_raw}".format(cur_raw=cur_raw)) | |
if state == 'expanded': | |
state = shrink(prevjpg, cur_raw) | |
run_command("cp {} wrecked_final.jpg".format(prevjpg)) | |
run_command("rm -f {}".format(prevjpg)) | |
return " && ".join(cmds) | |
def main(): | |
name = "tmp.png" | |
count = 10 | |
quality = 85 | |
q_source = "rand" | |
if len(sys.argv) > 1: | |
name = sys.argv[1] | |
if len(sys.argv) > 2: | |
count = int(sys.argv[2]) | |
if len(sys.argv) > 3: | |
quality = int(sys.argv[3]) | |
if len(sys.argv) > 4: | |
q_source = sys.argv[4] | |
cmds = img_converter(name, count, quality, q_source) | |
print(file=sys.stderr) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment