Vakar vienam iš vystomų projektų reikėjo sukurti foto galerijos funkcionalumą. Nieko ypatingo: tiesiog “thumbnail’ai”, kuriuos paspaudus iššoka naujas langas su originalaus dydžio nuotrauka. Kiek panaršius internete sukūriau testinį variantą, kuris rašė dvi bylas: originalą bei thumbnail’ą, tačiau kiek pamąsčius nusprendžiau, jog to paties paveikslo (nors ir skirtingo dydžio) saugojimas bei juo manipuliavimas neatitinka DRY principų =) Tad beliko tik parašyti kodą, kuris dinamiškai formuotu thumbnailą.
Veikimo principas: žemiau pateiktas kodas keliauja į application.rb, ir išbandyti jį galima taip: [jūsų controllerio pavadinimas] / img?src=rails.png
Update: dado1945 prašymu pateikiu sprendimą su thumbnail’ų kešavimų =) (Daugiau apie http kešavimą)
Update2: ištaisiau tikrai kvailą klaidą kai paveiksliukas nekeitė dydžio dėl vienodų matmenų =)
Update3: Rimanto dėka calc_size funkcijos kodas tapo daug gražesnis. Ačiū.
Tikiuosi kažkam padės sutaupyti laiko =)
[ruby]
BASE_SIZE = 200.0
def calc_size(width, height)
ratio = [width, height].max / BASE_SIZE
[width, height].map { |s| s.div ratio }
end
def img
require ‘RMagick’
file = “public/images/#{params[:src]}”
if file and File.exists?(file)
req_last_modified = Time.rfc2822(@request.env[“HTTP_IF_MODIFIED_SINCE”]) rescue nil
last_modified = File.mtime(file)
@response.headers[‘Last-Modified’] = last_modified.rfc2822
if req_last_modified and last_modified < = req_last_modified
render_text '', '304 Not Modified'
else
image = Magick::Image.read(file)[0]
width, height = calc_size(image.columns, image.rows)
image.resize!(width, height)
send_data(image.to_blob, :disposition => ‘inline’, :type => image.mime_type, :filename => file)
end
else
render_text “Image not found!”
end
end
[/ruby]