<?php
class resizeimage {
	// 图片类型
	var $type; 
	// 实际宽度
	var $width; 
	// 实际高度
	var $height; 
	// 改变后的宽度
	var $resize_width; 
	// 改变后的高度
	var $resize_height; 
	// 是否裁图
	var $cut; 
	// 源图象
	var $srcimg; 
	// 目标图象地址
	var $dstimg; 
	// 临时创建的图象
	var $im = null; 
	// 临时文件名
	var $imgname;
	var $CurrentBit = 0;

	function resizeimage($img) {
		$this -> imgname = $img;
		$this -> srcimg = $img;
		$this -> type = $this -> _get_image_type();
	} 

	function init() {
		if (!is_file($this -> srcimg)) return 1;
		if ($this -> type === false) return 2;
		if (!in_array($this -> type, array('gif', 'jpg', 'png','bmp'))) return 3;
		if ($this -> init_img() == false) return 4;
		$this -> width = imagesx($this -> im);
		$this -> height = imagesy($this -> im);
		return 0;
	} 

	/**
	* crop img
	*/
	function crop($x, $y, $w, $h, $quality = 75) {
		$out = imagecreatetruecolor($w, $h);
		imagecopyresampled($out, $this -> im, 0, 0, $x, $y, $w, $h, $w, $h);
		$this -> output($out, $this -> srcimg, $quality);
		imagedestroy($out);
		$this -> close();
	} 

	/**
	* img border
	*/
	function border($size, $color, $quality = 75) {
		$w = $this -> width + $size * 2;
		$h = $this -> height + $size * 2;
		$out = imagecreatetruecolor($w, $h);
		$c = $this -> parseColor($color);
		$color = ImageColorAllocate($this -> im, $c[0], $c[1], $c[2]);
		imagefilledrectangle($out, 0, 0, $w, $h, $color);
		imagecopymerge ($out, $this -> im, $size, $size, 0, 0, $this -> width, $this -> height, 100);
		$this -> output($out, $this -> srcimg, $quality);
		imagedestroy($out);
		$this -> close();
	} 

	function rotate($degrees, $quality = 75) {
		if ($degrees == 180) {
			$out = imagerotate($this -> im, $degrees, 180);
		} else { // 90 or 270
			$max = max($this -> width, $this -> height);
			$square = imagecreatetruecolor($max, $max);
			imagecopy($square, $this -> im, 0, 0, 0, 0, $this -> width, $this -> height);
			$square = imageRotate($square, $degrees, 0);
			$out = imagecreatetruecolor($this -> height, $this -> width);
			if ($degrees == 90) {
				imagecopy($out, $square, 0, 0, 0, $max - $this -> width, $this -> height, $this -> width);
			} elseif ($degrees == 270) {
				imagecopy($out, $square, 0, 0, $max - $this -> height, 0, $this -> height, $this -> width);
			} 
			imagedestroy($square);
		} 
		$this -> output($out, $this -> srcimg, $quality);
		imagedestroy($out);
		$this -> close();
	} 

	/**
	* resize img
	*/
	function resize($w, $h, $quality = 75) {
		$out = imagecreatetruecolor($w, $h);
		imagecopyresampled($out, $this -> im, 0, 0, 0, 0, $w, $h, $this -> width, $this -> height);
		$this -> output($out, $this -> srcimg, $quality);
		imagedestroy($out);
		$this -> close();
	} 

	/**
	* resize img
	*/
	function run($width, $height, $c = 0, $dstimg = '', $quality = 75) {
		$this -> resize_width = intval($width);
		$this -> resize_height = intval($height);
		$this -> quality = intval($quality);
		$this -> cut = intval($c);
		if ($dstimg) {
			$this -> dstimg = $dstimg;
		} else {
			$this -> dstimg = '';
		} 
		$this -> _newimg($quality);
	} 

	function close() {
		ImageDestroy ($this -> im);
	} 

