通过回形针从 URL 保存图像

Posted

技术标签:

【中文标题】通过回形针从 URL 保存图像【英文标题】:Save image from URL by paperclip 【发布时间】:2011-05-02 06:32:04 【问题描述】:

请给我建议一种通过 Paperclip 从 URL 中保存图像的方法。

【问题讨论】:

【参考方案1】:

在 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"

【讨论】:

来自回形针wiki:github.com/thoughtbot/paperclip/wiki/…我在控制台成功运行,应用在heroku中。 仅供参考,对于 S3 url,我仍然得到 application/octet_stream 作为 content_type 如果您在弃用后仍在使用回形针,您可能还需要确保加载 URI IO 加载器:Paperclip::UriAdapter.register(在配置中,或者如果仅此而已,则暂时通过控制台你需要) 方法是正确的,但在上一个版本中,sintax 发生了变化!在下面查看我的答案 => ***.com/a/56039191/3182171 你需要在初始化器github.com/thoughtbot/paperclip/wiki/…添加条目【参考方案2】:

这是一个简单的方法:

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"

【讨论】:

如果您需要使用update_attributes,例如将picture_from_url重命名为picture_url=(value) 这可能是不安全的,因为用户可以调用user.picture_from_url('/etc/password')。不过在大多数情况下它可能没问题。 为了安全起见,您应该将 URI 的方案列入白名单并将私有主机列入黑名单 查看下面的答案以获得更好的解决方案。 使用open(url),文件名不准确,例如open-uri20150106-10034-lpd5fm. 而不是 ef3a601e_ef3d008b_ef3d0f7e.jpg【参考方案3】:

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

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

我的回形针版本是 4.2.1

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

【讨论】:

谢谢!正是我自己想念的。 如果你这样做,你会失去你的exension。你需要 Paperclip::UriAdapter.register 在初始化器中。然后你不需要 .open 最后。见github.com/thoughtbot/paperclip/wiki/…【参考方案4】:

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

【讨论】:

我看不出这个答案有什么问题,投票赞成,因为我看到了反对票。 这是最高效的答案 (by far)。我不是一个真正的性能极客,但如果你正在处理大文件,这真的会加起来。【参考方案5】:

这里报入官方文档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) 谢谢,Diego,PaperClip v6.0.0 也很好用【参考方案6】:

它可能对你有帮助。这是使用远程 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

【讨论】:

【参考方案7】:

因为这些都是旧答案,所以这里有一个较新的答案:

将图像远程 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用于调用原方法,方法体的查找从发现包含原方法的对象的超类开始【参考方案8】:

这是一种硬核方法:

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。

【讨论】:

以上是关于通过回形针从 URL 保存图像的主要内容,如果未能解决你的问题,请参考以下文章

将图像从 Android(使用 Android 异步 Http 客户端)上传到 rails 服务器(使用回形针)

Rails:回形针不将图像保存到数据库

仅将处理后的图像保存在回形针中

通过 RestKit 或任何 HTTP 请求上传回形针照片

Rails API 回形针。上传图像将其转换为 base 64 并保存并检索它

上传图片 - Nodejs Paperclip 和 S3