[原创]39码编码函数

PHP程序设计语言和相关项目讨论
Post Reply
User avatar
renart
初见功力
初见功力
Posts: 59
Joined: 2006-11-05 23:40

[原创]39码编码函数

Post by renart » 2006-12-04 12:45

查资料写的,在网上搜过,没有找到类似的php脚本,所以冠原创两字,第一次在freediscuz发布过,这里是第二次发布

Code: Select all

<?
/**
 * @filename	BarCode39.php
 * @author		renart
 * @date		2006-08-04
 * @copyright	renart
 * 
 * 
 * CODE39码的编码规则是: 
 * 1.每五条线表示一个字符;
 * 2.粗线表示1,细线表示0; 
 * 3.线条间的间隙宽的表示1,窄的表示0; 
 * 4.五条线加上它们之间的四条间隙就是九位二进制编码,而且这九位中必定有三位是1,所以称为39码; 
 * 5.条形码的首尾各一个*标识开始和结束 
 * 6.在我们的程序中,给常用的字符都进行编码,解读时先取线条粗细,再取间隙宽窄
 * 
 * 本脚本中码字元表为数组$DeCode
 * 
 * 39码的检查码必须搭配[检查码相对值对照表]
 * 
 * 本脚本中对照表为数组$ChekCode
 * 
 * 如表所示,将查出的相对值累加后再除以43,得到的余数再查出相对的编码字元,即为检查码字元.
 * 
 * 例如要算出 *S123$5* 这笔资料的检查码,其计算过程如下:
 * 
 * 步骤1 参考检查码相对值对照表,找出编码字元相对值
 * 参考表,得到各编码字元的相对值为:
 * S 的相对值为28;1 的相对值为1;
 * 2 的相对值为2;3 的相对值为3;
 * $ 的相对值为39;5 的相对值为5.
 * 
 * 步骤2 将各相对值累加除以43
 * 累加相对值=28+1+2+3+39+5=78
 * 78/43=1...35
 * 
 * 步骤3 查出与余数相对的编码字元
 * 余数=35,
 * 查表5.4,得到相对值=35的编码字元为Z,
 * 故检查码=Z,得
 * 含检查码在内的39码,为:*S123$5Z*
 * 
 * 本函数没有设定检查码,有兴趣的人可以自己写
 *  
 * renart@gmail.com 
 */

