Last active
August 29, 2015 14:13
-
-
Save jbgutierrez/010109de33e12ceb4f04 to your computer and use it in GitHub Desktop.
Hodgepodge of useful scripts to analize different compression tools
This file contains 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 ruby | |
# coding: UTF-8 | |
require 'bundler/setup' | |
require "sinatra/base" | |
require "sinatra/reloader" | |
require "haml" | |
require_relative "image" | |
PWD = File.dirname(__FILE__) | |
class Server < Sinatra::Base | |
set :sessions, false | |
set :bind, '0.0.0.0' | |
set :public_folder, PWD | |
set :views, PWD | |
register Sinatra::Reloader | |
get '/' do | |
locals = { count: Image.count } | |
haml :index, locals: locals | |
end | |
get '/sample' do | |
content_type :json | |
Image.sample.to_json | |
end | |
post '/choose' do | |
Image.choose params[:file], request.ip | |
content_type :json | |
{}.to_json | |
end | |
run! | |
end |
This file contains 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
# A sample Gemfile | |
source "https://rubygems.org" | |
gem "sinatra" | |
gem "mongoid" | |
gem "bson_ext" | |
gem 'sinatra-reloader' | |
gem 'haml' |
This file contains 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 gnuplot | |
set terminal png size 900, 300 | |
set grid | |
set key invert reverse Left outside | |
set xlabel 'DSSIM' | |
set title "Size vs DSSIM (1920 width)" | |
set ylabel 'Size (kBs)' | |
set output "dssim-size-1920.png" | |
plot [:][:] "datas/imagemagick_1920.dat" using 3:2 title "imagemagick" with lines, "datas/jpegoptim+rescan_1920.dat" using 3:2 title "jpegoptim+rescan" with lines, "datas/mozjpeg_1920.dat" using 3:2 title "mozjpeg" with lines | |
set xlabel 'Quality' | |
set xrange [60:90] reverse | |
set xtics 3 | |
set title "Average DSSIM (1920 width)" | |
set ylabel 'DSSIM' | |
set output "quality-dssim-1920.png" | |
plot [:][:] "datas/imagemagick_1920.dat" using 1:2 title "imagemagick" with lines, "datas/jpegoptim+rescan_1920.dat" using 1:2 title "jpegoptim+rescan" with lines, "datas/mozjpeg_1920.dat" using 1:2 title "mozjpeg" with lines | |
set title "Average size (1920 width)" | |
set ylabel 'Size (kBs)' | |
set output "quality-size-1920.png" | |
plot [:][:] "datas/imagemagick_1920.dat" using 1:3 title "imagemagick" with lines, "datas/jpegoptim+rescan_1920.dat" using 1:3 title "jpegoptim+rescan" with lines, "datas/mozjpeg_1920.dat" using 1:3 title "mozjpeg" with lines |
This file contains 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 ruby | |
# coding: UTF-8 | |
class Array | |
def sum | |
inject(0.0) { |result, el| result + el } | |
end | |
def mean | |
sum / size | |
end | |
end | |
content = File.read 'dssim.log' | |
widths = {} | |
content.split("\n").each do |line| | |
line.gsub!(/resized\/|.jpg/, '') | |
size, dssim, w, q, tool, _ = *(line.split(/__|_q|_w|_| /).reverse) | |
samples = widths[w] ||= {} | |
key = tool + q | |
if sample = samples[key] | |
sample[:dssim] << dssim.to_f | |
sample[:size] << size.to_f | |
else | |
samples[key] = { | |
tool: tool, | |
q: q, | |
dssim: [ dssim.to_f ], | |
size: [ size.to_f ] | |
} | |
end | |
end | |
widths.each do |w, samples| | |
samples.each do |key, sample| | |
line = [ | |
sample[:q], | |
sample[:dssim].mean, | |
(sample[:size].mean / 1024.0).to_i | |
].join ' ' | |
file = 'datas/' + sample[:tool] + '_' + w + '.dat' | |
`echo "#{line}" >> #{file}` | |
end | |
end | |
This file contains 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
require 'bundler/setup' | |
require "mongoid" | |
require 'pathname' | |
Mongoid.load! "mongoid.yml", :production | |
Mongoid.logger = Logger.new $stdout | |
class Image | |
include Mongoid::Document | |
field :tool | |
field :file | |
field :base | |
field :ip | |
field :quality, type: BigDecimal | |
field :width, type: Integer | |
field :size, type: Integer | |
field :approved, type: Boolean | |
def self.load | |
pathname = Pathname.new "imgs/resized" | |
pathname.each_child.each do |file| | |
base, tool, q, w = *file.to_s.split(/__|_q|_w|\./) | |
size = file.stat.size | |
attributes = { tool: tool, quality: q, width: w, size: size, file: file.to_s, base: base } | |
Image.where(attributes).create! | |
end | |
end | |
def self.sample | |
criteria = where(approved: nil, tool: 'mozjpeg') | |
skip = Random.rand criteria.count | |
criteria.skip(skip).pluck(:file).first | |
end | |
def self.choose file, ip='' | |
image = where(file: file).first | |
images = where(:base => image.base, :tool => 'mozjpeg', :_id.ne => image._id) | |
images.update_all(approved: false, ip: ip) | |
image.update(approved: true, ip: ip) | |
end | |
end | |
if __FILE__ == $0 | |
# Image.load | |
image = Image.sample | |
puts image | |
# Image.choose image | |
end |
This file contains 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
!!! | |
%html.no-js{:lang => "es"} | |
%head | |
%meta{:charset => "utf-8"}/ | |
%meta{:content => "IE=edge", "http-equiv" => "X-UA-Compatible"}/ | |
%title | |
%meta{:content => "", :name => "description"}/ | |
%meta{:content => "width=device-width, initial-scale=1", :name => "viewport"}/ | |
%link{:href => "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css", :rel => "stylesheet"}/ | |
%link{:href => "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap-theme.min.css", :rel => "stylesheet"}/ | |
%link{:href => "main.css", :rel => "stylesheet"}/ | |
%body | |
.container-fluid | |
%h1.page-header Cata a ciegas | |
.lead.alert.alert-warning.alert-dismissible.fade.in{:role => "alert"} | |
%button.close{"aria-label" => "Close", "data-dismiss" => "alert", :type => "button"} | |
%span{"aria-hidden" => "true"} × | |
%p | |
La página irá enseñando imágenes grabadas con distintas | |
calidades. Se trata de pulsar encima de aquella que se | |
vea con suficiente calidad. | |
%p | |
Si valen las dos pulsar "Cualquier" | |
%ul#info | |
%li | |
Tiempo: | |
%strong#timer | |
%li | |
Calidad: | |
%strong#quality | |
#frames | |
.frame | |
%img#left | |
.frame | |
%img#right | |
.text-center | |
%button#both.btn.btn-default.btn-lg{:type => "button", 'data-target' => 'both'} Cualquiera | |
%script{:src => "https://code.jquery.com/jquery-2.1.3.js"} | |
/ Latest compiled and minified JavaScript | |
%script{:src => "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"} | |
%script{:src => "main.js"} |
This file contains 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 bash | |
log='dssim.log' | |
for width in 1920; do | |
declare -i quality=70 | |
while [ $quality -lt 91 ]; do | |
resize.sh . -q $quality -w $width -r -t mozjpeg | |
resize.sh . -q $quality -w $width -r -t jpegoptim | |
resize.sh . -q $quality -w $width -r -t imagemagick | |
(( quality=quality + 10 )) | |
done | |
# calculate stats | |
for file in *.jpg; do | |
base=${file/.jpg/} | |
echo "converting $base.jpg" | |
raw_base64=`convert $base.jpg -resize $width png:- | base64` | |
for path in resized/$base*$width*.jpg; do | |
echo "computing dssim for $path" | |
dssim=`convert $path png:- | dssim <(echo "$raw_base64" | base64 --decode) /dev/stdin | awk '{print $1}'` | |
size=`stat -f%z $path` | |
echo "$path $dssim $size" >> $log | |
done | |
done | |
done |
This file contains 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
$(document).ready -> | |
$.ajaxSetup type: "POST" | |
$(".frame").scroll -> | |
$frame = $ this | |
$frame. | |
siblings(). | |
scrollTop($frame.scrollTop()). | |
scrollLeft($frame.scrollLeft()) | |
$(".frame img,#both").click -> | |
$this = $ this | |
target = $this.data 'target' | |
ImageCtrl.target target | |
ImageCtrl = | |
$left: $ '#left' | |
$right: $ '#right' | |
$timer: $ '#timer' | |
$quality: $ '#quality' | |
updateTimer: -> | |
ImageCtrl.$timer.text ImageCtrl.secondsLeft | |
if not ImageCtrl.secondsLeft-- | |
clearTimeout ImageCtrl.timer | |
$('#both').addClass 'in' | |
# ImageCtrl.choose() | |
resetTimer: -> | |
clearTimeout @timer | |
@secondsLeft = Math.floor (@image.highest - @image.lowest) / 3 | |
@secondsLeft = Math.max @secondsLeft, 5 | |
@timer = setInterval @updateTimer, 1000 | |
sample: -> | |
@$left.attr 'src', '' | |
@$right.attr 'src', '' | |
Image.sample (@image) => @draw() | |
choose: -> | |
@image.choose => | |
ImageCtrl.sample() | |
@image = null | |
draw: -> | |
frames = [@$left, @$right] | |
frame = if Math.random() > 0.5 then frames.pop() else frames.shift() | |
frame.data 'target', 'lowest' | |
frame.attr 'src', @image.lowestSrc() | |
frame = frames.pop() | |
frame.data 'target', 'highest' | |
frame.attr 'src', @image.highestSrc() | |
@resetTimer() | |
@$quality.text @image.lowest | |
target: (target) -> | |
return unless @image | |
$('#both').removeClass 'in' | |
if @image.lowest is @image.highest or target isnt 'highest' | |
@choose() | |
else | |
@image.target 'highest' | |
@draw() | |
class Image | |
constructor: (@file) -> | |
@reset() | |
reset: -> | |
@lowest = 60 | |
@highest = 90 | |
@sample: (done) -> | |
$.get 'sample', (file) -> | |
done new Image file | |
choose: (done) -> | |
$.post 'choose', {file: @lowestSrc()}, done | |
target: (target) -> | |
if target is 'lowest' | |
@highest -= 2 | |
else | |
@lowest += 2 | |
lowestSrc: -> @file.replace /q\d+/, "q#{@lowest}" | |
highestSrc: -> @file.replace /q\d+/, "q#{@highest}" | |
ImageCtrl.sample() | |
This file contains 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
@import 'compass/utilities'; | |
@import "compass/css3"; | |
#frames { | |
margin-bottom: 1em; | |
height: 700px; | |
.frame { | |
width: 50%; | |
height: 700px; | |
float: right; | |
text-align: left; | |
overflow-y: auto; | |
right: 0; | |
cursor: pointer; | |
} | |
} | |
#info { | |
@include inline-list(); | |
li { | |
padding: 2em; | |
} | |
} | |
#info { | |
margin: 0 auto; | |
text-align: center; | |
display: block; | |
} | |
// keyframes mixin | |
@mixin keyframes($name) { | |
@-webkit-keyframes #{$name} { | |
@content; | |
} | |
@-moz-keyframes #{$name} { | |
@content; | |
} | |
@-ms-keyframes #{$name} { | |
@content; | |
} | |
@keyframes #{$name} { | |
@content; | |
} | |
} | |
// keyframes mixin | |
@mixin animation($content) { | |
-webkit-animation: $content; | |
-moz-animation: $content; | |
-ms-animation: $content; | |
animation: $content; | |
} | |
#both.in { | |
font-size: 3em; | |
@include transition-property(font-size); | |
@include transition-duration(2s); | |
@include transition-timing-function(ease-in); | |
@include keyframes(bounce) { | |
0% { background:red; } | |
25%, 75% { background:white; } | |
50% { background:white; } | |
100% { background:red; } | |
} | |
@include animation(bounce 1s infinite); | |
} |
This file contains 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
production: | |
sessions: | |
default: | |
hosts: | |
- localhost:27017 | |
database: advanced-compression-techniques |
This file contains 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 bash | |
# This script lets you resize images in batches with different compression tools | |
usage(){ | |
cat <<END | |
usage: resize FILE_OR_FOLDER [options] | |
The options are as follows: | |
-w widths (default: 2560 1920 1024 560) | |
-q quality (default: 75) | |
-a adjust Only files within the adjusted date will be resized. See 'man date' val[ymwdHMS] (default 1m) | |
-t tool Compression tool: jpegoptim, mozjpeg or imagemagick (default: imagemagick) | |
-r Losslessly shrink JPEG file with JPEGrescan (default: 0) | |
END | |
exit 1 | |
} | |
type "convert" > /dev/null 2>&1 || { echo "Please install imagemagick first" >&2; exit 1; } | |
[[ $# -ge 1 ]] || { echo -e "Incorrect number of parameters\n" >&2; usage; } | |
files=$1 | |
[[ -e $files ]] || { echo -e "resize: $files: No such file or directory\n" >&2; usage; } | |
shift | |
adjust="" | |
dir="resized" | |
quality=75 | |
widths="2560 1920 1024 560" | |
tool='imagemagick' | |
rescan=0 | |
while getopts ":w:q:a:t:r" opt; do | |
case $opt in | |
a) adjust=$OPTARG ;; | |
q) quality=$OPTARG ;; | |
r) rescan=1 ;; | |
t) tool=$OPTARG ;; | |
w) widths=$OPTARG ;; | |
--) break ;; | |
:) echo -e "Option -${OPTARG} is missing an argument\n" >&2; usage ;; | |
\?) echo -e "Unknown option: -${OPTARG}\n" >&2; usage ;; | |
esac | |
done | |
if [[ -d $files ]]; then | |
cd $files | |
if [[ -n $adjust ]]; then | |
timestamp=`date -j -v-$adjust +"%Y/%m/%d %H:%M"` | |
files=`find . -newermt "$timestamp" -d 1 -name '*.jpg'` | |
else | |
files=`find . -d 1 -name '*.jpg'` | |
fi | |
fi | |
mkdir -p $dir || { echo "Could not create $dir." >&2; exit 1; } | |
for file in $files; do | |
for width in $widths; do | |
resized_file="${file/.jpg/}__${tool}_q${quality}_w${width}.jpg" | |
echo "generating $resized_file" | |
case $tool in | |
"jpegoptim") `convert -resize $width $file jpg:- | jpegoptim -q -p -f --max=$quality --strip-all --stdout --stdin > $dir/$resized_file` ;; | |
"mozjpeg") `convert -resize $width $file png:- | cjpeg -quality $quality -optimize -dct float -outfile $dir/$resized_file` ;; | |
"imagemagick") `convert -quality $quality -resize $width $file $dir/$resized_file` ;; | |
esac | |
if (( $rescan )); then | |
optimized_file="${file/.jpg/}_${tool}+rescan_q${quality}_w${width}.jpg" | |
echo "generating $optimized_file" | |
`jpegrescan -q -s -i $dir/$resized_file $dir/$optimized_file` | |
fi | |
done | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment