Barcode Generator

To generate a barcode, simply enter a number below. An EAN barcode will consist of exactly 13 digits, while a UPC barcode will consist of 12 digits with a leading zero, making 13 digits in all.

The barcode will appear with a red background if the number entered is not exactly 13 digits long or contains a non-numeric character. If the number is the correct length, but not a valid barcode (i.e. the check digit is incorrect), it will appear with a yellow background. Otherwise, you have a perfectly valid barcode with a white background!


Barcode


Code

This code goes into a standalone PHP file, and is accessed from a browser by using :

<img src="barcode.php?q=0123456987654" alt="barcode" />

Now for the code…

<?php
define("BAR_WIDTH", 3);			//The width of a single bar, in pixels
define("BORDER_SPACING", 9);	//The gap between the bars and the top of the image, in pixels
define("NUM_BARS", 95);			//The total number of bars in the barcode - leave as 95
define("DATA_BAR_HEIGHT", 80);	//The height of data bars, in pixels
define("GUARD_BAR_HEIGHT", 95);	//The height of guard bars, in pixels

//Digit codings for the various areas of the barcode
$Lcodes = array ( 0x0D, 0x19, 0x13, 0x3D, 0x23, 0x31, 0x2F, 0x3B, 0x37, 0x0B );
$Gcodes = array ( 0x27, 0x33, 0x1B, 0x21, 0x1D, 0x39, 0x05, 0x11, 0x09, 0x17 );
$Rcodes = array ( 0x72, 0x66, 0x6C, 0x42, 0x5C, 0x4E, 0x50, 0x44, 0x48, 0x74 );

//The first digit specifies which codings to use. This maps that digit to the codings above.
$Encod = array ( 0x3F, 0x34, 0x32, 0x31, 0x2C, 0x26, 0x23, 0x2A, 0x29, 0x25 );

//Guard bar codings
$startEnd = 0x05;
$middle = 0x0A;

/**
 * Draws a byte pattern to the output image
 *
 * Parameters:
 *	$img		The image resource to draw to.
 *	$b			The pattern to draw.
 *	$position	The X position to draw the pattern, in pixels.
 *	$length		The number of bits to draw from the byte.
 *	$height		The height to draw the pattern, in pixels.
 *
 * Returns:
 *	The pixel position that was last drawn.
 **/
function drawByte($img, $b, $position, $length, $height)
{
	$b <<= 8 - $length;

	for ($i = 0; $i < $length; $i++)
	{
		if (($b & 0x80) != 0)
		{
			imagefilledrectangle($img, $position, BORDER_SPACING, $position + BAR_WIDTH - 1, $height + BORDER_SPACING, 0);
		}
		//else no bar
		$b <<= 1;

		//draw the line
		$position += BAR_WIDTH;
	}
	return BAR_WIDTH * $length;
}

/**
 * Draws a group of 6 digits.
 *
 * Parameters:
 *	$img		The image resource to draw to.
 *	$encoding	The encoding pattern to use; specified in the $Encod array.
 *	$position	The X position to draw the group, in pixels.
 *	$Rcode		True if the group should be drawn using R codes.
 *	$values		An array of numbers to draw.
 *
 * Returns:
 *	The pixel position that was last drawn.
 **/
function drawValues($img, $encoding, $position, $Rcode, $values)
{
	global $Lcodes;
	global $Gcodes;
	global $Rcodes;
	$offset = $Rcode ? 7 : 1;

	for ($i = 0; $i < 6; $i++)
	{
		if ($Rcode)
		{
			if(count($values) <= $i + 7)
				break;
			$pattern = $Rcodes[$values[$i+7]];
		}
		else if (($encoding & pow(2, 5-$i)) != 0)
		{
			if(count($values) <= $i + 1)
				break;
			$pattern = $Lcodes[$values[$i + 1]];
		}
		else if (count($values) > $i + 1)
		{
			$pattern = $Gcodes[$values[$i + 1]];
		}
		else
		{
			break;
		}

		imagestring($img, 6, $position + BAR_WIDTH, DATA_BAR_HEIGHT + BORDER_SPACING, $values[$i + $offset], 0);
		$position += drawByte($img, $pattern, $position, 7, DATA_BAR_HEIGHT);
	}
	return BAR_WIDTH * 7 * 6;
}

/**
 * Draws a barcode.
 *
 * Parameters:
 *	$img		The image resource to draw to.
 *	$values		An array of digits that make up the barcode.
 *
 * Returns:
 *	The image resource which the barcode was drawn to.
 **/
function drawBarcode($img, $values)
{
	global $Encod;
	global $startEnd;
	global $middle;
	if(count($values) <= 1)
		return $img;
	$encoding = $Encod[$values[0]];

	if($values[0] != 0)
		imagestring($img, 4, 0, DATA_BAR_HEIGHT + BORDER_SPACING, $values[0], 0);

	$position = BORDER_SPACING;
	$position += drawByte($img, $startEnd, $position, 3, GUARD_BAR_HEIGHT);	//start guard bars
	$position += drawValues($img, $encoding, $position, false, $values);	//first 6 digits
	$position += drawByte($img, $middle, $position, 5, GUARD_BAR_HEIGHT);	//middle guard bars
	$position += drawValues($img, $encoding, $position, true, $values);		//final 6 values
	$position += drawByte($img, $startEnd, $position, 3, GUARD_BAR_HEIGHT);	//end guard bars

	return $img;
}

/**
 * Checks whether a barcode is valid or not.
 *
 * Parameters:
 *	$values		The values that make up the barcode.
 *
 * Returns:
 *	0 if completely valid
 *	1 if the input is invalid
 *	2 if the input is valid, but the check digit is incorrect
 **/
function checkValidity($values)
{
	$invalid = false;
	$failChecksum = false;

	//Make sure all digits are numeric
	foreach($values as $i)
	{
		if(!is_numeric($i))
		{
			$invalid = true;
		}
	}

	//Make sure there are the right number of digits
	if(count($values) != 13)
	{
		$invalid = true;
	}

	//Make sure the check digit is correct
	if(!$invalid)
	{
		$oddSum = 0;
		$evenSum = 0;
		for($i=1; $i < 12; $i += 2)
		{
			$oddSum += $values[$i];
		}
		for($i = 0; $i < 12; $i += 2)
		{
			$evenSum += $values[$i];
		}
		$checksum = $oddSum * 3 + $evenSum;
		$checksum %= 10;
		$checksum = 10 - $checksum;
		$checksum %= 10;

		if($values[12] != $checksum)
		{
			$failChecksum = true;
		}
	}

	if($invalid)
		return 1;
	if($failChecksum)
		return 2;
	return 0;
}

//Set up the output image, and get input values.
$width = NUM_BARS * BAR_WIDTH + BORDER_SPACING * 2;
$height = GUARD_BAR_HEIGHT + BORDER_SPACING * 2;
$img = imagecreatetruecolor($width, $height);
$values = str_split($_GET['q']);

//Make sure the barcode is valid
$validity = checkValidity($values);

switch($validity)
{
	case 1:
		imagefill($img, 0, 0, imagecolorallocate($img , 0xff, 0x00, 0x00));
		break;
	case 2:
		imagefill($img, 0, 0, imagecolorallocate($img, 0xff, 0xff, 0x00));
		break;
	default:
		imagefill($img, 0, 0, imagecolorallocate($img, 0xff, 0xff, 0xff));
		break;
}

//Now draw the thing
$img = drawBarcode($img, $values);

//And then output to the browser as a GIF image.
header('Content-type: image/gif');
imagegif($img);
?>