<?php

/* EAN13 barcode renderer
 * Copyright 2012 Joel Yliluoma - http://iki.fi/bisqwit/
 */

class EAN13render
{
  
// These are the different barcode patterns for each digit (7 bit each).
  // '1' represents a black line, '0' represents white (no line).
  
static $Rcodes = Array('1110010','1100110','1101100','1000010','1011100',
                         
'1001110','1010000','1000100','1001000','1110100');

  
// The EAN13 defines three groups of bit patterns.
  // The 'R' pattern group, as above.
  // The 'G' group, which is a mirror of R (bits scanned in opposite order).
  // And the 'L' group, which is an inverse of R (0 becomes 1, 1 becomes 0).
  // Rather than defining them as arrays, we'll synthesize them at runtime.
  
  // This array describes which group to use for each digit,
  // depending on the first digit of the EAN code.
  
static $groups = Array('LLLLLL','LLGLGG','LLGGLG','LLGGGL','LGLLGG',
                         
'LGGLLG','LGGGLL','LGLGLG','LGLGGL','LGGLGL');

  public static function 
Render($barcode)
  {
    
$w 123$h 78// Size of our barcode image.
    
$im ImageCreateTrueColor($w,$h);
    
#ImageFilledRectangle($im, 0,0, $w,$h, 0xFFFFFF); // Fill the image with white
    
$xpos 19;

    
// This function renders bit patterns.
    
$synth = function($pattern$transformation$height) use(&$im,&$xpos)
    {
      
$b strlen($pattern);
      for(
$a=0$a<$b; ++$a)
      {
        
$index $a;
        
        
// If the group is 'G', mirror the code.
        
if($transformation == 'G'$index = ($b-1) - $index;

        
// Choose the bit from the pattern.
        
$bit = (int) $pattern[$index];
        
        
// Oh. For anyone wondering, this editor is actually
        // Joe. It is not the same editor I have used for many
        // of my videos. That's because now I'm making a Linux program.
        // Anyway.
        
        // If the group is 'L', invert the bit.
        
if($transformation == 'L'$bit 1-$bit;
        
        
// If the bit is '1', draw a vertical line in black color.
        
if($bit == 1)
          
ImageLine($im$xpos,0$xpos,$height0x000000);
        ++
$xpos;
      }
    };
    
    
// Define the lengths of the barcode lines.
    
$normal_height    $h-12;
    
$separator_height $h-7;
    
    
$font './arial.ttf';
    
    
// First, produce a begin separator (two thin bars).
    
$synth('101''R'$separator_height);
    
    
/*for($n=1; $n<13; ++$n)
    {
      $digit = (int) $barcode[$n];
      
      if($n == 0)
      {
        // Print the first digit separately (in black color)
        // Unless 0, which stands for UPC
        #if($digit != 0)
        #  ImageTTFtext($im, 8,0, $xpos-10,$h-1, 0x000000, $font, $digit);
      }
      else
      {
        // Print the digit (in black color)
        #ImageTTFtext($im, 8,0, $xpos,$h-1, 0x000000, $font, $digit);
        
        // Produce the pattern.
        $code   = EAN13render::$Rcodes[$digit];
        $select = 'R';
        if($n <= 6)
        {
          // Choose the patterns for the left side digits based
          // on the first digit of the barcode.
          $select = EAN13render::$groups[ (int)$barcode[0] ][ $n-1 ];
        }
        
        $synth($code, $select, $normal_height);
        
        if($n == 6)
        {
          // Produce the middle separator. Two thin bars, again.
          $synth('01010', 'R', $separator_height);
        }
      }
    }*/
    
    // Last, produce the end separator.
    // Which looks the same as the begin separator.
    
$synth('101''R'$separator_height);
    
    return 
$im;
  }
};

// This is my sample EAN-13 barcode (6425081281317):
$barcode sprintf('64%s'base_convert('BISQWIT',36,10));
#$barcode = '9780201633719';
#$barcode = '0'. '332960073452';

$im EAN13render::Render($barcode);
ImagePNG($im'test.png');