Skip to content

Instantly share code, notes, and snippets.

@dux
Last active April 4, 2024 08:01
Show Gist options
  • Save dux/6da7375b9ef982b90d2c to your computer and use it in GitHub Desktop.
Save dux/6da7375b9ef982b90d2c to your computer and use it in GitHub Desktop.
Sinatra/puma optimized ruby image resizer
#!/usr/bin/ruby
require 'sinatra'
require 'digest'
ROOT = Dir.getwd
error = nil
for dir in ['cache','cache/originals', 'cache/resized', 'cache/pages', 'cache/croped']
dir = "#{ROOT}/#{dir}"
Dir.mkdir(dir) unless Dir.exists?(dir)
end
def md5(data)
Digest::MD5.hexdigest data
end
class Image
attr_reader :ext, :original, :resized
def initialize(image, quality=80)
@image = image
@ext = image.split('.').reverse[0].to_s
@ext = 'jpg' unless @ext.length > 2 && @ext.length < 5
@ext = @ext.downcase
@quality = quality < 10 ? 80 : quality
@original = "#{ROOT}/cache/originals/#{md5(@image)}.#{@ext}"
end
def download
`curl '#{@image}' -s -o '#{@original}'` unless File.exists?(@original)
@original
end
def resize(size)
resized = "#{ROOT}/cache/resized/#{size}-q#{@quality}-#{md5(@image)}.#{@ext}"
unless File.exists?(resized)
download
`convert '#{@original}' -quality #{@quality} -resize #{size}x2000 '#{resized}'`
end
resized
end
def crop(size, gravity)
width, height = size.downcase.split('x')
height ||= width
raise 'Image to large' if width.to_i > 1500 || height.to_i > 1500
cropped = "#{ROOT}/cache/croped/#{width}x#{height}-q#{@quality}-#{md5(@image)}.#{@ext}"
unless File.exists?(cropped)
download
`convert #{@original} -quality #{@quality} -resize #{width}x#{height}^ -gravity #{gravity} -background black -extent #{width}x#{height} #{cropped}`
end
cropped
end
end
class Pumatra < Sinatra::Base
def get_param(name)
ret = params[name]
unless ret.length > 0
error = "[#{name}] not defined"
return false
end
ret
end
get "/" do
response.headers['Content-type'] = "text/plain"
return %[/resize
- image = source image
- width = integer 10<->1000
- crop = 200 || 200x300
]
end
get "/resize" do
image = params[:image]
return '[image] not defined' unless image.to_s.length > 1
resize_width = params[:width].to_i
crop_size = params[:crop]
return '[width || crop] not defined' if resize_width < 10 && crop_size.to_s.length == 0
img = Image.new(image, params[:q].to_i)
response.headers['Content-type'] = "image/#{img.ext}"
response.headers['Cache-control'] = 'public, max-age=10000000, no-transform'
if resize_width > 0
return 'Image to large' if resize_width > 1500
send_file(img.resize(resize_width), :disposition => 'inline')
else
gravity = params[:gravity].to_s.downcase
gravity = 'North' if gravity.length == 0
send_file(img.crop(crop_size, gravity), :disposition => 'inline')
end
end
get '/crop' do
end
end
if __FILE__ == $0
Pumatra.run!
end
window.imgs = []
imgs.push('http://image.tmdb.org/t/p/original/m7Mhnd7IeW9Ozskyi6IgM6wrvFO.jpg');
imgs.push('http://image.tmdb.org/t/p/original/5T3jI1BcmAlYL34SRK6sbEWkohF.jpg');
imgs.push('http://image.tmdb.org/t/p/original/iwqiKjhZkzisD0Xb2UYTyqv9HpB.jpg');
imgs.push('http://image.tmdb.org/t/p/original/4jL0oIAbH1ePHngpPB0W0c3UwtX.jpg');
imgs.push('http://image.tmdb.org/t/p/original/aIBFi2JEaF0fg0YiF6dVQwgNv8B.jpg');
imgs.push('http://image.tmdb.org/t/p/original/bysk3RM9Tunz6jR0JsD8LHarmDd.jpg');
imgs.push('http://image.tmdb.org/t/p/original/fRtKfOIQOcf5J1Hq2OfnXeqUN0O.jpg');
imgs.push('http://image.tmdb.org/t/p/original/kwG1vm97uUFTiGhTgiJYr9aB0AM.jpg');
imgs.push('http://image.tmdb.org/t/p/original/pYp3ieCZByLwSLQLkkOK2bTgYHz.jpg');
imgs.push('http://image.tmdb.org/t/p/original/MmGQAOfNgE9Ck7jIEkX9BJ9KCG.jpg');
imgs.push('http://image.tmdb.org/t/p/original/kgKgxFsQhG2DyEGpUB3EMUyhxxC.jpg');
imgs.push('http://image.tmdb.org/t/p/original/xameOHNhEduDjIcC2sBcxWLZmDb.jpg');
imgs.push('http://image.tmdb.org/t/p/original/1NvnjZHmPNKouu7KwxvN2q8SLP.jpg');
imgs.push('http://image.tmdb.org/t/p/original/2XH4q5wywTiH2826lEcGm40HmYt.jpg');
imgs.push('http://image.tmdb.org/t/p/original/9NfVtg8g0EPRnzSuljqsjM1q5HA.jpg');
imgs.push('http://image.tmdb.org/t/p/original/4wSaX31oLIrq4Ky762T1SBki2pv.jpg');
imgs.push('http://image.tmdb.org/t/p/original/bEVvfSYAq3zLG9yBk1Eo1LNS0dn.jpg');
imgs.push('http://image.tmdb.org/t/p/original/j951eosixWZm7HU3Ep2QtDslj6w.jpg');
imgs.push('http://image.tmdb.org/t/p/original/yeDHSsMVfqLEPqL6ZiOeFqHPgMK.jpg');
imgs.push('http://image.tmdb.org/t/p/original/cNsJTAVkzT3lUvzILK56Otppc5t.jpg');
imgs.push('http://image.tmdb.org/t/p/original/pZ2xLXQkLTTkVwtJ1x4Qgqqp0fr.jpg');
imgs.push('http://image.tmdb.org/t/p/original/zB0sSnRQ5ltAypFJA1V3hIvSLhm.jpg');
imgs.push('http://image.tmdb.org/t/p/original/7rtlNwdwqT200YVQmWiG2aGDJcB.jpg');
imgs.push('http://image.tmdb.org/t/p/original/ljQadcxMh3faeA3KkfsefMLwbIK.jpg');
imgs.push('http://image.tmdb.org/t/p/original/1o6ayEHWsATXJ76VL7sWDaTnvat.jpg');
imgs.push('http://image.tmdb.org/t/p/original/ki84Cc4pZCRoyKZeVfR5MzzncIB.jpg');
imgs.push('http://image.tmdb.org/t/p/original/rts3EtuDGTm0L0C3XmJQBa5UiY6.jpg');
imgs.push('http://image.tmdb.org/t/p/original/uzKw5vHY9DeVohFO1Rk1KZV3z4g.jpg');
imgs.push('http://image.tmdb.org/t/p/original/3BaAGGBSSWrugFaGRdBAB3DNnD9.jpg');
imgs.push('http://image.tmdb.org/t/p/original/1ltFtZsFdRAe3mjIbOTqkNyar13.jpg');
imgs.push('http://image.tmdb.org/t/p/original/nySPs0k8PMrCarXTxqOqyz2IacU.jpg');
imgs.push('http://image.tmdb.org/t/p/original/lYRy5AwmmkiakMlQHngNgHTAqw7.jpg');
imgs.push('http://image.tmdb.org/t/p/original/rcz7OZsRKhyBz6Jgf04RffpZYOg.jpg');
imgs.push('http://image.tmdb.org/t/p/original/aNsYhvJuFfIowgsLYYvQmBoof5d.jpg');
imgs.push('http://image.tmdb.org/t/p/original/tBWAZZzxGecBQQuaIGALTJX0oZ7.jpg');
imgs.push('http://image.tmdb.org/t/p/original/sLFMWfe7myzeSxDvPE0o1J6xPEU.jpg');
imgs.push('http://image.tmdb.org/t/p/original/oOoJgAcn4lzZM0mu67bJ7e7qhpn.jpg');
imgs.push('http://image.tmdb.org/t/p/original/7a7jFE2E31sVWeKMHC8YXqpWdDV.jpg');
imgs.push('http://image.tmdb.org/t/p/original/yMZEqg0bChOnx367HBezXFf36K9.jpg');
imgs.push('http://image.tmdb.org/t/p/original/fwwDiaHuuBX0xc3Gd91GQoNqOT3.jpg');
imgs.push('http://image.tmdb.org/t/p/original/dOHKCnfokD0iDCkbcGd9oZj8b3W.jpg');
imgs.push('http://image.tmdb.org/t/p/original/sDd6r9ue5NsJYkif8A3pTGeW361.jpg');
imgs.push('http://image.tmdb.org/t/p/original/2WWKJo7AfujwYSOf2ZNkcJfCig0.jpg');
imgs.push('http://image.tmdb.org/t/p/original/x6G5l3wkxIVrpeMGvVbquw2wuLT.jpg');
imgs.push('http://image.tmdb.org/t/p/original/mvQZoN6gkVyjZxULUVBfcNjVg3u.jpg');
imgs.push('http://image.tmdb.org/t/p/original/lxougpPIAYisfceFhatwDP5D8eF.jpg');
imgs.push('http://image.tmdb.org/t/p/original/ewMMHMFUQGLRaihF9rMRPfmjnO9.jpg');
imgs.push('http://image.tmdb.org/t/p/original/dOOlXLME65TVGJmK8dbEkbHGSre.jpg');
imgs.push('http://image.tmdb.org/t/p/original/g1wuUizX8fVDDQhd3CT14Q8zlGs.jpg');
imgs.push('http://image.tmdb.org/t/p/original/1P8o54EtD0Sh1cMlBw0jFBQFNxQ.jpg');
imgs.push('http://image.tmdb.org/t/p/original/dDHn2H952fKojnkU1UanXmmUsrQ.jpg');
imgs.push('http://image.tmdb.org/t/p/original/bzTwVkUj3EWF5QdYAGlUmUUa2Un.jpg');
imgs.push('http://image.tmdb.org/t/p/original/sHEkz7JG0b9SmFey50jFBxaL9NF.jpg');
imgs.push('http://image.tmdb.org/t/p/original/ddG783p9qvVAd7T7awbSeFdV3MX.jpg');
imgs.push('http://image.tmdb.org/t/p/original/fx2Ekv5MzjAHIQOVVHk6AWvWHb9.jpg');
imgs.push('http://image.tmdb.org/t/p/original/3RmPgpJNpZGOnAMctn46f1KFJzZ.jpg');
imgs.push('http://image.tmdb.org/t/p/original/iwRYh7sfuFyjYqLBBrtJQPGSpB.jpg');
imgs.push('http://image.tmdb.org/t/p/original/JhJs0pRn34giB3gudxpDlYMgnc.jpg');
imgs.push('http://image.tmdb.org/t/p/original/ljFZX4p0xwNBQtPkMQ1rfD9pS5c.jpg');
imgs.push('http://image.tmdb.org/t/p/original/sHn3WS8XaYC7C4RGLrRfIiZ5oyL.jpg');
imgs.push('http://image.tmdb.org/t/p/original/i7z7M0WiCXLV3otrKPZnpySxMPi.jpg');
imgs.push('http://image.tmdb.org/t/p/original/6GMmqBLWEHyxhurKoSSejKo4cGR.jpg');
imgs.push('http://image.tmdb.org/t/p/original/9RM7XpDCmuWcQU3LdjRjhJLY1Qo.jpg');
imgs.push('http://image.tmdb.org/t/p/original/xliLT62B3kCSvb3zS2YhN7Jdpge.jpg');
imgs.push('http://image.tmdb.org/t/p/original/73kS1tAzPs46hgVgS8nBLqQaaVd.jpg');
imgs.push('http://image.tmdb.org/t/p/original/hSOk7AQU7uJKSSBzAWt8pVnr0Yc.jpg');
imgs.push('http://image.tmdb.org/t/p/original/pxYJEkw1bNc1fsNEQZO1guuTh2i.jpg');
imgs.push('http://image.tmdb.org/t/p/original/ydiFEJNFsYQZryrmsJknRDlWTnj.jpg');
imgs.push('http://image.tmdb.org/t/p/original/bgXYUoqAabvwLK3XcAd7St0NZFx.jpg');
imgs.push('http://image.tmdb.org/t/p/original/aIsxd8BPZdOeFrgtJ34KffpN50Y.jpg');
imgs.push('http://image.tmdb.org/t/p/original/fZGYJ6nYWEtgiAwpISrN8BAiaGS.jpg');
imgs.push('http://image.tmdb.org/t/p/original/8wiADxMHK8jPPB4oKTqe6TQqWwA.jpg');
imgs.push('http://image.tmdb.org/t/p/original/5vGNKdhSpLLfAKR06lUQdxEWCR7.jpg');
imgs.push('http://image.tmdb.org/t/p/original/thvh9wky8qjKmGxwffHAH3En1l4.jpg');
imgs.push('http://image.tmdb.org/t/p/original/cBJXy4WSIeq0eAfFyqgbocWxCAS.jpg');
imgs.push('http://image.tmdb.org/t/p/original/l6Krz4HVu91Ahc7htYukoOmHNJS.jpg');
imgs.push('http://image.tmdb.org/t/p/original/swr6sHanAqSJHwZCFuqMbtmgmNl.jpg');
imgs.push('http://image.tmdb.org/t/p/original/GXmfNopUdTeah8FdWUf1kc8k6p.jpg');
imgs.push('http://image.tmdb.org/t/p/original/9yWm98n6vtTb1pjIGUI4XwezzHv.jpg');
imgs.push('http://image.tmdb.org/t/p/original/qWPp9IV9cVM9xF58Pi1FevkUzak.jpg');
imgs.push('http://image.tmdb.org/t/p/original/1V8NpxqGWapJriksHKOWwD7MLcT.jpg');
imgs.push('http://image.tmdb.org/t/p/original/xzxyGU86rjzNG2VAL6ZsTvB7G2T.jpg');
imgs.push('http://image.tmdb.org/t/p/original/5epr6MjaPhLEdkB5wEIZWlpvfSE.jpg');
imgs.push('http://image.tmdb.org/t/p/original/tQW4t4EnepMkeEtT8NawoOfC4GU.jpg');
imgs.push('http://image.tmdb.org/t/p/original/tLjxFW2wVwhAp8r1XMSofpXT3H2.jpg');
imgs.push('http://image.tmdb.org/t/p/original/rd7yUWjOK8XMeC9sXZTfe7ktFVO.jpg');
imgs.push('http://image.tmdb.org/t/p/original/8kmykDxEK2kPhDjiPryuBFjj0MB.jpg');
imgs.push('http://image.tmdb.org/t/p/original/pe5eIFEeW9TOrJajLw4GoPXoLgl.jpg');
imgs.push('http://image.tmdb.org/t/p/original/uhtSLpyIsjchjmZFVfb9XKUjRjA.jpg');
imgs.push('http://image.tmdb.org/t/p/original/efrww9Wgh6Y11g3Ze6WmSjOkVcy.jpg');
imgs.push('http://image.tmdb.org/t/p/original/fly7Hgt9PMHSuJqBxNVoIDbyxaW.jpg');
imgs.push('http://image.tmdb.org/t/p/original/hfQ9BEJNO7SZa3pv7chj2aiIWRJ.jpg');
imgs.push('http://image.tmdb.org/t/p/original/6ACovuOwM6PaiMxPtnrcCktFPju.jpg');
imgs.push('http://image.tmdb.org/t/p/original/uRU0pKM5ShNwpzETHtDUbUu2ws1.jpg');
imgs.push('http://image.tmdb.org/t/p/original/3ToFdE6YMmjo13Ba1Edp6eViD07.jpg');
imgs.push('http://image.tmdb.org/t/p/original/iDGtbmkcW1vVZu0hFoFgpYW9TtV.jpg');
imgs.push('http://image.tmdb.org/t/p/original/2FjtJ3RGSP3XHCTHSxrbvlCl6Ac.jpg');
imgs.push('http://image.tmdb.org/t/p/original/xlvednZb3xGbSEoULEtdNZW9DAI.jpg');
imgs.push('http://image.tmdb.org/t/p/original/hnu7rEmUXyrRBqlRTd2CzDBUap4.jpg');
imgs.push('http://image.tmdb.org/t/p/original/tEKCxPsjvA5mxx0MFAHELdcdx27.jpg');
imgs.push('http://image.tmdb.org/t/p/original/aRqjOkJcr0RLUaU23uN1v9FXZt7.jpg');
imgs.push('http://image.tmdb.org/t/p/original/ks7SRL5POqZMuKbvCQIEnhA4Gdl.jpg');
imgs.push('http://image.tmdb.org/t/p/original/vL6yYt4hhXliMHgsJKg3ZMEt7sE.jpg');
imgs.push('http://image.tmdb.org/t/p/original/5j6RGD8FFXS0BUKESYs8bzvLqNz.jpg');
imgs.push('http://image.tmdb.org/t/p/original/vbuefEuw5Tdu9h72YzR7jDBNSSS.jpg');
imgs.push('http://image.tmdb.org/t/p/original/yHbIm5xerfdmU4veyKqZlAfinnT.jpg');
imgs.push('http://image.tmdb.org/t/p/original/6qa8XsXVdE9Uc8yFJat0YSUxqwN.jpg');
imgs.push('http://image.tmdb.org/t/p/original/pbElGlpuXscpZUoqHl3J9gDEQGE.jpg');
imgs.push('http://image.tmdb.org/t/p/original/860zV8Ugy8Rpt5kQ0TYvhQi66H4.jpg');
<!DOCTYPE html>
<html>
<head>
<title>Resize test</title>
<script src="./movies.js"></script>
</head>
<body>
<p>Seconds to reisze 100 images: <b id="total">calculating ...</b> seconds</p>
<p>Click on the image to see original image</p>
<table>
<tr>
<td>Resize to width</td><td><input type="text" id="r_width" value="200" /> <button onclick="draw_thumbs('width', document.getElementById('r_width').value)">Go!</button></td>
</tr>
<tr>
<td>Crop to width-height</td><td><input id="r_crop" value="200x200" /> <button onclick="draw_thumbs('crop', document.getElementById('r_crop').value)">Go!</button></td>
</tr>
</table>
<br />
<br />
<div id="target" onload="alert(1)"></div>
<script>
window.r_time = function() {
document.getElementById('total').innerHTML = (new Date() - window.start)/1000
}
window.draw_thumbs = function(schema, size) {
target = document.getElementById('target')
target.innerHTML = ''
window.start = new Date()
for (var i=0; i<100; i++) {
target.innerHTML += '<a href="'+imgs[i]+'"><img onload="r_time()" style="width:200px; -height:300px; border:1px solid #aaa; margin-right:10px; margin-bottom:10px;" src="http://0.0.0.0:9292/resize?'+schema+'='+size+'&image='+imgs[i]+'" /></a>'
}
}
draw_thumbs('crop', 200)
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment