Carrierwave 作物特定版本

发布于 2024-11-06 11:51:44 字数 680 浏览 0 评论 0原文

我正在研究使用 Carrierwave 和 Jcrop 裁剪图像的能力。它是 Railscasts 第 182 集和第 253 集的组合。我已经进行了裁剪,但它裁剪了原始内容。是否有强制 manupulate! 使用不同的版本?

def crop_image(x,y,w,h)
  manipulate! do |img|
    img.crop(x.to_i, y.to_i, w.to_i, h.to_i)
  end
end

或者有没有办法从模型调用中设置版本?

attr_accessor :crop_x, :crop_y, :crop_w, :crop_h
attr_accessible :description, :image, :crop_x, :crop_y, :crop_w, :crop_h
after_update :reprocess_image, :if => :cropping?

def cropping?
  !crop_x.blank? && !crop_y.blank? && !crop_w.blank? && !crop_h.blank?
end


def reprocess_image
  image.crop_image(crop_x, crop_y, crop_w, crop_h)
end

I am working on the ability to crop images using carrierwave and Jcrop. Its a combination of Railscasts episode 182 and 253. I have cropping working but it crops the original. Is there anyway to force manupulate! to use a different version?

def crop_image(x,y,w,h)
  manipulate! do |img|
    img.crop(x.to_i, y.to_i, w.to_i, h.to_i)
  end
end

or is there a way to set the version from the model call?

attr_accessor :crop_x, :crop_y, :crop_w, :crop_h
attr_accessible :description, :image, :crop_x, :crop_y, :crop_w, :crop_h
after_update :reprocess_image, :if => :cropping?

def cropping?
  !crop_x.blank? && !crop_y.blank? && !crop_w.blank? && !crop_h.blank?
end


def reprocess_image
  image.crop_image(crop_x, crop_y, crop_w, crop_h)
end

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

季末如歌 2024-11-13 11:51:44

在 Railscast 中,Ryan 的解决方案是通过查找大版本与原始版本之间的比率来转换坐标以与原始图像配合使用。通过遵循相同的逻辑,我能够让它与 Carrierwave 和 jCrop 一起使用。有趣的是 Carrierwave 不存储图像的尺寸。我能够从这篇文章中破解一些内容: http://code.dblock.org/ShowPost.aspx?Id =194

这是我的解决方案。

user.rb

class User < ActiveRecord::Base

  attr_accessor :password, :crop_x, :crop_y, :crop_h, :crop_w
  after_update :reprocess_profile, :if => :cropping?

  mount_uploader :profile, ProfileUploader

  def cropping?
    !crop_x.blank? && !crop_y.blank? && !crop_w.blank? && !crop_h.blank?
  end

  def profile_geometry
    img = Magick::Image::read(self.profile.current_path).first
    @geometry = {:width => img.columns, :height => img.rows }
  end

  private

  def reprocess_profile
    self.profile.recreate_versions!
  end

end

account_controller.rb

class AccountController < ApplicationController

  def crop
    @account = current_user
  end

  def crop_update
    @account = current_user
    @account.crop_x = params[:account]["crop_x"]
    @account.crop_y = params[:account]["crop_y"]
    @account.crop_h = params[:account]["crop_h"]
    @account.crop_w = params[:account]["crop_w"]
    @account.save
    redirect_to account_path
  end

end

profile_uploader.rbcrop.html.erb

class ProfileUploader < CarrierWave::Uploader::Base

  def extension_white_list
    %w(jpg jpeg gif png)
  end

  version :large do
    process :resize_to_fit => [500, 500]
  end

  version :thumb do
    process :manualcrop
    process :resize_to_fill => [100, 100]
  end

  def manualcrop
    return unless model.cropping?
    manipulate! do |img| 
      img = img.crop(model.crop_x.to_i,model.crop_y.to_i,model.crop_h.to_i,model.crop_w.to_i) 
    end 
  end

end

<% content_for :head do %>
<%= stylesheet_link_tag "jquery.Jcrop" %>
<%= javascript_include_tag "jquery.Jcrop.min" %>
<script type="text/javascript" charset="utf-8">
$(function() {
  $('#cropbox').Jcrop({
    onChange: update_crop,
    onSelect: update_crop,
    setSelect: [0, 0, 500, 500],
    aspectRatio: 1
  });
});

function update_crop(coords) {
    var rx = 100/coords.w;
    var ry = 100/coords.h;
    var lw = $('#cropbox').width();
    var lh = $('#cropbox').height();
    var ratio = <%= @account.profile_geometry[:width] %> / lw ;

  $('#preview').css({
    width: Math.round(rx * lw) + 'px',
    height: Math.round(ry * lh) + 'px',
    marginLeft: '-' + Math.round(rx * coords.x) + 'px',
    marginTop: '-' + Math.round(ry * coords.y) + 'px'
  });
  $("#crop_x").val(Math.round(coords.x * ratio));
  $("#crop_y").val(Math.round(coords.y * ratio));
  $("#crop_w").val(Math.round(coords.w * ratio));
  $("#crop_h").val(Math.round(coords.h * ratio));
}
</script>
<% end %>

<%= image_tag @account.profile_url(:large), :id => "cropbox" %>

<h3>Preview</h3>
<div class="preview">
    <%= image_tag @account.profile_url(:large), :id => "preview" %>
