【问题标题】:Is there a simple way to get image dimensions in Ruby?有没有一种简单的方法可以在 Ruby 中获取图像尺寸?
【发布时间】:2011-01-27 21:33:48
【问题描述】:

我正在寻找一种简单的方法来获取 Ruby 中图像文件的宽度和高度尺寸,而无需使用 ImageMagick 或 ImageScience(运行 Snow Leapard)。

【问题讨论】:

    标签: ruby image osx-snow-leopard dimensions


    【解决方案1】:

    截至 2012 年 6 月,FastImage“通过尽可能少地获取所需的 uri 来查找图像的大小或类型”是一个不错的选择。它适用于本地图像和远程服务器上的图像。

    自述文件中的 IRB 示例:

    require 'fastimage'
    
    FastImage.size("http://stephensykes.com/images/ss.com_x.gif")
    => [266, 56]  # width, height
    

    脚本中的标准数组赋值:

    require 'fastimage'
    
    size_array = FastImage.size("http://stephensykes.com/images/ss.com_x.gif")
    
    puts "Width: #{size_array[0]}"
    puts "Height: #{size_array[1]}"
    

    或者,在脚本中使用多重赋值:

    require 'fastimage'
    
    width, height = FastImage.size("http://stephensykes.com/images/ss.com_x.gif")
    
    puts "Width: #{width}"
    puts "Height: #{height}"
    

    【讨论】:

      【解决方案2】:

      你可以试试这些(未经测试):

      http://snippets.dzone.com/posts/show/805

      PNG:

      IO.read('image.png')[0x10..0x18].unpack('NN')
      => [713, 54]
      

      GIF:

      IO.read('image.gif')[6..10].unpack('SS')
      => [130, 50]
      

      BMP:

      d = IO.read('image.bmp')[14..28]
      d[0] == 40 ? d[4..-1].unpack('LL') : d[4..8].unpack('SS')
      

      JPG:

      class JPEG
        attr_reader :width, :height, :bits
      
        def initialize(file)
          if file.kind_of? IO
            examine(file)
          else
            File.open(file, 'rb') { |io| examine(io) }
          end
        end
      
      private
        def examine(io)
          raise 'malformed JPEG' unless io.getc == 0xFF && io.getc == 0xD8 # SOI
      
          class << io
            def readint; (readchar << 8) + readchar; end
            def readframe; read(readint - 2); end
            def readsof; [readint, readchar, readint, readint, readchar]; end
            def next
              c = readchar while c != 0xFF
              c = readchar while c == 0xFF
              c
            end
          end
      
          while marker = io.next
            case marker
              when 0xC0..0xC3, 0xC5..0xC7, 0xC9..0xCB, 0xCD..0xCF # SOF markers
                length, @bits, @height, @width, components = io.readsof
                raise 'malformed JPEG' unless length == 8 + components * 3
              when 0xD9, 0xDA:  break # EOI, SOS
              when 0xFE:        @comment = io.readframe # COM
              when 0xE1:        io.readframe # APP1, contains EXIF tag
              else              io.readframe # ignore frame
            end
          end
        end
      end
      

      【讨论】:

      • 哦,亲爱的,直接在字节后面!老派!
      • Ruby 1.9 破坏了您在此处引用的 JPEG 类;我已经提交了一个额外的答案,我对该类的修改可以在 Ruby 1.8.7 和 Ruby 1.9 下工作。
      • @ChristopheD:谢谢;我刚刚进入 Ruby 1.9(使用 1.9.3)并且之前使用的是您找到的代码,所以我很高兴能弄清楚代码损坏的原因以及如何修复它!
      【解决方案3】:

      还有一个新的(2011 年 7 月)库,在最初提出该问题时并不存在:Dimensions ruby​​gem(似乎由负责字节操作技术的同一位 Sam Stephenson 编写建议在这里。)

      项目自述文件中的以下代码示例

      require 'dimensions'
      
      Dimensions.dimensions("upload_bird.jpg")  # => [300, 225]
      Dimensions.width("upload_bird.jpg")       # => 300
      Dimensions.height("upload_bird.jpg")      # => 225
      

      【讨论】:

      • 这颗宝石对我来说效果很好。从表面上看,它做的不多,但内部类非常灵活且编写良好。
      【解决方案4】:

      回形针宝石中有一个方便的方法:

      >> Paperclip::Geometry.from_file("/path/to/image.jpg")
      => 180x180
      

      这仅在安装了identify 时有效。如果不是,如果安装了 PHP,你可以这样做:

      system(%{php -r '$w = getimagesize("#{path}"); echo("${w[0]}x${w[1]}");'})
      # eg returns "200x100" (width x height)
      

      【讨论】:

      • 这是一个很好的解决方案,但是它依赖于 ImageMagick 的 identify 工具来安装
      【解决方案5】:

      我终于找到了一种快速获取图像尺寸的好方法。您应该使用 MiniMagick

      require 'mini_magick'
      
      image = MiniMagick::Image.open('http://www.thetvdb.com/banners/fanart/original/81189-43.jpg')
      assert_equal 1920, image[:width]
      assert_equal 1080, image[:height]
      

      【讨论】:

      • 使用了ImageMagick,发帖人要求不要使用。
      • 至少在 2018 年对我有帮助
      【解决方案6】:

      libimage-size 是一个 Ruby 库,用于计算各种图形格式的图像大小。可以使用 gem,或者您可以下载源 tarball 并解压缩 image_size.rb 文件。

      【讨论】:

        【解决方案7】:

        这是 ChristopheD 的回答中的 JPEG 类版本,适用于 Ruby 1.8.7 和 Ruby 1.9。这允许您通过直接查看位来获取 JPEG (.jpg) 图像文件的宽度和高度。 (或者,只需使用Dimensions gem,正如另一个答案中所建议的那样。)

        class JPEG
          attr_reader :width, :height, :bits
          def initialize(file)
            if file.kind_of? IO
              examine(file)
            else
              File.open(file, 'rb') { |io| examine(io) }
            end
          end
        private
          def examine(io)
            if RUBY_VERSION >= "1.9"
              class << io
                def getc; super.bytes.first; end
                def readchar; super.bytes.first; end
              end
            end
            class << io
              def readint; (readchar << 8) + readchar; end
              def readframe; read(readint - 2); end
              def readsof; [readint, readchar, readint, readint, readchar]; end
              def next
                c = readchar while c != 0xFF
                c = readchar while c == 0xFF
                c
              end
            end
            raise 'malformed JPEG' unless io.getc == 0xFF && io.getc == 0xD8 # SOI
            while marker = io.next
              case marker
                when 0xC0..0xC3, 0xC5..0xC7, 0xC9..0xCB, 0xCD..0xCF # SOF markers
                  length, @bits, @height, @width, components = io.readsof
                  raise 'malformed JPEG' unless length == 8 + components * 3
                # colons not allowed in 1.9, change to "then"
                when 0xD9, 0xDA then  break # EOI, SOS
                when 0xFE then        @comment = io.readframe # COM
                when 0xE1 then        io.readframe # APP1, contains EXIF tag
                else                  io.readframe # ignore frame
              end
            end
          end
        end
        

        【讨论】:

          【解决方案8】:

          对于 PNG,我得到了 ChristopeD 方法的修改版本。

          File.binread(path, 64)[0x10..0x18].unpack('NN')
          

          【讨论】:

          • 只是出于好奇,File.binreadIO.read 有什么区别?
          猜你喜欢
          • 2023-03-21
          • 2011-03-02
          • 1970-01-01
          • 2012-09-10
          • 2014-01-03
          • 2017-07-05
          • 1970-01-01
          • 2011-01-03
          • 2011-04-20
          相关资源
          最近更新 更多