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
Node::Caster, Node::VERSION_ATTRIBUTES
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).
-
#fix_sizes(w, h) ⇒ Object
This is called if the image’s width and/or height is nil and image builder could compute the size.
-
#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, #auth, #auth=, #auth_user, #auth_users, #author, author_proc, auto_create_discussion, #can_auto_create_discussion?, #can_comment?, cast_to_class, 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, #login_info, #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, #rcast, #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_eval, #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::Dates::ModelMethods
Methods included from Zena::Use::Dates::Common
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, #v_public?, #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, #auto_publish?, #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, #save_without_clone, #set_current_transition, #traductions, #transition_allowed?, #transition_for, #unpublish, #update_attributes_without_clone, #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
165 166 167 168 169 170 |
# File 'app/models/image.rb', line 165 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).
175 176 177 178 179 180 181 182 183 |
# File 'app/models/image.rb', line 175 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).
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
# File 'app/models/image.rb', line 187 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).
114 115 116 |
# File 'app/models/image.rb', line 114 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.
153 154 155 156 157 158 159 160 161 162 163 |
# File 'app/models/image.rb', line 153 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.
140 141 142 143 144 145 146 147 148 149 150 |
# File 'app/models/image.rb', line 140 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).
119 120 121 |
# File 'app/models/image.rb', line 119 def filesize(format=nil) version.filesize(format) end |
#fix_sizes(w, h) ⇒ Object
This is called if the image’s width and/or height is nil and image builder could compute the size.
209 210 211 212 213 |
# File 'app/models/image.rb', line 209 def fix_sizes(w, h) prop['width'] = w prop['height'] = h Zena::Db.set_attribute(version, 'properties', encode_properties(@properties)) end |
#height(format = nil) ⇒ Object
Return the height in pixels for an image at the given format.
99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'app/models/image.rb', line 99 def height(format=nil) if format.nil? || format[:size] == :keep prop['height'] elsif format[:size] == :force format[: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.
124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'app/models/image.rb', line 124 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 95 96 |
# File 'app/models/image.rb', line 84 def width(format=nil) if format.nil? || format[:size] == :keep prop['width'] elsif format[:size] == :force format[:width] else if img = image_with_format(format) img.width else nil end end end |