从 Ruby on Rails 中的 Base64 编码图像中检索文件名和内容类型

6

我正在尝试获取以base64编码格式接收的图像的内容类型和文件名。

以下是使用POST请求发送base64编码图像的代码:

require 'net/http'
require "rubygems"
require 'active_support'

url = URI.parse('http://localhost:3000/')
image = ActiveSupport::Base64.encode64(open("public/images/rails.png").to_a.join)
post_params = {'image' => image }
Net::HTTP.post_form(url, post_params)

在控制器中,我需要获取这张图片的content-type和文件名。因此,首先我需要对其进行解码。
image = ActiveSupport::Base64.decode64(params[:image])
image_data = StringIO.new(image)

然后我卡住了!

我基本上想使用Paperclip保存这张图片。需要一些严肃的帮助!

更新: 我无法为内容类型和文件名发送参数。我只是模仿客户端发送的内容(我无法控制添加额外的参数)。


你不能只是添加另一个post_param吗?像这样 {'filename' => 'rails.png'} - Serabe
不!我正在开发的API没有发送任何其他参数。只有编码图像数据。因此,我想知道是否可以在不发送任何其他参数的情况下实现这一点。 - Madhusudhan
你没有考虑使用用户提供的文件名来保存文件,对吧?那可不是个好主意。 - mu is too short
@mu-is-too-short 不是的!实际上它是由客户端应用程序(iPad应用程序)在我直接从用户那里收到之前进行处理的。 - Madhusudhan
很高兴听到这个消息。如果数据来自iPad,除非iPad用户手动命名为“名称X”,否则不会有任何文件名。 - mu is too short
2个回答

5
您可以使用各种ImageMagick库解码原始字节,然后询问ImageMagick格式。例如,使用RMagick
require 'rmagick'
bytes = ActiveSupport::Base64.decode64(params[:image])
img   = Magick::Image.from_blob(bytes).first
fmt   = img.format

那将在fmt中给你'PNG''JPEG'等。ImageMagick检查字节的魔数和其他识别信息,因此不需要文件名来知道您提供的图像类型。

至于文件名,除非有人明确告诉你它是什么,否则你就没有办法了。文件名很少有关系,如果需要,您应该永远不要使用未生成的文件名保存任何内容;只有用户提供的文件名应用于向人们显示名称,如果需要一个文件名,请自己编写一个(您知道是安全的)。


我认为现在文件名不应该是问题,因为Paperclip可以与适当的实例关联。我所需要的只是内容类型。让我试一试。谢谢! - Madhusudhan
谢谢这个,我可以得到 PNG 格式,至少可以将内容类型设置为 image/png - Madhusudhan

0
关于文件名,你为什么不直接发布它呢?这似乎更容易(post_params = {'image' => image, 'file_name' => same_file_you_passed_to_encode64 })。要找到内容类型,你可以使用像ruby-filemagic这样的库。

http://rubygems.org/gems/ruby-filemagic


我正在开发的API没有发送任何其他参数,只有编码后的图像数据。是否可能仅从编码数据中获取文件名?听说在PHP中可以实现,我确信在Ruby/Rails中也有出路。 - Madhusudhan
除非文件名是实际图像数据的一部分 - 这在我看来相当奇怪 - 我不知道它怎么会出现在Base64编码的字符串中。您确定您听到的关于PHP的内容与EXIF相关吗?例如,文件名可以是嵌入数据的一部分吗? - Michael Kohl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接