	function _newimg($quality) {
		$resize_ratio = ($this -> resize_width) / ($this -> resize_height);
		$ratio = ($this -> width) / ($this -> height);
		if (intval($this -> cut)) {
			if ($ratio >= $resize_ratio) {
				$newimg = imagecreatetruecolor($this -> resize_width, $this -> resize_height);
				imagecopyresampled($newimg, $this -> im, 0, 0, 0, 0, $this -> resize_width, $this -> resize_height, (($this -> height) * $resize_ratio), $this -> height);
				$this -> output ($newimg, $this -> dstimg, $quality);
				ImageDestroy ($newimg);
			} else {
				$newimg = imagecreatetruecolor($this -> resize_width, $this -> resize_height);
				imagecopyresampled($newimg, $this -> im, 0, 0, 0, 0, $this -> resize_width, $this -> resize_height, $this -> width, (($this -> width) / $resize_ratio));
				$this -> output ($newimg, $this -> dstimg, $quality);
				ImageDestroy ($newimg);
			} 
		} else {
			if ($ratio >= $resize_ratio) {
				$newimg = imagecreatetruecolor($this -> resize_width, ($this -> resize_width) / $ratio);
				imagecopyresampled($newimg, $this -> im, 0, 0, 0, 0, $this -> resize_width, ($this -> resize_width) / $ratio, $this -> width, $this -> height);
				$this -> output ($newimg, $this -> dstimg, $quality);
				ImageDestroy ($newimg);
			} else {
				$newimg = imagecreatetruecolor(($this -> resize_height) * $ratio, $this -> resize_height);
				imagecopyresampled($newimg, $this -> im, 0, 0, 0, 0, ($this -> resize_height) * $ratio, $this -> resize_height, $this -> width, $this -> height);
				$this -> output ($newimg, $this -> dstimg, $quality);
				ImageDestroy ($newimg);
			} 
		} 
	} 

	function output(&$newimg, $dstimg, $quality = 75) {
		switch ($this -> type) {
			case 'jpg':
				imagejpeg ($newimg, $dstimg, $quality);
				break;

			case 'gif':
				imagegif ($newimg, $dstimg);
				break;

			case 'png':
				imagepng ($newimg, $dstimg);
				break;

			case 'bmp':
				$this->imagebmp ($newimg, $dstimg);
				break;
		} 
	} 

	function init_img() {
		if ($this -> type == "jpg" && function_exists('imagecreatefromjpeg')) {
			$this -> im = imagecreatefromjpeg($this -> srcimg);
		} else if ($this -> type == "gif" && function_exists('imagecreatefromgif')) {
			$this -> im = imagecreatefromgif($this -> srcimg);
		} else if ($this -> type == "png" && function_exists('imagecreatefrompng')) {
			$this -> im = imagecreatefrompng($this -> srcimg);
		} else if ($this -> type == "bmp" && function_exists('imagecreatefrombmp')) {
			$this -> im = $this -> imagecreatefrombmp($this -> srcimg);
		} 
		if ($this -> im == null || $this -> im == false) {
			return false;
		} else {
			return true;
		} 
	} 

	function _get_image_type() {
		$info = @getimagesize($this -> srcimg);
		$map = array(1 => 'GIF',
			2 => 'JPG',
			3 => 'PNG',
			4 => 'SWF',
			5 => 'PSD',
			6 => 'BMP'
			);
		return ($info === false || !isset($map[$info[2]])) ? false : strtolower($map[$info[2]]);
	} 

	function parseColor($color) {
		if (substr($color, 0, 1) == '#') $color = substr($color, 1);
		$arr = array();
		for($ii = 0; $ii < strlen($color); $ii++) {
			$arr[] = hexdec(substr($color, $ii, 2));
			$ii++;
		} 
		return $arr;
	} 

