_obj = new Archive_Zip($file); } function addFile($file, $filename) { rename($file, $filename); $this->_obj->add($filename); unlink($filename); } function close() { } } } ini_set('memory_limit', '512M'); set_time_limit(300); define('QUALITY_MIN', 0); define('QUALITY_MAX', 4095); $qualitys = range(QUALITY_MIN, QUALITY_MAX); $qualitys[0] = '自動'; // エンコード if (isset($_REQUEST['func']) && $_REQUEST['func'] == 'encode') { $fileName = $_FILES['file']['name']; $tmp_name = $_FILES['file']['tmp_name']; $backName = $_FILES['back']['name']; $backtmp_name = $_FILES['back']['tmp_name']; $quality = $_REQUEST['quality']; if (is_uploaded_file($tmp_name) && is_uploaded_file($backtmp_name) && array_key_exists($quality, $qualitys)) { // 格納データをzipに梱包 $tmpFile = uniqid('./', true); $zip = new ZipArchive(); $zip->open($tmpFile, ZipArchive::CREATE); $zip->addFile($tmp_name, mb_convert_encoding($fileName, 'Shift_JIS', 'UTF-8')); $zip->close(); $src = file_get_contents($tmpFile); unlink($tmpFile); // RGBデータに変換 $hex = bin2hex($src); $hexLength = strlen($hex); $hexLengthHex = dechex($hexLength); // 先頭にquality情報 $rgbs[0] = str_pad(dechex($quality), 3, 0, STR_PAD_LEFT); $lengthRgbs = str_split(str_pad($hexLengthHex, 6, 0, STR_PAD_LEFT), 3); $rgbs = array_merge($rgbs, $lengthRgbs, str_split($hex, 3)); $rgbsCount = count($rgbs); $rgbs[$rgbsCount - 1] = str_pad($rgbs[$rgbsCount - 1], 3, 0); // 背景用データを取得 list($backWidth, $backHeight, $backType) = getimagesize($backtmp_name); // 背景データのpixel数 $pixels = $backWidth * $backHeight; // qualityが0ならば自動的に算出する if ($quality == 0) { $quality = floor($pixels / $rgbsCount); if (QUALITY_MAX < $quality) { $quality = QUALITY_MAX; } // データを差し替える $rgbs[0] = str_pad(dechex($quality), 3, 0, STR_PAD_LEFT); } // pixel数が足りない if ($pixels < $rgbsCount * $quality || $quality <= 0) { echo 'back ground image is smaller than include data.'; return; } // 画像を読み取る switch($backType) { case IMAGETYPE_GIF: $pallet = imagecreatefromgif($backtmp_name); break; case IMAGETYPE_JPEG: $pallet = imagecreatefromjpeg($backtmp_name); break; case IMAGETYPE_PNG: $pallet = imagecreatefrompng($backtmp_name); break; // case IMAGETYPE_BMP: // $pallet = imagecreatefrombmp($backtmp_name); // break; default: echo 'not image.'; return false; } // イメージリソースの取得に失敗 if (!$pallet) { echo 'fail get image resource.'; return; } // 出力用意 $axisX = 0; $axisY = 0; foreach ($rgbs as $rgb) { // RGB情報を分割 list($red, $green, $blue) = str_split($rgb, 1); // 背景の色情報を読み取る $color = imagecolorat($pallet, $axisX, $axisY); $backRed = dechex(($color >> 16) & 0xFF); $backGreen = dechex(($color >> 8) & 0xFF); $backBlue = dechex($color & 0xFF); $backRed = str_pad($backRed, 2, 0, STR_PAD_LEFT); $backGreen = str_pad($backGreen, 2, 0, STR_PAD_LEFT); $backBlue = str_pad($backBlue, 2, 0, STR_PAD_LEFT); // 色情報を統合 $red = $backRed[0] . $red; $green = $backGreen[0] . $green; $blue = $backBlue[0] . $blue; $color = imagecolorallocate($pallet, hexdec($red), hexdec($green), hexdec($blue)); imagesetpixel($pallet, $axisX, $axisY, $color); $axisX += $quality; if ($backWidth <= $axisX) { $axisX -= $backWidth; $axisY++; } } $mimeType = 'image/png'; $fileName = mb_convert_encoding(substr($backName, 0, strrpos($backName, '.')), 'Shift_JIS', 'UTF-8') . '_' . $quality . '.png'; header("Content-type: {$mimeType}"); header('Content-Disposition: attachment; filename="' . $fileName . '"'); imagepng($pallet, null, 9); exit; } } // デコード if (isset($_REQUEST['func']) && $_REQUEST['func'] == 'decode') { $fileName = $_FILES['file']['name']; $tmp_name = $_FILES['file']['tmp_name']; if (is_uploaded_file($tmp_name)) { $pallet = imagecreatefrompng($tmp_name); $width = imagesx($pallet); $height = imagesy($pallet); $area = $width * $height; $axisX = $axisY = 0; $rgbs = array(); for ($i = 0; $i < $area; $i++) { $color = imagecolorat($pallet, $axisX, $axisY); $red = dechex(($color >> 16) & 0xFF); $green = dechex(($color >> 8) & 0xFF); $blue = dechex($color & 0xFF); $red = str_pad($red, 2, 0, STR_PAD_LEFT); $green = str_pad($green, 2, 0, STR_PAD_LEFT); $blue = str_pad($blue, 2, 0, STR_PAD_LEFT); $rgbs[] = $red[1] . $green[1] . $blue[1]; $axisX++; if ($axisX == $width) { $axisX = 0; $axisY++; } } // 先頭セルより画質情報を取得する $quality = hexdec($rgbs[0]); // RGBデータから有効な情報だけを取得する $selectedRgbs = array(); $count = count($rgbs); for ($i = 0; $i < $count; $i++) { if ($i % $quality == 0) { $selectedRgbs[] = $rgbs[$i]; } } $rgbs = $selectedRgbs; unset($selectedRgbs); // 有効データ長を計算 $hexLength = hexdec($rgbs[1] . $rgbs[2]); // データ(配列)を文字列に展開 $hex = implode('', array_slice($rgbs, 3)); unset($rgbs); // バイナリを復元 $source = pack('H*', substr($hex, 0, $hexLength)); $mimeType = 'application/zip'; $fileName = mb_convert_encoding(substr($fileName, 0, strrpos($fileName, '.')), 'Shift_JIS', 'UTF-8') . '.zip'; header("Content-type: {$mimeType}"); header('Content-Disposition: attachment; filename="' . $fileName . '"'); print($source); exit; } } ?>