wake-up-neo.net

Gibt es eine einfache Möglichkeit, Bildabmessungen in Ruby abzurufen?

Ich bin auf der Suche nach einem einfachen Weg, um Breiten- und Höhenmaße für Bilddateien in Ruby zu ermitteln, ohne ImageMagick oder Image Science (mit Snow Leopard) verwenden zu müssen.

30
gruner

libimage-size ist eine Ruby-Bibliothek zur Berechnung von Bildgrößen für eine Vielzahl von Grafikformaten. Ein Juwel ist verfügbar, oder Sie können den Quell-Tarball herunterladen und die image_size.rb-Datei extrahieren.

4
bta

Ab Juni 2012 ist FastImage eine gute Option, mit der "die Größe oder der Typ eines Bilds anhand seiner Uri ermittelt wird, indem so wenig wie nötig abgerufen wird". Es funktioniert mit lokalen Images und solchen auf Remote-Servern.

Ein IRB-Beispiel aus der Readme:

require 'fastimage'

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

Standard-Array-Zuordnung in einem Skript:

require 'fastimage'

size_array = FastImage.size("http://stephensykes.com/images/ss.com_x.gif")

puts "Width: #{size_array[0]}"
puts "Height: #{size_array[1]}"

Oder verwenden Sie mehrere Zuweisungen in einem Skript:

require 'fastimage'

width, height = FastImage.size("http://stephensykes.com/images/ss.com_x.gif")

puts "Width: #{width}"
puts "Height: #{height}"
43
Alan W. Smith

Sie könnten dies versuchen (ungetestet):

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
31
ChristopheD

Es gibt auch eine neue Bibliothek (Juli 2011), die zu dem Zeitpunkt, als die Frage ursprünglich gestellt wurde, noch nicht verfügbar war: das Dimensions Rubygem (das anscheinend von demselben Sam Stephenson verfasst wurde, der auch für die vorgeschlagenen Byte-Manipulationstechniken verantwortlich ist Hier.)

Unten ein Codebeispiel aus der README-Datei des Projekts

require 'dimensions'

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

Es gibt eine praktische Methode in der Büroklammer:

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

Dies funktioniert nur, wenn identify installiert ist. Wenn dies nicht der Fall ist und PHP installiert ist, können Sie Folgendes tun:

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

Ich habe endlich einen netten schnellen Weg gefunden, um Dimensionen eines Bildes zu erhalten. Sie solltenMiniMagickverwenden.

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]
8
Adam Harte

Hier ist eine Version der JPEG-Klasse aus ChristopheDs Antwort, die sowohl in Ruby 1.8.7 als auch in Ruby 1.9 funktioniert. Auf diese Weise können Sie die Breite und Höhe einer JPEG-Bilddatei (.jpg) ermitteln, indem Sie die Bits direkt betrachten. (Alternativ können Sie auch den Dimensions-Edelstein verwenden, wie in einer anderen Antwort vorgeschlagen.)

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
3
matt

Für PNGs habe ich diese modifizierte Version der ChristopeD-Methode zum Laufen gebracht.

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