	function imagebmp(&$img, $file = "", $RLE = 0) {
		$ColorCount = imagecolorstotal($img);

		$Transparent = imagecolortransparent($img);
		$IsTransparent = $Transparent != -1;

		if ($IsTransparent)
			$ColorCount--;

		if ($ColorCount == 0) {
			$ColorCount = 0;
			$BitCount = 24;
		} 
		if (($ColorCount > 0) and ($ColorCount <= 2)) {
			$ColorCount = 2;
			$BitCount = 1;
		} 
		if (($ColorCount > 2) and ($ColorCount <= 16)) {
			$ColorCount = 16;
			$BitCount = 4;
		} 
		if (($ColorCount > 16) and ($ColorCount <= 256)) {
			$ColorCount = 0;
			$BitCount = 8;
		} 

		$Width = imagesx($img);
		$Height = imagesy($img);

		$Zbytek = (4 - ($Width / (8 / $BitCount)) % 4) % 4;
		$palsize = 0; // cid added
		if ($BitCount < 24)
			$palsize = pow(2, $BitCount) * 4;

		$size = (floor($Width / (8 / $BitCount)) + $Zbytek) * $Height + 54;
		$size += $palsize;
		$offset = 54 + $palsize;
		$ret = 'BM'; // header (2b)
		$ret .= $this -> int_to_dword($size); // size of file (4b)
		$ret .= $this -> int_to_dword(0); // reserved (4b)
		$ret .= $this -> int_to_dword($offset); // byte location in the file which is first byte of IMAGE (4b) 
		$ret .= $this -> int_to_dword(40); // Size of BITMAPINFOHEADER (4b)
		$ret .= $this -> int_to_dword($Width); // width of bitmap (4b)
		$ret .= $this -> int_to_dword($Height); // height of bitmap (4b)
		$ret .= $this -> int_to_word(1); // biPlanes = 1 (2b)
		$ret .= $this -> int_to_word($BitCount); // biBitCount = {1 (mono) or 4 (16 clr ) or 8 (256 clr) or 24 (16 Mil)} (2b)
		$ret .= $this -> int_to_dword($RLE); // RLE COMPRESSION (4b)
		$ret .= $this -> int_to_dword(0); // width x height (4b)
		$ret .= $this -> int_to_dword(0); // biXPelsPerMeter (4b)
		$ret .= $this -> int_to_dword(0); // biYPelsPerMeter (4b)
		$ret .= $this -> int_to_dword(0); // Number of palettes used (4b)
		$ret .= $this -> int_to_dword(0); // Number of important colour (4b) 
		$CC = $ColorCount;
		$sl1 = strlen($ret);
		if ($CC == 0)
			$CC = 256;
		if ($BitCount < 24) {
			$ColorTotal = imagecolorstotal($img);
			if ($IsTransparent)
				$ColorTotal--;

			for ($p = 0; $p < $ColorTotal; $p++) {
				$color = imagecolorsforindex($img, $p);
				$ret .= $this -> inttobyte($color["blue"]);
				$ret .= $this -> inttobyte($color["green"]);
				$ret .= $this -> inttobyte($color["red"]);
				$ret .= $this -> inttobyte(0); //RESERVED
			} 

			$CT = $ColorTotal;
			for ($p = $ColorTotal; $p < $CC; $p++) {
				$ret .= $this -> inttobyte(0);
				$ret .= $this -> inttobyte(0);
				$ret .= $this -> inttobyte(0);
				$ret .= $this -> inttobyte(0); //RESERVED
			} 
		} 

		$retd = ''; // cid added
		if ($BitCount <= 8) {
			for ($y = $Height -1; $y >= 0; $y--) {
				$bWrite = "";
				for ($x = 0; $x < $Width; $x++) {
					$color = imagecolorat($img, $x, $y);
					$bWrite .= $this -> decbinx($color, $BitCount);
					if (strlen($bWrite) == 8) {
						$retd .= $this -> inttobyte(bindec($bWrite));
						$bWrite = "";
					} 
				} 

				if ((strlen($bWrite) < 8) and (strlen($bWrite) != 0)) {
					$sl = strlen($bWrite);
					for ($t = 0; $t < 8 - $sl; $t++)
					$sl .= "0";
					$retd .= $this -> inttobyte(bindec($bWrite));
				} 
				for ($z = 0; $z < $Zbytek; $z++)
				$retd .= $this -> inttobyte(0);
			} 
		} 

		if (($RLE == 1) and ($BitCount == 8)) {
			for ($t = 0; $t < strlen($retd); $t += 4) {
				if ($t != 0)
					if (($t) % $Width == 0)
						$ret .= chr(0) .
						chr(0);
					if (($t + 5) % $Width == 0) {
						$ret .= chr(0) . chr(5) . substr($retd, $t, 5) . chr(0);
						$t += 1;
					} 
					if (($t + 6) % $Width == 0) {
						$ret .= chr(0) . chr(6) . substr($retd, $t, 6);
						$t += 2;
					} else {
						$ret .= chr(0) . chr(4) . substr($retd, $t, 4);
					} 
				} 
				$ret .= chr(0) . chr(1);
			} else {
				$ret .= $retd;
			} 

			if ($BitCount == 24) {
				$Dopl = ''; // cid added
				for ($z = 0; $z < $Zbytek; $z++)
				$Dopl .= chr(0);

				for ($y = $Height -1; $y >= 0; $y--) {
					for ($x = 0; $x < $Width; $x++) {
						$color = imagecolorsforindex($img, ImageColorAt($img, $x, $y));
						$ret .= chr($color["blue"]) . chr($color["green"]) . chr($color["red"]);
					} 
					$ret .= $Dopl;
				} 
			} 

			if ($file != "") {
				$r = ($f = fopen($file, "w"));
				$r = $r and fwrite($f, $ret);
				$r = $r and fclose($f);
				return $r;
			} else {
				echo $ret;
			} 
		} 

