I've been at this for some time now. I"m using cloudinary to upload photos and am trying to implement a cropping feature using jcrop on a photo create action. After I implemented cloudinary I followed railscasts #182 on Jcrop. I think I'm having problems getting the new cropped parameters (x,y,w,h) back to the uploader before the image is saved.
Update: I'm not even getting the values put into the f.text_fields. When I move the cropper around, there should be new values right? Here's a pic of what it looks like with empty fields:
Also when I submit the photo, now I'm getting conflicting transformation on crop fit!=crop
Here's my code...
image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
#include Sprockets::Helpers::RailsHelper
#include Sprockets::Helpers::IsolatedHelper
include Cloudinary::CarrierWave
process :tags => ["profile pic"]
process :convert => "jpg"
version :thumbnail
process :crop
eager
resize_to_fill(150, 150)
cloudinary_transformation :quality => 80
end
# For more options, see
# http://cloudinary.com/documentation/rails_integration#carrierwave
def crop
if model.crop_x.present?
resize_to_limit(400, 400)
manipulate! do |img|
x = model.crop_x.to_i
y = model.crop_y.to_i
w = model.crop_w.to_i
h = model.crop_h.to_i
img.crop!(x, y, w, h)
end
end
end
photos.js.coffee
update = (coords) ->
$("#crop_x").val coords.x
$("#crop_y").val coords.y
$("#crop_w").val coords.w
$("#crop_h").val coords.h
$(document).ready ->
$(".cloudinary-fileupload").fileupload(
dropZone: "#dropzone"
start: (e) ->
$(".status").text "Starting upload..."
progress: (e, data) ->
$(".status").text "Uploading... " + Math.round((data.loaded * 100.0) / data.total) + "%"
fail: (e, data) ->
$(".status").text "Upload failed"
).off("cloudinarydone").on "cloudinarydone", (e, data) ->
$("#photo_bytes").val data.result.bytes
$(".status").text ""
$(".preview").html($.cloudinary.image(data.result.public_id,
format: data.result.format
width: 400
height: 400
crop: "fit"
id: "jcrop_target"
)).css height = "400"
$("#jcrop_target").Jcrop
aspectRatio: 1
setSelect: [100, 0, 200, 200]
onSelect: @update
onChange: @update
photo.rb (I have set params.permit for crop_x,y,w,h in the controller)
class Photo < ActiveRecord::Base
belongs_to :master
belongs_to :dog
mount_uploader :image, ImageUploader
validates_presence_of :image
attr_accessor :crop_x, :crop_y, :crop_w, :crop_h
before_create :crop_image
def crop_image
image.recreate_versions! if crop_x.present?
end
end
photo/new.html.erb
<div id="dropzone">
<h1>Change Profile Photo.</h1>
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-10 col-sm-offset-1 col-md-8 col-md-offset-2">
<div id="direct_upload">
<p>Select the upload button or drag and drop an image.</p>
<% if params[:photo_option] == "dog_photo" %>
<% url = master_dog_photos_path %>
<% else %>
<% url = master_photos_path %>
<% end %>
<%= form_for(@photo, :url => url, role: "form") do |f| %>
<!--<div class="form_line">
<%= f.label :title, "Title:" %>
<div class="form_controls">
<%= f.text_field :title %>
</div>
</div>-->
<div class="form_line form-group">
<%= f.label :image, "Image:" %>
<div class="form-group">
<div class="upload_button_holder">
<%= link_to "Upload", "#", class: "btn btn-primary btn-lg upload_button" %>
<%= f.cl_image_upload(:image) %>
</div>
<span class="status"></span>
</div>
</div>
<div class="form-group">
<div class="form_controls">
<div class="preview"></div>
</div>
</div>
<%= f.text_field :crop_x, id: "crop_x"%>
<%= f.text_field :crop_y, id: "crop_y"%>
<%= f.text_field :crop_w, id: "crop_w"%>
<%= f.text_field :crop_h, id: "crop_h"%>
<div class="form-group">
<div class="form_controls">
<%= f.submit "Submit Photo", class: "btn btn-lg btn-success" %>
<% if @error %><span class="error"><%= @error %></span><% end %>
</div>
</div>
<%= f.hidden_field :bytes %>
<%= hidden_field_tag :direct, params[:direct] %>
<% end %>
</div>
<% if params[:photo_option] == "dog_photo" %>
<% link_to "Back to House", master_path(@master) %>
<% else %>
<a href="<%= edit_master_registration_path %>">Back to Master edit.</a>
<% end %>
</div>
</div>
</div>
</div>
<!-- Configure Cloudinary jQuery plugin -->
<%= cloudinary_js_config %>
You can have a look at the following link for the information about Custom coordinates based cropping with Carrierwave: http://cloudinary.com/documentation/rails_carrierwave#custom_coordinates_based_cropping
Ok I solved it by doing the following... took the @ off of the update callbacks and that made the fields get updated with the cropping parameters (bad syntax on my part). Then I persistantly stored the cropping values in the model and got rid of the image.revisions! callback and then put the following code in my uploader:
class ImageUploader < CarrierWave::Uploader::Base
#include Sprockets::Helpers::RailsHelper
#include Sprockets::Helpers::IsolatedHelper
include Cloudinary::CarrierWave
process :tags => ["profile pic"]
process :convert => "jpg"
version :thumbnail do
cloudinary_transformation :transformation => [
{:width => 400, :height => 400, :crop => :limit}]
process :custom_crop
end
def custom_crop
return :x => model.crop_x, :y => model.crop_y,
:width => model.crop_w, :height => model.crop_h, :crop => :crop
end
end
followed by this in my view:
<%= image_tag(@dog.photos.last.image.thumbnail.url, :width => 150, :height => 150, :crop => :fill, class: "img-circle center") %>
来源:https://stackoverflow.com/questions/21401445/using-jcrop-with-cloudinary-through-rails-4-to-crop-before-creating-image