Lưu hình ảnh từ URL bằng kẹp giấy


Câu trả lời:


154

Đây là một cách đơn giản:

require "open-uri"

class User < ActiveRecord::Base
  has_attached_file :picture

  def picture_from_url(url)
    self.picture = open(url)
  end
end

Sau đó chỉ cần:

user.picture_from_url "http://www.google.com/images/logos/ps_logo2.png"

7
Nếu bạn cần sử dụng update_attributesđổi tên picture_from_urlthành picture_url=(value)chẳng hạn.
Daniel Rikowski

3
Điều này có khả năng không an toàn vì người dùng có thể gọi user.picture_from_url('/etc/password'). Nó có thể ổn trong hầu hết các tình huống.
David Tuite.

1
Để bảo mật, bạn nên lập danh sách trắng chương trình của URI và host riêng danh sách đen
John Douthat

3
Xem câu trả lời bên dưới để có giải pháp tốt hơn.
geekazoid

6
Sử dụng open(url), tên tệp không chính xác, ví dụ: open-uri20150106-10034-lpd5fm.thay vì ef3a601e_ef3d008b_ef3d0f7e.jpg.
Joshua Pinter

196

Trong Paperclip 3.1.4, nó thậm chí còn trở nên đơn giản hơn.

def picture_from_url(url)
  self.picture = URI.parse(url)
end

Điều này tốt hơn một chút so với mở (url). Bởi vì với mở (url), bạn sẽ lấy "stringio.txt" làm tên tệp. Với những điều trên, bạn sẽ nhận được tên riêng của tệp dựa trên URL. I E

self.picture = URI.parse("http://something.com/blah/avatar.png")

self.picture_file_name    # => "avatar.png"
self.picture_content_type # => "image/png"

3
Từ wiki kẹp giấy: github.com/thoughtbot/paperclip/wiki/… Tôi đã chạy thành công nó trong bảng điều khiển, ứng dụng có trong heroku.
Donny Kurnia

3
FYI, cho url S3 tôi vẫn nhận được application/octet_streamcontent_type.
Joshua Pinter

5
Nếu bạn vẫn đang sử dụng kẹp giấy sau khi nó không được dùng nữa, bạn cũng có thể cần đảm bảo trình nạp URI IO được tải: Paperclip :: UriAdapter.register (trong cấu hình hoặc tạm thời thông qua bảng điều khiển nếu đó là tất cả những gì bạn cần)
Msencenb

Cách tiếp cận là đúng nhưng trong phiên bản cuối cùng, sintax đã bị thay đổi! Kiểm tra câu trả lời của tôi bên dưới => stackoverflow.com/a/56039191/3182171
Diego D

Bạn cần thêm mục nhập trong trình khởi tạo github.com/thoughtbot/paperclip/wiki/…
ianpetzer

16

Nó không hoạt động với tôi cho đến khi tôi sử dụng "open" cho URI được phân tích cú pháp. một khi tôi thêm "mở" nó đã hoạt động!

def picture_from_url(url)
  self.picture = URI.parse(url).open
end

Phiên bản kẹp giấy của tôi là 4.2.1

Trước khi mở, nó sẽ không phát hiện đúng loại nội dung vì nó không phải là tệp. Nó sẽ nói rằng image_content_type: "binary / octet-stream" và ngay cả khi tôi ghi đè nó bằng loại nội dung phù hợp thì nó cũng không hoạt động.


Cảm ơn vì điều đó! Chính xác những gì tôi đã thiếu bản thân mình.
Dan

Bạn sẽ mất quyền miễn trừ nếu bạn làm điều này. Bạn cần Paperclip :: UriAdapter.register trong trình khởi tạo .. sau đó bạn không cần .open ở cuối. Xem github.com/thoughtbot/paperclip/wiki/…
ianpetzer

15

Đầu tiên tải hình ảnh có curbgem vào a TempFile, sau đó chỉ cần gán đối tượng tempfile và lưu mô hình của bạn.


2
Tôi không thấy câu trả lời này có gì sai, hãy biểu quyết nó vì tôi đang thấy một cuộc bỏ phiếu thấp.
jpemberthy

Đây là câu trả lời hiệu quả nhất ( cho đến nay ). Tôi không thực sự là một người đam mê hiệu suất, nhưng điều này thực sự bổ sung nếu bạn đang làm việc với các tệp lớn.
Chip

3

Nó có thể hữu ích cho bạn. Đây là mã sử dụng kẹp giấy và hình ảnh có trong URL từ xa.

require 'rubygems'
require 'open-uri'
require 'paperclip'
model.update_attribute(:photo,open(website_vehicle.image_url))

Trong mô hình

class Model < ActiveRecord::Base
  has_attached_file :photo, :styles => { :small => "150x150>", :thumb => "75x75>" }
end

3

Vì đó là những câu trả lời cũ, đây là câu trả lời mới hơn:

Thêm URL từ xa hình ảnh vào Bộ điều khiển mong muốn của bạn trong Cơ sở dữ liệu

$ rails generate migration AddImageRemoteUrlToYour_Controller image_remote_url:string
$ rake db:migrate

Chỉnh sửa mô hình của bạn

attr_accessible :description, :image, :image_remote_url
.
.
.
def image_remote_url=(url_value)
  self.image = URI.parse(url_value) unless url_value.blank?
  super
end

* Trong Rails4, bạn phải thêm attr_accessible trong Controller.

Cập nhật biểu mẫu của bạn, nếu bạn cho phép người khác tải lên Hình ảnh từ URL

<%= f.input :image_remote_url, label: "Enter a URL" %>

là những gì supercho?
Terence Chow

Các chức năng superđược sử dụng để gọi phương thức ban đầu, tìm kiếm các phương pháp khởi động cơ thể trong lớp siêu của đối tượng đã được phát hiện có chứa các phương pháp ban đầu
Mini John

2

Đây là một phương pháp khó:

original_url = url.gsub(/\?.*$/, '')
filename = original_url.gsub(/^.*\//, '')
extension = File.extname(filename)

temp_images = Magick::Image.from_blob open(url).read
temp_images[0].write(url = "/tmp/#{Uuid.uuid}#{extension}")

self.file = File.open(url)

trong đó Uuid.uuid chỉ tạo một số ID ngẫu nhiên.


2

Tài liệu chính thức được báo cáo tại đây https://github.com/thoughtbot/paperclip/wiki/Attachment-downloaded-from-a-URL

Dù sao thì nó có vẻ như không được cập nhật, bởi vì trong phiên bản cuối cùng của kẹp giấy, một số thứ đã thay đổi và dòng mã này không còn giá trị nữa:

user.picture = URI.parse(url)

Nó gây ra lỗi, cụ thể là lỗi này được nêu ra:

Paperclip::AdapterRegistry::NoHandlerError: No handler found for #<URI:: ...

Cú pháp đúng mới là cú pháp sau:

url = "https://www.example.com/photo.jpeg"
user.picture = Paperclip.io_adapters.for(URI.parse(url).to_s, { hash_digest: Digest::MD5 })

Ngoài ra, chúng ta cần thêm các dòng này vào tệp config / initializers / paperclip.rb :

Paperclip::DataUriAdapter.register
Paperclip::HttpUrlProxyAdapter.register

Đã kiểm tra điều này với phiên bản kẹp giấy 5.3.0và nó hoạt động.


Cảm ơn cho điều này - những thứ cấu hình cố định nó cho tôi (Kẹp giấy phiên bản 6.1.0)
Owlvark
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.