		function imagecreatefrombmp($file) {
			$f = @fopen($file, "r");
			$Header = fread($f, 2);
			if ($Header == "BM") {
				$Size = $this -> freaddword($f);
				$Reserved1 = $this -> freadword($f);
				$Reserved2 = $this -> freadword($f);
				$FirstByteOfImage = $this -> freaddword($f);

				$SizeBITMAPINFOHEADER = $this -> freaddword($f);
				$Width = $this -> freaddword($f);
				$Height = $this -> freaddword($f);
				$biPlanes = $this -> freadword($f);
				$biBitCount = $this -> freadword($f);
				$RLECompression = $this -> freaddword($f);
				$WidthxHeight = $this -> freaddword($f);
				$biXPelsPerMeter = $this -> freaddword($f);
				$biYPelsPerMeter = $this -> freaddword($f);
				$NumberOfPalettesUsed = $this -> freaddword($f);
				$NumberOfImportantColors = $this -> freaddword($f);

				if ($biBitCount < 24) {
					$img = imagecreate($Width, $Height);
					$Colors = pow(2, $biBitCount);
					for ($p = 0; $p < $Colors; $p++) {
						$B = $this -> freadbyte($f);
						$G = $this -> freadbyte($f);
						$R = $this -> freadbyte($f);
						$Reserved = $this -> freadbyte($f);
						$Palette[] = imagecolorallocate($img, $R, $G, $B);
					} 

					if ($RLECompression == 0) {
						$Zbytek = (4 - ceil(($Width / (8 / $biBitCount))) % 4) % 4;

						for ($y = $Height -1; $y >= 0; $y--) {
							$this -> CurrentBit = 0;
							for ($x = 0; $x < $Width; $x++) {
								$C = $this -> freadbits($f, $biBitCount);
								imagesetpixel($img, $x, $y, $Palette[$C]);
							} 
							if ($this -> CurrentBit != 0) {
								$this -> freadbyte($f);
							} 
							for ($g = 0; $g < $Zbytek; $g++)
							$this -> freadbyte($f);
						} 
					} 
				} 

				if ($RLECompression == 1) { // $BI_RLE8
					$y = $Height;
					$pocetb = 0;
					while (true) {
						$y--;
						$prefix = $this -> freadbyte($f);
						$suffix = $this -> freadbyte($f);
						$pocetb += 2;

						$echoit = false;

						if ($echoit)
							echo "Prefix: $prefix Suffix: $suffix<BR>";
						if (($prefix == 0) and ($suffix == 1))
							break;
						if (feof($f))
							break;

						while (!(($prefix == 0) and ($suffix == 0))) {
							if ($prefix == 0) {
								$pocet = $suffix;
								$Data .= fread($f, $pocet);
								$pocetb += $pocet;
								if ($pocetb % 2 == 1) {
									$this -> freadbyte($f);
									$pocetb++;
								} 
							} 
							if ($prefix > 0) {
								$pocet = $prefix;
								for ($r = 0; $r < $pocet; $r++)
								$Data .= chr($suffix);
							} 
							$prefix = $this -> freadbyte($f);
							$suffix = $this -> freadbyte($f);
							$pocetb += 2;
							if ($echoit)
								echo "Prefix: $prefix Suffix: $suffix<BR>";
						} 

						for ($x = 0; $x < strlen($Data); $x++) {
							imagesetpixel($img, $x, $y, $Palette[ord($Data[$x])]);
						} 
						$Data = "";
					} 
				} 
				if ($RLECompression == 2) { // $BI_RLE4
					$y = $Height;
					$pocetb = 0;
					while (true) {
						$y--;
						$prefix = $this -> freadbyte($f);
						$suffix = $this -> freadbyte($f);
						$pocetb += 2;

						$echoit = false;

						if ($echoit)
							echo "Prefix: $prefix Suffix: $suffix<BR>";
						if (($prefix == 0) and ($suffix == 1))
							break;
						if (feof($f))
							break;

						while (!(($prefix == 0) and ($suffix == 0))) {
							if ($prefix == 0) {
								$pocet = $suffix;
								$this -> CurrentBit = 0;
								for ($h = 0; $h < $pocet; $h++)
								$Data .= chr($this -> freadbits($f, 4));
								if ($this -> CurrentBit != 0)
									$this -> freadbits($f, 4);
								$pocetb += ceil(($pocet / 2));
								if ($pocetb % 2 == 1) {
									$this -> freadbyte($f);
									$pocetb++;
								} 
							} 
							if ($prefix > 0) {
								$pocet = $prefix;
								$i = 0;
								for ($r = 0; $r < $pocet; $r++) {
									if ($i % 2 == 0) {
										$Data .= chr($suffix % 16);
									} else {
										$Data .= chr(floor($suffix / 16));
									} 
									$i++;
								} 
							} 
							$prefix = $this -> freadbyte($f);
							$suffix = $this -> freadbyte($f);
							$pocetb += 2;
							if ($echoit)
								echo "Prefix: $prefix Suffix: $suffix<BR>";
						} 

						for ($x = 0; $x < strlen($Data); $x++) {
							imagesetpixel($img, $x, $y, $Palette[ord($Data[$x])]);
						} 
						$Data = "";
					} 
				} 

				if ($biBitCount == 24) {
					$img = imagecreatetruecolor($Width, $Height);
					$Zbytek = $Width % 4;

					for ($y = $Height -1; $y >= 0; $y--) {
						for ($x = 0; $x < $Width; $x++) {
							$B = $this -> freadbyte($f);
							$G = $this -> freadbyte($f);
							$R = $this -> freadbyte($f);
							$color = imagecolorexact($img, $R, $G, $B);
							if ($color == -1)
								$color = imagecolorallocate($img, $R, $G, $B);
							imagesetpixel($img, $x, $y, $color);
						} 
						for ($z = 0; $z < $Zbytek; $z++)
						$this -> freadbyte($f);
					} 
				} 
				return $img;
			} 
			fclose($f);
		} 

