在 Ruby 中,我如何知道托管在 Internet 上的图像文件的扩展名是什么?
In Ruby how can I tell what the extension is to an image file that's hosted on the internet?
我想从网上下载一些图片,但是有些网址没有指定文件扩展名,例如:
http://sportslabs-webproxy.imgix.net/http%3A%2F%2Fkty-platform-prod.silverchalice.co%2Fv3%2Fimages%2Fcontents%2F55bbe945e4b073340d3851fb?fit=clip&h=532&w=800&s=61b00197aca130a83de011484841158e
我打算使用“How do I download a picture using Ruby?”中提到的以下方法来下载文件,但正如我所说,我不确定如何告诉脚本将其保存为什么文件扩展名。
您可以使用 Content-Type
HTTP header。对于您提供的 URL,header 是:
$ curl -I "http://sportslabs-webproxy.imgix.net/http%3A%2F%2Fkty-platform-prod.silverchalice.co%2Fv3%2Fimages%2Fcontents%2F55bbe945e4b073340d3851fb?fit=clip&h=532&w=800&s=61b00197aca130a83de011484841158e"
HTTP/1.1 200 OK
Cache-Control: public,no-transform,max-age=86400,s-maxage=86400
Last-Modified: Mon, 01 Feb 2016 20:08:08 GMT
Content-Length: 35176
Accept-Ranges: bytes
Connection: keep-alive
Content-Type: image/jpeg
...
在这里,您可以看到图像是JPEG。您可以使用 MIME-type 库,例如mime-types for Ruby 根据内容类型确定要使用的扩展名。
绝大多数服务器都会指定Content-Type
header。如果不指定,可以使用Eric的方法从内容推断文件类型。
如果你想坚持使用 open-uri
,你可以使用 content_type
字段来获取 Content-Type
:
require 'open-uri'
url = 'http://sportslabs-webproxy.imgix.net/http%3A%2F%2Fkty-platform-prod.silverchalice.co%2Fv3%2Fimages%2Fcontents%2F55bbe945e4b073340d3851fb?fit=clip&h=532&w=800&s=61b00197aca130a83de011484841158e'
open(url) { |file|
content_type = file.content_type
# Determine extension, copy file to disk, ...
}
调查 ruby-filemagic gem.
例如:
require 'open-uri'
require 'filemagic'
url = 'http://sportslabs-webproxy.imgix.net/http%3A%2F%2Fkty-platform-prod.silverchalice.co%2Fv3%2Fimages%2Fcontents%2F55bbe945e4b073340d3851fb?fit=clip&h=532&w=800&s=61b00197aca130a83de011484841158e'
open('raw_file', 'wb') do |file|
file << open(url).read
end
puts FileMagic.new(FileMagic::MAGIC_MIME).file( 'raw_file' )
# => 'image/jpeg; charset=binary'
更新:要找到保存文件的扩展名,您可以使用 mime-types
content_type = FileMagic.new(FileMagic::MAGIC_MIME).file( 'raw_file' ).split( ';' ).first
require 'mime/types'
puts MIME::Types[content_type].first.extensions.first
# => 'jpeg'
好吧,你有几个选择。您可以做的第一件事是信任 Web 服务器正确识别 Content-Type:
header 中的类型。这是一个示例(需要 mime-types
Rubygem):
require 'open-uri'
require 'mime/types'
url = 'http://sportslabs-webproxy.imgix.net/http%3A%2F%2Fkty-platform-prod.silverchalice.co%2Fv3%2Fimages%2Fcontents%2F55bbe945e4b073340d3851fb?fit=clip&h=532&w=800&s=61b00197aca130a83de011484841158e'
open(url) do |f|
filename = File.basename url
if filename !~ /\./ then
t = MIME::Type[f.content_type]
if t && t.first && t.first.extensions then
filename += ".#{t.first.extensions.first}"
end
end
open(filename, 'w') do |w|
w.write(f.read)
end
end
但是您最好使用 Eric 的解决方案并在下载文件后检查文件以确保它确实如您所想。
轻量级选项是 fastimage gem。下面是示例用法:
require 'fastimage'
FastImage.type("http://stephensykes.com/images/pngimage")
=> :png
我想从网上下载一些图片,但是有些网址没有指定文件扩展名,例如:
http://sportslabs-webproxy.imgix.net/http%3A%2F%2Fkty-platform-prod.silverchalice.co%2Fv3%2Fimages%2Fcontents%2F55bbe945e4b073340d3851fb?fit=clip&h=532&w=800&s=61b00197aca130a83de011484841158e
我打算使用“How do I download a picture using Ruby?”中提到的以下方法来下载文件,但正如我所说,我不确定如何告诉脚本将其保存为什么文件扩展名。
您可以使用 Content-Type
HTTP header。对于您提供的 URL,header 是:
$ curl -I "http://sportslabs-webproxy.imgix.net/http%3A%2F%2Fkty-platform-prod.silverchalice.co%2Fv3%2Fimages%2Fcontents%2F55bbe945e4b073340d3851fb?fit=clip&h=532&w=800&s=61b00197aca130a83de011484841158e"
HTTP/1.1 200 OK
Cache-Control: public,no-transform,max-age=86400,s-maxage=86400
Last-Modified: Mon, 01 Feb 2016 20:08:08 GMT
Content-Length: 35176
Accept-Ranges: bytes
Connection: keep-alive
Content-Type: image/jpeg
...
在这里,您可以看到图像是JPEG。您可以使用 MIME-type 库,例如mime-types for Ruby 根据内容类型确定要使用的扩展名。
绝大多数服务器都会指定Content-Type
header。如果不指定,可以使用Eric的方法从内容推断文件类型。
如果你想坚持使用 open-uri
,你可以使用 content_type
字段来获取 Content-Type
:
require 'open-uri'
url = 'http://sportslabs-webproxy.imgix.net/http%3A%2F%2Fkty-platform-prod.silverchalice.co%2Fv3%2Fimages%2Fcontents%2F55bbe945e4b073340d3851fb?fit=clip&h=532&w=800&s=61b00197aca130a83de011484841158e'
open(url) { |file|
content_type = file.content_type
# Determine extension, copy file to disk, ...
}
调查 ruby-filemagic gem.
例如:
require 'open-uri'
require 'filemagic'
url = 'http://sportslabs-webproxy.imgix.net/http%3A%2F%2Fkty-platform-prod.silverchalice.co%2Fv3%2Fimages%2Fcontents%2F55bbe945e4b073340d3851fb?fit=clip&h=532&w=800&s=61b00197aca130a83de011484841158e'
open('raw_file', 'wb') do |file|
file << open(url).read
end
puts FileMagic.new(FileMagic::MAGIC_MIME).file( 'raw_file' )
# => 'image/jpeg; charset=binary'
更新:要找到保存文件的扩展名,您可以使用 mime-types
content_type = FileMagic.new(FileMagic::MAGIC_MIME).file( 'raw_file' ).split( ';' ).first
require 'mime/types'
puts MIME::Types[content_type].first.extensions.first
# => 'jpeg'
好吧,你有几个选择。您可以做的第一件事是信任 Web 服务器正确识别 Content-Type:
header 中的类型。这是一个示例(需要 mime-types
Rubygem):
require 'open-uri'
require 'mime/types'
url = 'http://sportslabs-webproxy.imgix.net/http%3A%2F%2Fkty-platform-prod.silverchalice.co%2Fv3%2Fimages%2Fcontents%2F55bbe945e4b073340d3851fb?fit=clip&h=532&w=800&s=61b00197aca130a83de011484841158e'
open(url) do |f|
filename = File.basename url
if filename !~ /\./ then
t = MIME::Type[f.content_type]
if t && t.first && t.first.extensions then
filename += ".#{t.first.extensions.first}"
end
end
open(filename, 'w') do |w|
w.write(f.read)
end
end
但是您最好使用 Eric 的解决方案并在下载文件后检查文件以确保它确实如您所想。
轻量级选项是 fastimage gem。下面是示例用法:
require 'fastimage'
FastImage.type("http://stephensykes.com/images/pngimage")
=> :png