</div>

<%= form_for @account, :as => :account, :url => { :action => "crop_update" } do |f| %>
    <% for attribute in [:crop_x, :crop_y, :crop_h, :crop_w] %>
        <%= f.hidden_field attribute, :id => attribute %>
    <% end %>
    <p><%= f.submit "Crop" %></p>
<% end %>

style.css

.preview {
    width:100px;
    height:100px;
    overflow:hidden;
}

In the railscast, Ryan's solution was to convert the coords to work with the original image by finding the ratio between the large version and the original version. I was able to get it to work with Carrierwave and jCrop by following the same logic. Interesting enough Carrierwave does not store the dimensions of the images. I was able to hack together something from this post: http://code.dblock.org/ShowPost.aspx?Id=194.

Here is my solution.

user.rb

class User < ActiveRecord::Base

  attr_accessor :password, :crop_x, :crop_y, :crop_h, :crop_w
  after_update :reprocess_profile, :if => :cropping?

  mount_uploader :profile, ProfileUploader

  def cropping?
    !crop_x.blank? && !crop_y.blank? && !crop_w.blank? && !crop_h.blank?
  end

  def profile_geometry
    img = Magick::Image::read(self.profile.current_path).first
    @geometry = {:width => img.columns, :height => img.rows }
  end

  private

  def reprocess_profile
    self.profile.recreate_versions!
  end

end

account_controller.rb

class AccountController < ApplicationController

  def crop
    @account = current_user
  end

  def crop_update
    @account = current_user
    @account.crop_x = params[:account]["crop_x"]
    @account.crop_y = params[:account]["crop_y"]
    @account.crop_h = params[:account]["crop_h"]
    @account.crop_w = params[:account]["crop_w"]
    @account.save
    redirect_to account_path
  end

end

profile_uploader.rb

class ProfileUploader < CarrierWave::Uploader::Base

  def extension_white_list
    %w(jpg jpeg gif png)
  end

  version :large do
    process :resize_to_fit => [500, 500]
  end

  version :thumb do
    process :manualcrop
    process :resize_to_fill => [100, 100]
  end

  def manualcrop
    return unless model.cropping?
    manipulate! do |img| 
      img = img.crop(model.crop_x.to_i,model.crop_y.to_i,model.crop_h.to_i,model.crop_w.to_i) 
    end 
  end

end

crop.html.erb

<% content_for :head do %>
<%= stylesheet_link_tag "jquery.Jcrop" %>
<%= javascript_include_tag "jquery.Jcrop.min" %>
<script type="text/javascript" charset="utf-8">
$(function() {
  $('#cropbox').Jcrop({
    onChange: update_crop,
    onSelect: update_crop,
    setSelect: [0, 0, 500, 500],
    aspectRatio: 1
  });
});

function update_crop(coords) {
    var rx = 100/coords.w;
    var ry = 100/coords.h;
    var lw = $('#cropbox').width();
    var lh = $('#cropbox').height();
    var ratio = <%= @account.profile_geometry[:width] %> / lw ;

  $('#preview').css({
    width: Math.round(rx * lw) + 'px',
    height: Math.round(ry * lh) + 'px',
    marginLeft: '-' + Math.round(rx * coords.x) + 'px',
    marginTop: '-' + Math.round(ry * coords.y) + 'px'
  });
  $("#crop_x").val(Math.round(coords.x * ratio));
  $("#crop_y").val(Math.round(coords.y * ratio));
  $("#crop_w").val(Math.round(coords.w * ratio));
  $("#crop_h").val(Math.round(coords.h * ratio));
}
</script>
<% end %>

<%= image_tag @account.profile_url(:large), :id => "cropbox" %>

<h3>Preview</h3>
<div class="preview">
    <%= image_tag @account.profile_url(:large), :id => "preview" %>
</div>

<%= form_for @account, :as => :account, :url => { :action => "crop_update" } do |f| %>
    <% for attribute in [:crop_x, :crop_y, :crop_h, :crop_w] %>
        <%= f.hidden_field attribute, :id => attribute %>
    <% end %>
    <p><%= f.submit "Crop" %></p>
<% end %>

style.css

.preview {
    width:100px;
    height:100px;
    overflow:hidden;
}
回忆凄美了谁 2024-11-13 11:51:44

如果我正确理解问题,更简单的方法是将 trueSize 选项发送到 Jcrop。

<% geo = @item.image_geometry %>
$('#cropbox').Jcrop({boxWidth:656,boxHeight:350,onChange:update_crop,onSelect: update_crop,aspectRatio:656/350,trueSize:[<%= "#{geo[0]}, #{geo[1]}"%>]});

If I correctly understand the problem more simple way is to send trueSize option to the Jcrop.

<% geo = @item.image_geometry %>
$('#cropbox').Jcrop({boxWidth:656,boxHeight:350,onChange:update_crop,onSelect: update_crop,aspectRatio:656/350,trueSize:[<%= "#{geo[0]}, #{geo[1]}"%>]});
初懵 2024-11-13 11:51:44

Ryan 刚刚更新了 Railscasts #182,它现在使用 CarrierWave

http://railscasts.com/episodes/ 182-裁剪图像-修订

Ryan just updated railscasts #182, it uses CarrierWave now

http://railscasts.com/episodes/182-cropping-images-revised

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文