		function freadbyte($f) {
			return ord(fread($f, 1));
		} 

		function freadword($f) {
			$b1 = $this -> freadbyte($f);
			$b2 = $this -> freadbyte($f);
			return $b2 * 256 + $b1;
		} 

		function freadlngint($f) {
			return $this -> freaddword($f);
		} 

		function freaddword($f) {
			$b1 = $this -> freadword($f);
			$b2 = $this -> freadword($f);
			return $b2 * 65536 + $b1;
		} 

		function RetBits($byte, $start, $len) {
			$bin = $this -> decbin8($byte);
			$r = bindec(substr($bin, $start, $len));
			return $r;
		} 

		function freadbits($f, $count) {
			$Byte = $this -> freadbyte($f);
			$LastCBit = $this -> CurrentBit;
			$this -> CurrentBit += $count;
			if ($this -> CurrentBit == 8) {
				$this -> CurrentBit = 0;
			} else {
				fseek($f, ftell($f) - 1);
			} 
			return $this -> RetBits($Byte, $LastCBit, $count);
		} 

		function RGBToHex($Red, $Green, $Blue) {
			$hRed = dechex($Red);
			if (strlen($hRed) == 1)
				$hRed = "0$hRed";
			$hGreen = dechex($Green);
			if (strlen($hGreen) == 1)
				$hGreen = "0$hGreen";
			$hBlue = dechex($Blue);
			if (strlen($hBlue) == 1)
				$hBlue = "0$hBlue";
			return ($hRed . $hGreen . $hBlue);
		} 

		function int_to_dword($n) {
			return chr($n &255) . chr(($n >> 8) &255) . chr(($n >> 16) &255) . chr(($n >> 24) &255);
		} 

		function int_to_word($n) {
			return chr($n &255) . chr(($n >> 8) &255);
		} 

		function decbin8($d) {
			return $this -> decbinx($d, 8);
		} 

		function decbinx($d, $n) {
			$bin = decbin($d);
			$sbin = strlen($bin);
			for ($j = 0; $j < $n - $sbin; $j++)
			$bin = "0$bin";
			return $bin;
		} 

		function inttobyte($n) {
			return chr($n);
		} 
	} 

	?>
