通过回形针从URL保存图像


Answers:


154

这是一个简单的方法:

require "open-uri"

class User < ActiveRecord::Base
  has_attached_file :picture

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

然后简单地:

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

7
如果你需要使用update_attributes重命名picture_from_urlpicture_url=(value)的例子。
Daniel Rikowski

3
这可能是不安全的,因为用户可以拨打电话user.picture_from_url('/etc/password')。不过,在大多数情况下这可能很好。
David Tuite 2013年

1
为了安全起见,您应该将URI的方案列入白名单,并将私有主机列入黑名单
John Douthat 2014年

3
请参阅下面的答案以获得更好的解决方案。
geekazoid 2014年

6
使用open(url),文件名是不准确的,如open-uri20150106-10034-lpd5fm.代替ef3a601e_ef3d008b_ef3d0f7e.jpg
Joshua Pinter 2015年

196

在Paperclip 3.1.4中,它变得更加简单。

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

这比open(url)略好。因为使用open(url),您将获得“ stringio.txt”作为文件名。通过上面的内容,您将基于URL获得文件的正确名称。即

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

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

3
paperclip Wiki:github.com/thoughtbot/paperclip/wiki/… 我已成功在控制台中运行它,该应用程序在heroku中。
Donny Kurnia

3
仅供参考,对于S3网址,我仍然得到application/octet_streamcontent_type
约书亚·品特

5
如果弃用后仍在使用回形针,则可能还需要确保已加载URI IO加载器:Paperclip :: UriAdapter.register(在配置中,或者如果需要的话,临时通过控制台)
Msencenb

该方法是正确的,但在最新版本中,sintax已更改!在下面查看我的答案=> stackoverflow.com/a/56039191/3182171
Diego D


16

在我对解析的URI使用“打开”之前,它对我不起作用。一旦我添加“打开”,它就起作用了!

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

我的回形针版本是4.2.1

在打开之前,它不是正确的内容类型,因为它不是文件。它会说image_content_type:“ binary / octet-stream”,即使我用正确的内容类型覆盖它也不起作用。


谢谢你!正是我想念自己的东西。
丹,

如果这样做,您将失去您的期望。您需要在初始值设定项中使用Paperclip :: UriAdapter.register。然后不需要在最后打开.open。见github.com/thoughtbot/paperclip/wiki/…–
ianpetzer

15

首先将带有curbgem 的图像下载到a TempFile,然后简单地分配tempfile对象并保存模型。


2
我看不出这个答案有什么问题,请投赞成票,因为我看到投反对票。
jpemberthy 2011年

这是最高效的答案(到目前为止)。我并不是一个性能极客,但是如果您正在使用大型文件,这的确加起来了。
2013年

3

它可能对您有帮助。这是使用回形针和远程URL中存在的图像的代码。

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

在模型中

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

3

由于这些都是旧答案,因此这里是一个较新的答案:

将图像远程URL添加到数据库中所需的控制器

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

编辑模型

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

*在Rails4中,您必须在Controller中添加attr_accessible。

如果您允许其他人从URL上传图像,请更新您的表单

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

有什么super用?
周星驰

该函数super用于调用原始方法,方法主体的搜索始于包含原始方法的对象的超类
Mini John

2

这是一个硬核方法:

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)

其中Uuid.uuid只是使一些随机ID。


2

进入官方文档的报告在这里https://github.com/thoughtbot/paperclip/wiki/Attachment-downloaded-from-a-URL

无论如何,它似乎没有更新,因为在回形针的最新版本中某些内容已更改,并且此行代码不再有效:

user.picture = URI.parse(url)

它引发一个错误,特别是引发此错误:

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

新的正确语法是这样的:

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

另外,我们需要将这些行添加到config / initializers / paperclip.rb文件中:

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

使用回形针版本5.3.0对其进行了测试,并且可以正常工作。


谢谢-配置文件为我修复了它(Paperclip v6.1.0)
Owlvark
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.