Module: CamaleonCms::UploaderImageProcessing

Included in:
RuntimeUploaderConcern, UploaderHelper
Defined in:
lib/camaleon_cms/uploader_image_processing.rb

Overview

Image transformation shared by the two uploader entry points, CamaleonCms::RuntimeUploaderConcern and CamaleonCms::UploaderHelper, so cropping and resizing behave identically whichever one a caller included.

Constant Summary collapse

SVG_EXT_PATTERN =

Terminal .svg extension, any case. The upload pipeline preserves the client's extension case (logo.SVG is stored verbatim), so every site renaming an SVG-derived artifact to .jpg must match case-insensitively or uppercase uploads keep their SVG name and format. Anchored so the rename never touches an .svg occurring mid-path.

/\.svg\z/i

Instance Method Summary collapse

Instance Method Details

#cama_crop_image(file_path, w = nil, h = nil, w_offset = 0, h_offset = 0, resize = false, replace = true) ⇒ Object

crop and image and saved as imagename_crop.ext file: file path w: new width h: new height w_offset: left offset w_offset: top offset resize: true/false (true => resize the image to this dimension) (false => crop the image with this dimension) replace: Boolean (replace current image or create another file)



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/camaleon_cms/uploader_image_processing.rb', line 39

def cama_crop_image(file_path, w = nil, h = nil, w_offset = 0, h_offset = 0, resize = false, replace = true)
  force = w.present? && h.present? && !w.include?('?') && !h.include?('?') ? '!' : ''
  img = MiniMagick::Image.open(file_path)
  w = clamp_to_image_dimension(w, img[:width])
  h = clamp_to_image_dimension(h, img[:height])
  data = { img: img, w: w, h: h, w_offset: w_offset, h_offset: h_offset, resize: resize, replace: replace }
  hooks_run('before_crop_image', data)
  data[:img].combine_options do |i|
    i.resize("#{w.presence}x#{h.presence}#{force}") if data[:resize]
    i.crop "#{w.presence}x#{h.presence}+#{w_offset}+#{h_offset}#{force}" unless data[:resize]
  end

  ext = File.extname(file_path)
  res = data[:replace] ? file_path : file_path.gsub(ext, "_crop#{ext}")
  data[:img].write res
  res
end

#cama_resize_and_crop(file, w, h, settings = {}) ⇒ Object

resize and crop a file SVGs are converted to JPEGs for editing Params:

file: (String) File path
w: (Integer) width
h: (Integer) height
settings:
gravity: (Sym, default :north_east)
  Crop position: :north_west, :north, :north_east, :east, :south_east, :south, :south_west, :west, :center
overwrite: (Boolean, default true) true for overwrite current image with resized resolutions,
  false: create other file called with prefix "crop_"
output_name: (String, default prefixd name with crop_), permit to define the output name of the
  thumbnail if overwrite = true

Return: (String) file path where saved this cropped sample: cama_resize_and_crop(my_file, 200, 200, :north_east, overwrite: false)



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/camaleon_cms/uploader_image_processing.rb', line 72

def cama_resize_and_crop(file, w, h, settings = {})
  settings = { gravity: :north_east, overwrite: true, output_name: +'' }.merge!(settings)
  img = MiniMagick::Image.open(file)
  if file.match?(SVG_EXT_PATTERN)
    img.format 'jpg'
    file.sub!(SVG_EXT_PATTERN, '.jpg')
    settings[:output_name]&.sub!(SVG_EXT_PATTERN, '.jpg')
  end
  w = clamp_to_image_dimension(w, img[:width])
  h = clamp_to_image_dimension(h, img[:height])
  w_original = img[:width].to_f
  h_original = img[:height].to_f
  w = w.to_i if w.present?
  h = h.to_i if h.present?

  # check proportions
  if w_original * h < h_original * w
    op_resize = "#{w.to_i}x"
    w_result = w
    h_result = (h_original * w / w_original)
  else
    op_resize = "x#{h.to_i}"
    w_result = (w_original * h / h_original)
    h_result = h
  end

  w_offset, h_offset = cama_crop_offsets_by_gravity(settings[:gravity], [w_result, h_result], [w, h])
  data = { img: img, w: w, h: h, w_offset: w_offset, h_offset: h_offset, op_resize: op_resize, settings: settings }
  hooks_run('before_resize_crop', data)
  data[:img].combine_options do |i|
    i.resize(data[:op_resize])
    i.gravity(settings[:gravity])
    i.crop "#{data[:w].to_i}x#{data[:h].to_i}+#{data[:w_offset]}+#{data[:h_offset]}!"
  end

  if settings[:overwrite]
    data[:img].write(file.sub(SVG_EXT_PATTERN, '.jpg'))
  elsif settings[:output_name].present?
    data[:img].write(file = File.join(File.dirname(file), settings[:output_name]).to_s)
  else
    data[:img].write(file = uploader_verify_name(
      File.join(File.dirname(file), "crop_#{File.basename(file.sub(SVG_EXT_PATTERN, '.jpg'))}")
    ))
  end
  file
end

#cama_resize_upload(image_path, dimension, args = {}) ⇒ Object

resize image if the format is correct return resized file path



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/camaleon_cms/uploader_image_processing.rb', line 121

def cama_resize_upload(image_path, dimension, args = {})
  if cama_uploader.class.validate_file_format(image_path, 'image') && dimension.present?
    dim_parts = dimension.split('x')
    r = { file: image_path, w: dim_parts[0], h: dim_parts[1], w_offset: 0, h_offset: 0,
          resize: !dim_parts[2] || dim_parts[2] == 'resize',
          replace: true, gravity: :north_east }.merge!(args)
    hooks_run('on_uploader_resize', r)
    image_path = if r[:w].present? && r[:h].present?
                   cama_resize_and_crop(r[:file], r[:w], r[:h], { overwrite: r[:replace], gravity: r[:gravity] })
                 else
                   cama_crop_image(r[:file], r[:w], r[:h], r[:w_offset], r[:h_offset], r[:resize], r[:replace])
                 end
  end
  image_path
end

#cama_uploader_generate_thumbnail(uploaded_io, key, thumb_size = nil, remove_source = false) ⇒ Object

generate thumbnail of a existent image key: key of the current file the thumbnail will be saved in my_images/my_img.png => my_images/thumb/my_img.png



18
19
20
21
22
23
24
25
26
27
# File 'lib/camaleon_cms/uploader_image_processing.rb', line 18

def cama_uploader_generate_thumbnail(uploaded_io, key, thumb_size = nil, remove_source = false)
  w = thumb_size.present? ? thumb_size.split('x')[0] : cama_uploader.thumb[:w]
  h = thumb_size.present? ? thumb_size.split('x')[1] : cama_uploader.thumb[:h]
  uploaded_io = File.open(uploaded_io) if uploaded_io.is_a?(String)
  path_thumb = cama_resize_and_crop(uploaded_io.path, w, h)
  thumb = cama_uploader.add_file(path_thumb, cama_uploader.version_path(key).sub(SVG_EXT_PATTERN, '.jpg'),
                                 is_thumb: true, same_name: true)
  FileUtils.rm_f(path_thumb) if remove_source
  thumb
end