Skip to content

Instantly share code, notes, and snippets.

@skorianez
Created October 24, 2011 00:06
Show Gist options
  • Star 26 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save skorianez/1308103 to your computer and use it in GitHub Desktop.
Save skorianez/1308103 to your computer and use it in GitHub Desktop.
JCrop + Carrierwave
# 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
@hugodias
Copy link

CarrierWave::MiniMagick shouldn't be included in this example?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment