Created
October 24, 2011 00:06
-
-
Save skorianez/1308103 to your computer and use it in GitHub Desktop.
JCrop + Carrierwave
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# https://github.com/gzigzigzeo/carrierwave-meta | |
# Integrating CarrierWave with JCrop | |
# Let implement the behavior like at this demo: deepliquid.com/projects/Jcrop/demos.php?demo=thumbnail | |
# The uploader: | |
class CropUploader < SobakaUploader | |
include CarrierWave::Meta | |
# Crop source is a source image converted from original which could be bigger than source area (left image in the example). | |
version :crop_source do | |
process :resize_to_fit => [300, 300] | |
process :store_meta | |
# This is the cropped version of parent image. Let crop to 50x50 square. | |
version :crop do | |
process :crop_to => [50, 50] | |
end | |
end | |
# Defines crop area dimensions. | |
# This should be assigned before #store! and #cache! called and should be saved in the model's instance. | |
# Otherwise cropped image would be lost after #recreate_versions! is called. | |
# If crop area dimensions are'nt assigned, uploader calculates crop area dimensions inside the | |
# parent image and creates the default image. | |
model_delegate_attribute :x | |
model_delegate_attribute :y | |
model_delegate_attribute :w | |
model_delegate_attribute :h | |
# Crop processor | |
def crop_to(width, height) | |
# Checks that crop area is defined and crop should be done. | |
if ((crop_args[0] == crop_args[2]) || (crop_args[1] == crop_args[3])) | |
# If not creates default image and saves it's dimensions. | |
resize_to_fill_and_save_dimensions(width, height) | |
else | |
args = crop_args + [width, height] | |
crop_and_resize(*args) | |
end | |
end | |
def crop_and_resize(x, y, width, height, new_width, new_height) | |
manipulate! do |img| | |
cropped_img = img.crop(x, y, width, height) | |
new_img = cropped_img.resize_to_fill(new_width, new_height) | |
destroy_image(cropped_img) | |
destroy_image(img) | |
new_img | |
end | |
end | |
# Creates the default crop image. | |
# Here the original crop area dimensions are restored and assigned to the model's instance. | |
def resize_to_fill_and_save_dimensions(new_width, new_height) | |
manipulate! do |img| | |
width, height = img.columns, img.rows | |
new_img = img.resize_to_fill(new_width, new_height) | |
destroy_image(img) | |
w_ratio = width.to_f / new_width.to_f | |
h_ratio = height.to_f / new_height.to_f | |
ratio = [w_ratio, h_ratio].min | |
self.w = ratio * new_width | |
self.h = ratio * new_height | |
self.x = (width - self.w) / 2 | |
self.y = (height - self.h) / 2 | |
new_img | |
end | |
end | |
private | |
def crop_args | |
%w(x y w h).map { |accessor| send(accessor).to_i } | |
end | |
end | |
# Post should have :crop_source_version_x, :crop_source_version_y, :crop_source_version_h, :crop_source_version_w columns | |
class Post < ActiveRecord::Base | |
mount_uploader CropUploader, :image | |
end | |
# Let's upload an image | |
post = Post.new | |
post.image = params[:image] # Let the uploaded file is 800x600 JPEG | |
post.save! | |
post.image.crop_source.width # 300 | |
post.image.crop_source.height # 200 | |
post.image.crop_source.crop.width # 50 | |
post.image.crop_source.crop.height # 50 | |
# Default crop area coordinates within the limits of big image dimensions: square at the center of an image | |
post.image.crop_source.crop.x # 50 | |
post.image.crop_source.crop.y # 50 | |
post.image.crop_source.crop.w # 200 | |
post.image.crop_source.crop.h # 200 | |
# Let user change the crop area with JCrop script. Pass new crop area parameters to the model. | |
post.crop_source_crop_x = 100 | |
post.crop_source_crop_y = 100 | |
post.crop_source_crop_w = 100 | |
post.crop_source_crop_h = 100 | |
post.save! # Crop image is reprocessed | |
post.image.crop_source.crop.width # 50 | |
post.image.crop_source.crop.height # 50 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
CarrierWave::MiniMagick shouldn't be included in this example?