Class: Neofiles::ImagesController

Inherits:
ActionController::Metal
  • Object
show all
Includes:
ActionController::DataStreaming, ActionController::Helpers, Devise::Controllers::Helpers, NotFound
Defined in:
app/controllers/neofiles/images_controller.rb

Overview

Special controller for serving images from the database via single action #show.

Defined Under Namespace

Classes: NotAdminException

Constant Summary collapse

CROP_MAX_WIDTH =
Rails.application.config.neofiles.image_max_crop_width
CROP_MAX_HEIGHT =
Rails.application.config.neofiles.image_max_crop_height

Instance Method Summary collapse

Instance Method Details

#showObject

Request parameters:

format  - resize image to no more than that size, example: '100x200'
crop    - if '1' and params[:format] is present, then cut image sides if its aspect ratio differs from
          params[:format] (otherwise image aspect ration will be preserved)
quality - output quality, integer from 1 till 100 for JPEG input, default is 75
          for PNG input any value less than 75 triggers lossless compression using pngquant library
nowm    - force returned image to not contain watermark - user must be admin or 403 Forbidden response is returned
          @see #admin_or_die (also this removes the default quality to let admins download image originals)

Maximum allowed format dimensions are set via Rails.application.config.neofiles.image_max_crop_width/height.

Watermark is added automatically from /assets/images/neofiles/watermark.png or via proc Rails.application.config.neofiles.watermarker if present.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'app/controllers/neofiles/images_controller.rb', line 35

def show
  # get image
  image_file = Neofiles::Image.find params[:id]

  # prepare headers
  data = image_file.data
  options = {
      filename: CGI::escape(image_file.filename),
      type: image_file.content_type || 'image/jpeg',
      disposition: 'inline',
  }
  quality = [[Neofiles::quality_requested(params), 100].min, 1].max if Neofiles::quality_requested?(params)
  quality ||= 75 unless nowm?(image_file)

  image = MiniMagick::Image.read(data)

  if params[:format].present?
    width, height = params[:format].split('x').map(&:to_i)
    raise Mongoid::Errors::DocumentNotFound unless width.between?(1, CROP_MAX_WIDTH) and height.between?(1, CROP_MAX_HEIGHT)
  end

  crop_requested            = Neofiles.crop_requested? params
  resizing                  = width && height
  need_resize_without_crop  = resizing && (image_file.width > width || image_file.height > height)

  image.combine_options('convert') do |convert|
    resize_image convert, width, height, crop_requested, need_resize_without_crop if resizing

    unless nowm?(image_file)
      wm_width, wm_height = resizing ? Neofiles::resized_image_dimensions(image_file, width, height, params) : [image_file.width, image_file.height]
      add_watermark convert, image, wm_width, wm_height if wm_width && wm_height
    end

    compress_image convert, quality if quality || resizing
  end

  # use pngquant when quality is less than 75
  ::PngQuantizator::Image.new(image.path).quantize! if options[:type] == 'image/png' && quality && quality < 75

  data = image.to_blob

  # stream image headers & bytes
  send_file_headers! options
  headers['Content-Length'] = data.length.to_s
  self.status = 200
  self.response_body = data

rescue NotAdminException
  self.response_body = I18n.t 'neofiles.403_access_denied'
  self.content_type = 'text/plain; charset=utf-8'
  self.status = 403
ensure
  image.try :destroy! #delete mini_magick tempfile
end