function BarCode39($Code, $Title = "", $UseCheck = 0) {
	/*
	网上查出来的一种码表,经过检查,不对,呵呵
	$DeCode = array("A" => "110101001011", "B" => "101101001011", "C" => "110110100101", "D" => "101011001011",
					"E" => "110101100101", "F" => "101101100101", "G" => "101010011011", "H" => "110101001101",
					"I" => "101101001101", "J" => "101011001101", "K" => "110101010011", "L" => "101101010011",
					"M" => "110110101001", "N" => "101011010011", "O" => "110101101001", "P" => "101101101001",
					"Q" => "101010110011", "R" => "110101011001", "S" => "101101011001", "T" => "101011011001",
					"U" => "110010101011", "V" => "100110101011", "W" => "110011010101", "X" => "100101101011",
					"Y" => "110010110101", "Z" => "100110110101", "0" => "101001101101", "1" => "110100101011",
					"2" => "101100101011", "3" => "110110010101", "4" => "101001101011", "5" => "110100110101",
					"6" => "101100110101", "7" => "101001011011", "8" => "110100101101", "9" => "101100101101",
					"+" => "100101001001", "-" => "100101011011", "*" => "100101101101", "/" => "100100101001",
					"%" => "101001001001", "$" => "100100100101", "." => "110010101101", " " => "100110101101");
	*/

	//元码表
	$DeCode = array("0" => "000110100", "1" => "100100001", "2" => "001100001", "3" => "101100000",
					"4" => "000110001", "5" => "100110000", "6" => "001110000", "7" => "000100101",
					"8" => "100100100", "9" => "001100100", "A" => "100001001", "B" => "001001001",
					"C" => "101001000", "D" => "000011001", "E" => "100011000", "F" => "001011000",
					"G" => "000001101", "H" => "100001100", "I" => "001001101", "J" => "000011100",
					"K" => "100000011", "L" => "001000011", "M" => "101000010", "N" => "000010011",
					"O" => "100010010", "P" => "001010010", "Q" => "000000111", "R" => "100000110",
					"S" => "001000110", "T" => "000010110", "U" => "110000001", "V" => "011000001",
					"W" => "111000000", "X" => "010010001", "Y" => "110010000", "Z" => "011010000",
					"-" => "010000101", "%" => "000101010", "$" => "010101000", "*" => "010010100");

	//检查码表
	$ChekCode = array("0" =>  "0", "1" =>  "1", "2" =>  "2", "3" =>  "3", "4" =>  "4", "5" =>  "5", "6" =>  "6",
					  "7" =>  "7", "8" =>  "8", "9" =>  "9", "A" => "10", "B" => "11", "C" => "12", "D" => "13",
					  "E" => "14", "F" => "15", "G" => "16", "H" => "17", "I" => "18", "J" => "19", "K" => "20",
					  "L" => "21", "M" => "22", "N" => "23", "O" => "24", "P" => "25", "Q" => "26", "R" => "27",
					  "S" => "28", "T" => "29", "U" => "30", "V" => "31", "W" => "32", "X" => "33", "Y" => "34",
					  "Z" => "35", "-" => "36", "." => "37", " " => "38", "$" => "39", "/" => "40", "+" => "41",
					  "%" => "42");

	//定义几个开关
	$UseTitle = 1;	//条码上端显示标题
	$UseTTF = 1;	//使用TTF字体,方便显示中文,需要$UseTitle=1时才能生效
	$UseStand = 1;	//检查输入待编码字符是否为标准格式(是否以*开始结束)

	$WidthCU = 4;	//粗线和宽间隙宽度
	$WidthXI = 1;	//细线和窄间隙宽度
	$Height = 100;	//定义图片高度

	$xCoordinate = 15;	//条码起始坐标

	if ($Title == "") {
		$UseTitle = 0;
	}

	$sh = 0;	//用来修改高度的,以便于将编码嵌入条码

	$Code = strtoupper($Code);	//转为大写
	if (preg_match("/[^[A-Z0-9\-\%\$\*]]?/",$Code)) {
		die("非法输入字符");
	}
	
	$OriginalCode = $Code;	//保存一个原始码值

	//计算检查码
	if ($UseCheck) {
		$Check = 0;
		for ($i = 0; $i < strlen($Code); $i++) {
			$Check += $ChekCode[$Code[$i]];
		}
		$Check = $ChekCode[$Check%43];
		$Code .= $Check;
		$OriginalCode .= "    " . $Check;
	}

	//标准化输入字符
	if ($UseStand) {
		if (substr($Code,0,1) != "*") {
			$Code = "*" . $Code;
		}
		if (substr($Code,0,-1) != "*") {
			$Code = $Code . "*";
		}
	}

	//重新编码输入字符,用新的变量,因为原始变量有别的用途
	$NewCode = "";
	for ($i = 0; $i < strlen($Code); $i++) {
		$NewCode .= $DeCode[$Code[$i]]."0";
	}

	$PHPVersion = explode(".", PHP_VERSION);	//获得版本

	if ($PHPVersion[0] >=5) {
		$Width = array_sum(str_split($NewCode)) * ($WidthCU - $WidthXI) + strlen($NewCode) * $WidthXI + 30;	//计算图片宽度
	} else {
		$Width = array_sum(preg_split('//', $NewCode, -1)) * ($WidthCU - $WidthXI) + strlen($NewCode) * $WidthXI + 30;	//计算图片宽度;
	}

	$Image = ImageCreate($Width, $Height + 50);

	$fg = ImageColorAllocate($Image, 0, 0, 0);	//前景颜色,黑色
	$bg = ImageColorAllocate($Image, 255, 255, 255);	//背景颜色,白色

	ImageFilledRectangle($Image, 0, 0, $Width, $Height + 50, $bg);	//填充背景

	if ($UseTitle) {
		$Title = iconv("GBK", "UTF-8", $Title);
		if ($UseTTF) {
			imagettftext($Image, 12, 0, ($Width - 9 * strlen($Title)) / 2, 20, $fg, "simsun.ttc", $Title);
		} else {
			imagestring($Image, 5, ($Width - 9 * strlen($Title)) / 2, 5, $Title, $fg);
		}
	}

	for ($i = 0; $i< strlen($NewCode) - 1; $i++) {
		$Color = $fg;
		ImageFilledRectangle($Image, $xCoordinate, 5 + $UseTitle * 20, $xCoordinate + ($NewCode[$i] == "0" ? $WidthXI : $WidthCU), $Height + 25, $Color);
		$xCoordinate = $xCoordinate + ($NewCode[$i] == "0" ? $WidthXI : $WidthCU);
		$i++;
		$Color = $bg;
		ImageFilledRectangle($Image, $xCoordinate, 5 + $UseTitle * 20, $xCoordinate + ($NewCode[$i] == "0" ? $WidthXI : $WidthCU), $Height + 25, $Color);
		$xCoordinate = $xCoordinate + ($NewCode[$i] == "0" ? $WidthXI : $WidthCU);
	}

	//Add the Human Readable Label
	for ($i = 0; $i < strlen($OriginalCode); $i++) {
		imagestring($Image, 5, 12 * $i + ($Width - 12 * strlen($OriginalCode)) / 2, $Height + 25, $OriginalCode[$i], $fg);
	}

	//Output the Header and Content.
	header("Content-Type: image/png");
	ImagePNG($Image);
	ImageDestroy($Image);
}

