hoogte en breedte van een JPEG
Als je bezig bent met web applicaties loop je vaak tegen het probleem dat het lastig is om de grootte van een afbeelding te bepalen. Voor GIF’s en PNG’s is dat triviaal maar JPEG’s zijn lastig. Ik heb wat oude code geport naar Ruby en kan nu zonder afhankelijk te zijn van een of andere library JPEG’s lezen.
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
Mijn liefde voor Ruby wordt weer bevestigd door meta-singleton-eigen-classes; hier pas ik m’n io object aan zodat ik gemakkelijk JPEG’s kan lezen. Een mini DSL in een paar regels code!
Volgende stap is de EXIF tag decoderen maar omdat deze in TIFF formaat is gecodeerd (ja echt! er zit een TIFF in je JPEG!) moet er eerst een TIFF decoder komen. Vast heel gemakkelijk allemaal in Ruby, ik word alleen al moe als ik aan het lezen van m’n oude Java code of de specs denk. Veel te veel werk voor een Ruby-Kata, meer een conditie training..
Remco,
Van de echte inhoud begrijp ik niks maar “grootte” schrijf je niet met slechts 1 t!
Nog gefeliciteerd met je verjaardag…
Groeten uit Lelystad
Bedankt en aangepast en bedankt. Natuurlijke talen zijn veel te moeilijk!