Attachment_fu model With Custom Filename, Square Cropping.
이번 작업을 하면서 필요했던 부분.
Attachment_fu에서 저장되는 파일 명 변경과 함께, 특정 이미지를 골라서 정해준 위치에 맞게 Cropping을 하는 기능이 필요했다. Cropping 관련 메소드는 Kropper에서 빌려옴. ^^
class ArticleImage < ActiveRecord::Base
belongs_to :article
@@thumbs = {
:large => '180x180!',
:medium => '120x120!',
:small => '90x90!'
}
has_attachment :content_type => :image,
:storage => :file_system,
:max_size => 20.megabytes,
:path_prefix => "public/images/#{table_name}",
:resize_to => '600x400>',
:processor => "Rmagick",
:thumbnails => {
:large => '180x180!',
:medium => '120x120!',
:small => '90x90!'
}
validates_as_attachment
# Customizing Filename.
def full_filename(thumbnail = nil)
file_system_path = (thumbnail ? thumbnail_class : self).attachment_options[:path_prefix].to_s
@thumb = self.thumbnail unless (@thumb = thumbnail)
asset = self.parent_id.nil? ? self.id : self.parent_id
File.join(RAILS_ROOT, file_system_path, *partitioned_path(thumbnail_name_for(@thumb, asset)))
end
# Filename Customizing Method
def thumbnail_name_for(thumbnail = nil, asset = nil)
suffix = "_#{thumbnail}" unless thumbnail.blank?
extension = filename.scan(/\.\w+$/)
return "#{asset}#{suffix}#{extension}"
end
# crops the attached image according to the passed left, top, width, and height params.
# if resize_to_stencil is true, the image is resized to stencil_w x stencil_h.
# after cropping and resizing, the resulting image is saved back to disk.
# any thumbnail image the image may have is automatically updated.
def crop!( options = {} )
# setup the default params
options[:crop_left] ||= 0
options[:crop_top] ||= 0
options[:crop_width] ||= 100
options[:crop_height] ||= 100
options[:stencil_width] ||= 100
options[:stencil_height] ||= 100
options[:resize_to_stencil] ||= false
# passed params could be strings, so convert them to ints/booleans
crop_l = options[:crop_left].to_i
crop_t = options[:crop_top].to_i
crop_w = options[:crop_width].to_i
crop_h = options[:crop_height].to_i
stencil_w = options[:stencil_width].to_i
stencil_h = options[:stencil_height].to_i
resize_to_stencil = false if (options[:resize_to_stencil] == false) || (options[:resize_to_stencil] == "false")
resize_to_stencil = true if (options[:resize_to_stencil] == true) || (options[:resize_to_stencil] == "true")
# call the appropriate crop method for the image processor we're using with attachment_fu
if self.class.include?(Technoweenie::AttachmentFu::Processors::RmagickProcessor)
crop_with_rmagick! crop_l, crop_t, crop_w, crop_h, stencil_w, stencil_h, resize_to_stencil
else
raise "You're using an unsupported image processor."
end
end
private
def crop_with_rmagick!(crop_l, crop_t, crop_w, crop_h, stencil_w, stencil_h, resize_to_stencil)
# create a temporary cropped version of our image
cropped_img = nil
self.with_image do |img|
if (crop_w <= 0) || (crop_h <= 0) || (crop_l + crop_w <= 0) || (crop_t + crop_h <= 0) || (crop_l >= img.base_columns) || (crop_t >= img.base_rows)
raise InvalidCropRect
end
cropped_img = img.crop(crop_l, crop_t, crop_w, crop_h, true )
cropped_img.resize!(stencil_w, stencil_h) if resize_to_stencil
end
# write the cropped image to a temp file, which attachment_fu will use
# to replace the existing image file (and thumbnail, if any) on save
self.temp_path = write_to_temp_file(cropped_img.to_blob)
@@thumbs.each { |suffix, size| create_or_update_thumbnail(self.temp_path, suffix, *size) }
#callback_with_args :after_resize, cropped_img
end
endAttachment_fu model Spec for RSpec
OKJSP에 남겨놨던 글을 좀 자세하게 블로그에 정리.
환경은 다음과 같다.
- Ruby on Rails 2.0.2
- RSpec 1.1.3
- Spec::Rails 1.1.3
- Attachment_fu 2008-03-17
사실 원래 목적은, 이번 플젝을 진행하면서 소소하게 BDD를 적용해 보다가, Plugin으로 처리되는 파일 업로드를 위한 Spec 파일을 만드는것.
역시나 언제나 처럼 구글에는 개발할 때 필요한 거의 모든게 있다. ^^
require File.dirname(__FILE__) + '/../spec_helper'
describe ArticleImage do
before(:all) do
SAMPLE_FILE = RAILS_ROOT + '/tmp/rails.png'
@article_image = ArticleImage.new
@article_image.uploaded_data =
ActionController::TestUploadedFile.new(SAMPLE_FILE, 'image/png')
@article_image.send :process_attachment
end
it "should be valid" do
@article_image.should be_valid
end
end