Module: Fleximage::Model::InstanceMethods
- Defined in:
- lib/fleximage/model.rb
Overview
Provides methods that every model instance that acts_as_fleximage needs.
Instance Method Summary collapse
-
#delete_image_file ⇒ Object
Delete the image file for this record.
-
#directory_path ⇒ Object
Returns the path to the master image file for this record.
-
#extension ⇒ Object
Returns original format of the image if the image_format column exists otherwise returns the globally set format.
-
#file_path ⇒ Object
Returns the path to the master image file for this record.
-
#has_image? ⇒ Boolean
Return true if this record has an image.
- #has_saved_image? ⇒ Boolean
- #image_file ⇒ Object
-
#image_file=(file) ⇒ Object
Sets the image file for this record to an uploaded file.
-
#image_file_base64=(data) ⇒ Object
Set the image for this record by reading in a file as a base64 encoded string.
-
#image_file_string=(data) ⇒ Object
Set the image for this record by reading in file data as a string.
-
#image_file_temp=(file_name) ⇒ Object
Sets the uploaded image to the name of a file in Rails.root/tmp that was just uploaded.
-
#image_file_url ⇒ Object
Return the @image_file_url that was previously assigned.
-
#image_file_url=(file_url) ⇒ Object
Assign the image via a URL, which will make the plugin go and fetch the image at the provided URL.
-
#load_image ⇒ Object
Load the image from disk/DB, or return the cached and potentially processed output image.
-
#operate(&block) ⇒ Object
Call from a .flexi view template.
-
#operate!(&block) ⇒ Object
Self destructive operate.
-
#output_image(options = {}) ⇒ Object
Convert the current output image to a jpg, and return it in binary form.
- #url_format ⇒ Object
-
#validate_image ⇒ Object
Execute image presence and validity validations.
Instance Method Details
#delete_image_file ⇒ Object
Delete the image file for this record. This is automatically ran after this record gets destroyed, but you can call it manually if you want to remove the image from the record.
552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 |
# File 'lib/fleximage/model.rb', line 552 def delete_image_file return unless self.class.has_store? if self.class.db_store? update_attribute :image_file_data, nil unless frozen? elsif self.class.s3_store? AWS::S3::S3Object.delete "#{id}.#{self.class.image_storage_format}", self.class.s3_bucket else File.delete(file_path) if File.exists?(file_path) end clear_magic_attributes self end |
#directory_path ⇒ Object
Returns the path to the master image file for this record.
@some_image.directory_path #=> /var/www/myapp/uploaded_images
If this model has a created_at field, it will use a directory structure based on the creation date, to prevent hitting the OS imposed limit on the number files in a directory.
@some_image.directory_path #=> /var/www/myapp/uploaded_images/2008/3/30
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 |
# File 'lib/fleximage/model.rb', line 271 def directory_path directory = self.class.image_directory raise 'No image directory was defined, cannot generate path' unless directory # base directory directory = "#{Rails.root}/#{directory}" unless /^\// =~ directory # specific creation date based directory suffix. creation = self[:created_at] || self[:created_on] if self.class.use_creation_date_based_directories && creation "#{directory}/#{creation.year}/#{creation.month}/#{creation.day}" else directory end end |
#extension ⇒ Object
Returns original format of the image if the image_format column exists otherwise returns the globally set format.
296 297 298 299 300 301 302 303 304 305 306 307 |
# File 'lib/fleximage/model.rb', line 296 def extension if self.respond_to?( :image_format) case image_format when "JPEG" "jpg" else image_format ? image_format.downcase : self.class.image_storage_format end else self.class.image_storage_format end end |
#file_path ⇒ Object
Returns the path to the master image file for this record.
@some_image.file_path #=> /var/www/myapp/uploaded_images/123.png
290 291 292 |
# File 'lib/fleximage/model.rb', line 290 def file_path "#{directory_path}/#{id}.#{extension}" end |
#has_image? ⇒ Boolean
Return true if this record has an image.
451 452 453 |
# File 'lib/fleximage/model.rb', line 451 def has_image? @uploaded_image || @output_image || has_saved_image? end |
#has_saved_image? ⇒ Boolean
455 456 457 458 459 460 461 462 463 |
# File 'lib/fleximage/model.rb', line 455 def has_saved_image? if self.class.db_store? !!image_file_data elsif self.class.s3_store? AWS::S3::S3Object.exists?("#{id}.#{self.class.image_storage_format}", self.class.s3_bucket) elsif self.class.file_store? File.exists?(file_path) end end |
#image_file ⇒ Object
372 373 374 |
# File 'lib/fleximage/model.rb', line 372 def image_file has_image? end |
#image_file=(file) ⇒ Object
Sets the image file for this record to an uploaded file. This can be called directly, or passively like from an ActiveRecord mass assignment.
Rails will automatically call this method for you, in most of the situations you would expect it to.
# via mass assignment, the most common form you'll probably use
Photo.new(params[:photo])
Photo.create(params[:photo])
# via explicit assignment hash
Photo.new(:image_file => params[:photo][:image_file])
Photo.create(:image_file => params[:photo][:image_file])
# Direct Assignment, usually not needed
photo = Photo.new
photo.image_file = params[:photo][:image_file]
# via an association proxy
p = Product.find(1)
p.images.create(params[:photo])
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 |
# File 'lib/fleximage/model.rb', line 335 def image_file=(file) if self.class.image_file_exists(file) file_path = file.is_a?( ActionDispatch::Http::UploadedFile ) ? file.tempfile.path : file.path # Create RMagick Image object from uploaded file if file_path @uploaded_image = Magick::Image.read(file_path).first else @uploaded_image = Magick::Image.from_blob(file.read).first end # Sanitize image data @uploaded_image.colorspace = Magick::RGBColorspace @uploaded_image.density = '72' # Save meta data to database set_magic_attributes(file) # Success, make sure everything is valid @invalid_image = false save_temp_image(file) unless @dont_save_temp end rescue Magick::ImageMagickError => e error_strings = [ 'Improper image header', 'no decode delegate for this image format', 'UnableToOpenBlob', 'Must specify image size' ] if e.to_s =~ /#{error_strings.join('|')}/ @invalid_image = true else raise e end end |
#image_file_base64=(data) ⇒ Object
Set the image for this record by reading in a file as a base64 encoded string.
data = Base64.encode64(File.read('my_image_file.jpg'))
photo = Photo.find(123)
photo.image_file_base64 = data
photo.save
422 423 424 |
# File 'lib/fleximage/model.rb', line 422 def image_file_base64=(data) self.image_file_string = Base64.decode64(data) end |
#image_file_string=(data) ⇒ Object
Set the image for this record by reading in file data as a string.
data = File.read('my_image_file.jpg')
photo = Photo.find(123)
photo.image_file_string = data
photo.save
412 413 414 |
# File 'lib/fleximage/model.rb', line 412 def image_file_string=(data) self.image_file = StringIO.new(data) end |
#image_file_temp=(file_name) ⇒ Object
Sets the uploaded image to the name of a file in Rails.root/tmp that was just uploaded. Use as a hidden field in your forms to keep an uploaded image when validation fails and the form needs to be redisplayed
429 430 431 432 433 434 435 436 437 438 439 440 441 442 |
# File 'lib/fleximage/model.rb', line 429 def image_file_temp=(file_name) if !@uploaded_image && file_name && file_name.present? && file_name !~ %r{\.\./} @image_file_temp = file_name file_path = "#{Rails.root}/tmp/fleximage/#{file_name}" @dont_save_temp = true if File.exists?(file_path) File.open(file_path, 'rb') do |f| self.image_file = f end end @dont_save_temp = false end end |
#image_file_url ⇒ Object
Return the @image_file_url that was previously assigned. This is not saved in the database, and only exists to make forms happy.
446 447 448 |
# File 'lib/fleximage/model.rb', line 446 def image_file_url @image_file_url end |
#image_file_url=(file_url) ⇒ Object
Assign the image via a URL, which will make the plugin go and fetch the image at the provided URL. The image will be stored locally as a master image for that record from then on. This is intended to be used along side the image upload to allow people the choice to upload from their local machine, or pull from the internet.
@photo.image_file_url = 'http://foo.com/bar.jpg'
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 |
# File 'lib/fleximage/model.rb', line 383 def image_file_url=(file_url) @image_file_url = file_url if file_url =~ %r{^(https?|ftp)://} file = open(URI.parse(URI.encode(file_url))) # Force a URL based file to have an original_filename eval <<-CODE def file.original_filename "#{file_url}" end CODE self.image_file = file elsif file_url.empty? # Nothing to process, move along else # invalid URL, raise invalid image validation error @invalid_image = true end end |
#load_image ⇒ Object
Load the image from disk/DB, or return the cached and potentially processed output image.
492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 |
# File 'lib/fleximage/model.rb', line 492 def load_image #:nodoc: @output_image ||= @uploaded_image # Return the current image if we have loaded it already return @output_image if @output_image # Load the image from disk if self.class.db_store? # Load the image from the database column if image_file_data && image_file_data.present? @output_image = Magick::Image.from_blob(image_file_data).first end elsif self.class.s3_store? # Load image from S3 filename = "#{id}.#{self.class.image_storage_format}" bucket = self.class.s3_bucket if AWS::S3::S3Object.exists?(filename, bucket) @output_image = Magick::Image.from_blob(AWS::S3::S3Object.value(filename, bucket)).first end else # Load the image from the disk @output_image = Magick::Image.read(file_path).first end if @output_image @output_image else master_image_not_found end rescue Magick::ImageMagickError => e if e.to_s =~ /unable to open (file|image)/ master_image_not_found else raise e end end |
#operate(&block) ⇒ Object
Call from a .flexi view template. This enables the rendering of operators so that you can transform your image. This is the method that is the foundation of .flexi views. Every view should consist of image manipulation code inside a block passed to this method.
# app/views/photos/thumb.jpg.flexi
@photo.operate do |image|
image.resize '320x240'
end
474 475 476 477 478 479 480 |
# File 'lib/fleximage/model.rb', line 474 def operate(&block) self.tap do proxy = ImageProxy.new(load_image, self) block.call(proxy) @output_image = proxy.image end end |
#operate!(&block) ⇒ Object
Self destructive operate. This will modify the master image for this record with the updated and processed result of the operation AND SAVES THE RECORD
484 485 486 487 488 |
# File 'lib/fleximage/model.rb', line 484 def operate!(&block) operate(&block) self.image_file_string = output_image save end |
#output_image(options = {}) ⇒ Object
Convert the current output image to a jpg, and return it in binary form. options support a :format key that can be :jpg, :gif or :png
536 537 538 539 540 541 542 543 544 545 546 547 548 |
# File 'lib/fleximage/model.rb', line 536 def output_image( = {}) #:nodoc: format = ([:format] || :jpg).to_s.upcase @output_image.format = format @output_image.strip! if format == 'JPG' quality = @jpg_compression_quality || self.class.output_image_jpg_quality @output_image.to_blob { self.quality = quality } else @output_image.to_blob end ensure GC.start end |
#url_format ⇒ Object
309 310 311 |
# File 'lib/fleximage/model.rb', line 309 def url_format extension.to_sym end |
#validate_image ⇒ Object
Execute image presence and validity validations.
569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 |
# File 'lib/fleximage/model.rb', line 569 def validate_image #:nodoc: field_name = (@image_file_url && @image_file_url.present?) ? :image_file_url : :image_file # Could not read the file as an image if @invalid_image errors.add field_name, self.class. # no image uploaded and one is required elsif self.class.require_image && !has_image? errors.add field_name, self.class. # Image does not meet minimum size elsif self.class.validates_image_size && !@uploaded_image.nil? x, y = Fleximage::Operator::Base.size_to_xy(self.class.validates_image_size) if @uploaded_image.columns < x || @uploaded_image.rows < y errors.add field_name, self.class. end end end |