Class: Neofiles::Image
Overview
Special case of Neofiles::File for dealing with images.
Alongside usual file things: 1) stores width & height of image; 2) does some useful manipulations, like EXIF rotation & cleaning; 3) stores no_wm [no_watermark] flag to tell Neofiles::ImagesController not to put watermark automatically.
Defined Under Namespace
Classes: ImageFormatException
Constant Summary
Constants inherited from File
Instance Attribute Summary
Attributes inherited from File
Instance Method Summary collapse
-
#admin_compact_view(template) ⇒ Object
Overrides parent “admin views” with square 100x100 thumbnail.
-
#dimensions ⇒ Object
Return array with width & height decorated with singleton function to_s returning ‘WxH’ string.
-
#no_wm=(value) ⇒ Object
Set no_wm from HTML form (value is a string ‘1’/‘0’).
-
#save_file ⇒ Object
Do useful stuf before calling parent #save from Neofiles::File.
Methods inherited from File
#base64, binary_for, #bytes, chunking, class_by_content_type, class_by_file_name, class_by_file_object, cleanname, #data, #data_uri, #each, extract_basename, extract_content_type, #nullify_unpersisted_file, reading, rewind, #slice, #unpersisted_file?
Instance Method Details
#admin_compact_view(template) ⇒ Object
Overrides parent “admin views” with square 100x100 thumbnail.
112 113 114 115 116 |
# File 'app/models/neofiles/image.rb', line 112 def admin_compact_view(template) # _path instead of _url to keep admin session cookie which is lost when changing domains url_method = Neofiles.is_admin?(template) ? :neofiles_image_nowm_path : :neofiles_image_path template.neofiles_img_link self, 100, 100, {}, target: '_blank', href: template.send(url_method, self) end |
#dimensions ⇒ Object
Return array with width & height decorated with singleton function to_s returning ‘WxH’ string.
103 104 105 106 107 108 109 |
# File 'app/models/neofiles/image.rb', line 103 def dimensions dim = [width, height] def dim.to_s join 'x' end dim end |
#no_wm=(value) ⇒ Object
Set no_wm from HTML form (value is a string ‘1’/‘0’).
119 120 121 |
# File 'app/models/neofiles/image.rb', line 119 def no_wm=(value) write_attribute :no_wm, value.is_a?(String) ? value == '1' : value end |
#save_file ⇒ Object
Do useful stuf before calling parent #save from Neofiles::File.
-
Rotates image if orientation is present in EXIF and Rails.application.config.neofiles.image_rotate_exif == true.
-
Cleans all EXIF data if Rails.application.config.neofiles.image_clean_exif == true.
-
Crops input to some max size in case enormous 10000x10000 px input is provided (fill Rails.application.config.neofiles.image_max_dimensions with [w, h] or w, height: h or wh)
Uses MiniMagick and works only with JPEG, PNG & GIF formats.
TODO: переделать работу с файлом. Сейчас МиниМеджик копирует входной файл в темповую директорию, после его обработки я делаю еще одну темповую копию и ее тут же читаю - неэкономно! Это сделано потому, что МиниМеджик не дает мне инфу о своем темповом файле, если бы давал дескриптор или его имя, я бы его читал. Но я могу только считать содержимое или попросить МиниМеджик скопировать его, что и происходит. Вариант: построить класс StringIO, который может читать строку блоками, и натравить на image.to_blob (этот метод прочитает содержимое темпового файла), и уже этот поток нарезать на чанки. Еще вариант: тупо пройтись по строке image.to_blob в цикле.
32 33 34 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 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'app/models/neofiles/image.rb', line 32 def save_file return if @file.nil? begin image = ::MiniMagick::Image.read @file rescue ::MiniMagick::Invalid raise ImageFormatException.new I18n.t('neofiles.mini_magick_error') end # check input forma type = image[:format].downcase raise ImageFormatException.new I18n.t('neofiles.unsupported_image_type', type: type.upcase) unless type.in? %w{ jpeg gif png } # rotate from exit dimensions = image[:dimensions] if Rails.application.config.neofiles.image_rotate_exif case image['exif:orientation'] when '3' image.rotate '180' when '6' image.rotate '90' dimensions.reverse! when '8' image.rotate '-90' dimensions.reverse! end end # clean exif image.strip if Rails.application.config.neofiles.image_clean_exif # crop to max size if crop_dimensions = Rails.application.config.neofiles.image_max_dimensions if crop_dimensions.is_a? Hash crop_dimensions = crop_dimensions.values_at :width, :height elsif !(crop_dimensions.is_a? Array) crop_dimensions = [crop_dimensions, crop_dimensions] end image.resize crop_dimensions.join('x').concat('>') dimensions = image[:dimensions] end # fill in some fields self.width = dimensions[0] self.height = dimensions[1] self.content_type = "image/#{type}" begin # make temp image tempfile = Tempfile.new 'neofiles-image' tempfile.binmode image.write tempfile # substitute file to be saved with the temp @file = tempfile # call super #save super ensure tempfile.close tempfile.unlink end ensure image.try :destroy! #delete mini_magick tempfile end |