Gibt es eine einfache Möglichkeit, Bildabmessungen in Ruby zu bekommen?
-
20-09-2019 - |
Frage
Ich bin auf der Suche nach einer einfachen Möglichkeit bekommt Breiten- und Höhenabmessungen für Bilddateien in Ruby, ohne ImageMagick oder Bildwissenschaften (mit Snow Leopard) zu verwenden.
Lösung
libimage-size eine Ruby-Bibliothek ist für die Berechnung der Bildgrößen für eine Vielzahl von grafischen Formaten . Ein Juwel ist vorhanden, oder Sie können den Quelltext-Tarball herunterladen und die image_size.rb
-Datei extrahieren.
Andere Tipps
Ab Juni 2012 FastImage die „findet die Größe oder Art eines Bildes aufgrund seiner uri durch holen so wenig wie nötig“ist eine gute Wahl. Es arbeitet mit lokalen Bildern und die auf entfernten 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 mit Mehrfachzuordnung in einem Skript:
require 'fastimage'
width, height = FastImage.size("http://stephensykes.com/images/ss.com_x.gif")
puts "Width: #{width}"
puts "Height: #{height}"
Sie könnten versuchen, diese (nicht getestet):
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
Es gibt auch eine neue (Juli 2011) Bibliothek, die nicht in der Nähe zu der Zeit die Frage war ursprünglich gefragt wurde: Abmessungen rubygem (die auch hier vorgeschlagen von der gleichen Sam Stephenson verantwortlich für die Byte-Manipulationstechniken Autor zu sein scheint.)
Im Folgenden Codebeispiel aus Projekt README
require 'dimensions'
Dimensions.dimensions("upload_bird.jpg") # => [300, 225]
Dimensions.width("upload_bird.jpg") # => 300
Dimensions.height("upload_bird.jpg") # => 225
Es gibt eine praktische Methode in der Büroklammer Juwel:
>> Paperclip::Geometry.from_file("/path/to/image.jpg")
=> 180x180
Dies funktioniert nur, wenn identify
installiert ist. Wenn dies nicht der Fall, wenn PHP installiert ist, können Sie so etwas tun könnte:
system(%{php -r '$w = getimagesize("#{path}"); echo("${w[0]}x${w[1]}");'})
# eg returns "200x100" (width x height)
ich habe endlich eine schöne schnelle Art und Weise zu bekommen Dimensionen ein Bild gefunden. Sie sollten 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]
Hier ist eine Version der JPEG-Klasse von ChristopheD Antwort, die 1,9 sowohl in Ruby-1.8.7 und Ruby arbeitet. Auf diese Weise können Sie die Breite und Höhe eines JPEG (.jpg) Bild-Datei erhalten, indem man die Bits direkt an. (Alternativ nur das Juwel Abmessungen 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
Für PNGs Ich habe diese modifizierte Version von ChristopeD Methode zu arbeiten.
File.binread(path, 64)[0x10..0x18].unpack('NN')