Class: Image
- Includes:
- Zena::Use::Upload::UploadedFile
- Defined in:
- app/models/image.rb
Overview
An Image is a Document with a file that we can view inline. An image can be displayed in various formats (defined through modes). These modes are defined for each Site through Iformat. Default modes:
'tiny' => { :size=>:force, :width=>16, :height=>16, },
'mini' => { :size=>:force, :width=>32, :ratio=>1.0, },
'pv' => { :size=>:force, :width=>70, :ratio=>1.0 },
'med' => { :size=>:limit, :width=>280, :ratio=>2/3.0 },
'top' => { :size=>:force, :width=>280, :ratio=>2.0/3.0, :gravity=>Magick::NorthGravity},
'mid' => { :size=>:force, :width=>280, :ratio=>2.0/3.0, :gravity=>Magick::CenterGravity},
'low' => { :size=>:force, :width=>280, :ratio=>2.0/3.0, :gravity=>Magick::SouthGravity},
'edit' => { :size=>:limit, :width=>400, :height=>400 },
'std' => { :size=>:limit, :width=>600, :ratio=>2/3.0 },
'full' => { :size=>:keep },
To display an image with one of those formats, you use the ‘img_tag’ helper :
img_tag(@node, :mode=>'med')
For more information on img_tag, have a look at ApplicationHelper#img_tag.
An image can be croped by changing the ‘crop’ pseudo attribute (see Image#crop= ) :
@node.update_attributes(:crop=>{:x=>10, :y=>10, :width=>30, :height=>60})
Version
The version class used by images is the ImageVersion.
Storage
File data is managed by the Document Attachment. This class is responsible for storing the file and retrieving the data.
Properties
These properties are added to Images :
size(format):: file size for the image at the given format
width(format):: image width in pixel for the given format
height(format):: image height in pixel for the given format
links
Default links for Image are:
- icon_for
-
become the unique ‘icon’ for the linked node.
Example on how to use ‘icon’ with ruby:
@node.icon.img_tag('pv') <= display the node's icon with the 'pv' (preview) format.
Same example in a zafu template:
<r:img src='icon' format='pv'/>
or to create a link to the article using the icon:
<r:img src='icon' format='pv' href='self'/>
Constant Summary
Constants inherited from Node
Constants included from Zena::Use::Workflow
Zena::Use::Workflow::WORKFLOW_ATTRIBUTES
Class Method Summary collapse
- .accept_content_type?(content_type) ⇒ Boolean
-
.change_to_classes_for_form ⇒ Object
Class list to which this class can change to.
Instance Method Summary collapse
- #can_crop?(format) ⇒ Boolean
-
#crop=(format) ⇒ Object
Crop the image using the ‘crop’ hash with the top left corner position (:x, :y) and the width and height (:width, :heigt).
-
#cropped_file(format) ⇒ Object
Return a cropped image using the ‘crop’ hash with the top left corner position (:x, :y) and the width and height (:width, :heigt).
-
#exif ⇒ Object
Return the Exchangeable Image Format (Exif).
-
#file(format = nil) ⇒ Object
Return a file with the data for the given format.
-
#file=(file) ⇒ Object
Set content file, will refuse to accept the file if it is not an image.
-
#filesize(format = nil) ⇒ Object
Return the size of the image for the given format (see Image for information on format).
-
#height(format = nil) ⇒ Object
Return the height in pixels for an image at the given format.
-
#update_attributes(attributes) ⇒ Object
Updaging image attributes and propreties.
-
#width(format = nil) ⇒ Object
Return the width in pixels for an image at the given format.
Methods inherited from Document
accept_content_type_change?, document_class_from_content_type, #filename, #filepath, #image?, new, o_new, #size, version_class
Methods inherited from Node
#all_relations, allowed_change_to_classes, #archive, #asset_path, #author, author_proc, auto_create_discussion, #can_auto_create_discussion?, #can_comment?, class_for_relation, classes_for_form, #comments, #comments_count, #content_lang, create_node, create_nodes_from_folder, create_or_update_node, #data, #discussion, #dyn_attribute_keys, #empty?, #export_keys, #export_to_folder, extract_archive, find_by_parent_title_and_kpath, find_by_title, find_by_zip, find_node_by_pseudo, #find_node_by_pseudo, get_attributes_from_yaml, get_class, #get_discussion_id, #get_project_id, get_role, #get_section_id, inherited, inspect, #klass, #klass=, #klass_changed?, #kpath_match?, kpath_match?, kpaths_for_form, load_unhandled_children, #m_author, #m_author=, #m_text, #m_text=, #m_title, #m_title=, make_schema, #merge_multi_errors, native_classes, native_classes_by_name, new, #new_child, new_node, #o_skin, #o_user, #parent, #parent_zip, #parent_zip=, #parse_assets, #parse_keys, plural_relation?, #project, #project_zip, #real_project, #real_section, #reload, #replace_attributes_in_values, #safe_method_type, #safe_send, #section, #section_zip, #skin, #skin_zip, #skin_zip=, #sweep_cache, #to_yaml, transform_attributes, translate_pseudo_id, #unparse_assets, #update_attributes_with_transformation, #user, #user_zip, #v_number, #vclass, #versions_with_secure, #virtual_class, #virtual_class=, #vkind_of?, zafu_attribute, #zafu_versions
Methods included from Zena::Use::Search::NodeClassMethods
#match_query, #search_index, #search_records, #search_text
Methods included from Zena::Acts::Secure
#secure_scope, #secure_write_scope, #visitor=
Methods included from Zena::Acts::Secure::SecureResult
#construct_id_map, #secure_result
Methods included from Zena::Acts::SecureNode
Methods included from Zena::Use::QueryNode::ModelMethods
#db_attr, #find, included, #safe_first, #start_node_zip
Methods included from Zena::Use::ScopeIndex::ModelMethods
included, #rebuild_index_with_scope_index!, #rebuild_scope_index!, #scope_index, scope_index_proc
Methods included from Zena::Use::Relations::ModelMethods
#add_link, #all_relations, included, #l_comment, #l_comment=, #l_date, #l_date=, #l_status, #l_status=, #link_id, #link_id=, #linked_node, #linked_node=, #rel, #rel=, #rel_attributes=, #relation_alias, #relation_links, #relation_proxy, #relation_proxy_from_link, #relations_for_form, #remove_link
Methods included from Zena::Use::Fulltext::ModelMethods
included, #rebuild_index_for_version_with_fulltext
Methods included from Zena::Use::PropEval::ModelMethods
included, #merge_prop_eval, #need_set__id, #rebuild_index_for_version_with_prop_eval, #set__id
Methods included from Zena::Use::VersionHash::ModelMethods
#rebuild_vhash, #version, #version_id, #vhash, #visible_versions
Methods included from Zena::Acts::Serializable::ModelMethods
#all_link_ids, #default_serialization_options, #export_ids, #export_properties, included, #to_xml
Methods included from Zena::Use::Ancestry::ModelMethods
#ancestors, #basepath, #fullpath_as_title, included, #is_ancestor?, #pseudo_id, #short_path, #z_ancestors
Methods included from Zena::Use::Workflow
#after_all, #apply, #apply_with_callbacks, #can_apply?, #can_destroy_version?, #can_edit?, #can_propose?, #can_publish?, #can_refuse?, #can_remove?, #can_unpublish?, #can_update?, #destroy_version, #edit_content!, #get_publish_from, included, #propose, #publish, #redit, #refuse, #remove, #set_current_transition, #traductions, #transition_allowed?, #transition_for, #unpublish, #would_change_original?
Methods included from Zena::Use::NestedAttributesAlias::ModelMethods
#attributes_with_nested_alias=, included, #nested_model_names_for_alias, #resolve_attributes_alias
Methods included from Zena::Acts::Enrollable::ModelMethods
#assigned_roles, #has_role?, included, #zafu_possible_roles
Methods included from Zena::Use::FieldIndex::ModelMethods
included, #property_field_index
Methods included from Zena::Use::MLIndex::ModelMethods
included, #index_reader, #rebuild_index_for_version, #rebuild_index_with_multi_lingual!
Methods included from Zena::Use::Kpath::InstanceMethods
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class Zena::Use::Relations::ModelMethods
Class Method Details
.accept_content_type?(content_type) ⇒ Boolean
73 74 75 |
# File 'app/models/image.rb', line 73 def accept_content_type?(content_type) Zena::Use::ImageBuilder.image_content_type?(content_type) end |
.change_to_classes_for_form ⇒ Object
Class list to which this class can change to
78 79 80 |
# File 'app/models/image.rb', line 78 def change_to_classes_for_form classes_for_form(:class => 'Image') end |
Instance Method Details
#can_crop?(format) ⇒ Boolean
161 162 163 164 165 166 |
# File 'app/models/image.rb', line 161 def can_crop?(format) x, y, w, h = [format['x'].to_i, 0].max, [format['y'].to_i, 0].max, [format['w'].to_i, width].min, [format['h'].to_i, height].min (format['max_value'] && (format['max_value'].to_f * (format['max_unit'] == 'Mb' ? 1024 : 1) * 1024) < prop['size']) || (format['format'] && format['format'] != prop['ext']) || ((x < width && y < height && w > 0 && h > 0) && !(x==0 && y==0 && w == width && h == height)) end |
#crop=(format) ⇒ Object
Crop the image using the ‘crop’ hash with the top left corner position (:x, :y) and the width and height (:width, :heigt). Example:
@node.crop = {:x=>10, :y=>10, :width=>30, :height=>60}
Be carefull as this method changes the current file. So you should make a backup version before croping the image (the popup editor displays a warning).
171 172 173 174 175 176 177 178 179 |
# File 'app/models/image.rb', line 171 def crop=(format) if can_crop?(format) # do crop if file = self.cropped_file(format) # crop can return nil, check first. self.file = file end end end |
#cropped_file(format) ⇒ Object
Return a cropped image using the ‘crop’ hash with the top left corner position (:x, :y) and the width and height (:width, :heigt).
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'app/models/image.rb', line 183 def cropped_file(format) original = format['original'] || @loaded_file || self.file x, y, w, h = format['x'].to_f, format['y'].to_f, format['w'].to_f, format['h'].to_f new_type = format['format'] ? Zena::EXT_TO_TYPE[format['format'].downcase][0] : nil max = format['max_value'].to_f * (format['max_unit'] == 'Mb' ? 1024 : 1) * 1024 # crop image img = Zena::Use::ImageBuilder.new(:file => original) img.crop!(x, y, w, h) if x && y && w && h img.format = format['format'] if new_type && new_type != content_type img.max_filesize = max if format['max_value'] && max file = Tempfile.new(filename) File.open(file.path, "wb") { |f| f.syswrite(img.read) } ctype = Zena::EXT_TO_TYPE[img.format.downcase][0] fname = "#{filename}.#{Zena::TYPE_TO_EXT[ctype][0]}" uploaded_file(file, filename, ctype) end |
#exif ⇒ Object
Return the Exchangeable Image Format (Exif).
110 111 112 |
# File 'app/models/image.rb', line 110 def exif prop['exif'] || ExifData.new({}) end |
#file(format = nil) ⇒ Object
Return a file with the data for the given format. It is the receiver’s responsability to close the file.
149 150 151 152 153 154 155 156 157 158 159 |
# File 'app/models/image.rb', line 149 def file(format=nil) if format.nil? || format.size == :keep super() else if File.exist?(self.filepath(format)) || make_image(format) File.new(self.filepath(format)) else nil end end end |
#file=(file) ⇒ Object
Set content file, will refuse to accept the file if it is not an image.
136 137 138 139 140 141 142 143 144 145 146 |
# File 'app/models/image.rb', line 136 def file=(file) new_file = super if self.class.accept_content_type?(new_file.content_type) @new_image = new_file img = image_with_format(nil) prop['width' ] = img.width prop['height'] = img.height prop['exif'] = img.exif rescue nil end end |
#filesize(format = nil) ⇒ Object
Return the size of the image for the given format (see Image for information on format).
115 116 117 |
# File 'app/models/image.rb', line 115 def filesize(format=nil) version.filesize(format) end |
#height(format = nil) ⇒ Object
Return the height in pixels for an image at the given format.
97 98 99 100 101 102 103 104 105 106 107 |
# File 'app/models/image.rb', line 97 def height(format=nil) if format.nil? || format.size == :keep prop['height'] else if img = image_with_format(format) img.height else nil end end end |
#update_attributes(attributes) ⇒ Object
Updaging image attributes and propreties. Accept also :file and :crop keys.
120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'app/models/image.rb', line 120 def update_attributes(attributes) attributes.stringify_keys! # If file and crop attributes are both present when updating, make sure to run file= before crop=. if attributes['file'] && attributes['crop'] file = attributes.delete('file') crop = attributes.delete('crop') super(attributes) self.file = file self.crop = crop save else super end end |
#width(format = nil) ⇒ Object
Return the width in pixels for an image at the given format.
84 85 86 87 88 89 90 91 92 93 94 |
# File 'app/models/image.rb', line 84 def width(format=nil) if format.nil? || format.size == :keep prop['width'] else if img = image_with_format(format) img.width else nil end end end |