hoogte en breedte van een JPEG

Gepubliceerd op: 2.XII.2005 01:02 CET
Categorieën: ruby

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..

Paps @ 5 dagen

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

Remco @ 6 dagen

Bedankt en aangepast en bedankt. Natuurlijke talen zijn veel te moeilijk!