BarCode39 ("1234567890", "PHPBBChina", 0);

?>
Attachments
111.jpg
效果
111.jpg (39.14 KiB) Viewed 2908 times

User avatar
renart
初见功力
初见功力
Posts: 59
Joined: 2006-11-05 23:40

Post by renart » 2006-12-04 12:47

对了,这个函数里面的检验码已经可以用了,用

Code: Select all

BarCode39 ("1234567890", "PHPBBChina", 1);
调用就行了
另外,函数里的开关设置看一下,因为涉及到字体,需要自己找字体文件

User avatar
IOsetting
论坛管理员
论坛管理员
Posts: 3645
Joined: 2006-10-17 1:48

Post by IOsetting » 2006-12-04 13:06

强啊,很早以前就想研究一下条形码,大概知道一点点原理,不过要用代码做出来还真是没有想过。这样的生成结果可以用在什么场合?需要摄像头辅助识别么?

User avatar
renart
初见功力
初见功力
Posts: 59
Joined: 2006-11-05 23:40

Post by renart » 2006-12-04 14:12

超市用的和图书上用的是UPCA码
这种39码一般用在码位数不定的地方,例如学生证,资料编号等等
广泛地说,任何场合都能用上

可以用标准条码扫描器扫描成数字信号处理

User avatar
ifubo
界面组成员
界面组成员
Posts: 437
Joined: 2006-10-26 17:46

Post by ifubo » 2006-12-04 16:50

太强了,楼主高人呀
还是期待你完善服务器端的解压缩,毕竟那东西对我们来说很实用
俺是一只大大大菜鸟......想要飞却怎么样也飞不高.....
支持phpbb,支持phpbbchina

一帘幽梦
初来乍到
初来乍到
Posts: 3
Joined: 2008-09-17 9:42

Re: [原创]39码编码函数

Post by 一帘幽梦 » 2008-09-19 14:07

不错,支持下。。。。。。。 :grin:
合肥网站建设

Post Reply