Ruby on Rails:如何检查文件是否是图像?

你如何检查文件是否是图像? 我想你可以使用这样的方法:

def image?(file) file.to_s.include?(".gif") or file.to_s.include?(".png") or file.to_s.include?(".jpg") end 

但这可能有点低效且不正确。 有任何想法吗?

(我正在使用回形针插件,顺便说一句,但我没有看到任何方法来确定文件是否是回形针中的图像)

我会使用ruby-filemagic gem,这是一个用于libmagic的Ruby绑定。

一种方法是使用“幻数”约定来读取文件的第一位。
http://www.astro.keele.ac.uk/oldusers/rno/Computing/File_magic.html

例子:

   “BM”是位图图像
   “GIF8”是GIF图像
   “\ xff \ xd8 \ xff \ xe0”是JPEG图像

Ruby中的示例:

   def位图?(数据)
    返回数据[0,2] ==“MB”
  结束

   def gif?(数据)
    返回数据[0,4] ==“GIF8”
  结束

   def jpeg?(数据)
    返回数据[0,4] ==“\ xff \ xd8 \ xff \ xe0”
  结束

   def file_is_image?(filename)
     f = File.open(filename,'rb')#rb表示使用二进制读取
     data = f.read(9)#魔术数最多为9个字节
     f.close
    返回位图?(数据)还是gif?(数据)还是jpeg?(数据)
  结束

为什么使用它而不是文件扩展名或filemagic模块?

在将任何数据写入磁盘之前检测数据类型。 例如,我们可以在将任何数据写入磁盘之前读取上传数据流。 如果幻数与网络表单内容类型不匹配,那么我们可以立即报告错误。

我们的实际代码略有不同。 我们创建一个哈希:每个键都是一个神奇的数字字符串,每个值都是一个符号,如:bitmap,:gif,:jpeg等。如果有人想看到我们的真实代码,请随时与我联系。

请检查一次

 MIME::Types.type_for('tmp/img1.jpg').first.try(:media_type) => "image" MIME::Types.type_for('tmp/img1.jpeg').first.try(:media_type) => "image" MIME::Types.type_for('tmp/img1.gif').first.try(:media_type) => "image" MIME::Types.type_for('tmp/ima1.png').first.try(:media_type) => "image" 

由于您正在使用Paperclip,因此可以在使用“has_attached_file”的模型中使用内置的“validates_attachment_content_type”方法,并指定要允许的文件类型。

以下是用户上传其个人资料头像的应用程序示例:

 has_attached_file :avatar, :styles => { :thumb => "48x48#" }, :default_url => "/images/avatars/missing_avatar.png", :default_style => :thumb validates_attachment_content_type :avatar, :content_type => ["image/jpeg", "image/pjpeg", "image/png", "image/x-png", "image/gif"] 

文档在这里http://dev.thoughtbot.com/paperclip/classes/Paperclip/ClassMethods.html

imagemagick有一个名为identity的命令来处理这个问题 – 检查回形针文档 – 可能有一种方法可以在你的RoR应用程序中处理这个问题。

作为Joel答案的补充,在Rails 5中我不得不将比较字符串转换为字节码。 例如:

 def jpeg?(data) return data[0,4]=="\xff\xd8\xff\xe0".b end