PHP : GD で Windows のビットマップを扱う

  BMP => GD



どちらの変換も オンラインの PHP のマニュアルの投稿部分に使えるコードがあります。
少なくとも、GD から BMP への変換は、実際に使わせてもらいました。(ハートアイコンエディタ)

※ "vfile_type/Vfile_size/Vreserved/Vbitmap_offset" は、全て符号なしの 16(2) 32(4) 32(4) 32(4) で14バイトです

to create an image from a BMP file
<?
header("Content-type: image/png");
header("Content-Disposition: attachment; filename=winofsql.png");
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );

$im = ImageCreateFromBMP("winofsql.bmp");
imagepng($im);
imagedestroy($im);

// *********************************************************
// Windows BMP を読み込んで GD のリソースに変換する
// http://jp.php.net/manual/ja/function.imagecreate.php#53879
// *********************************************************
function ImageCreateFromBMP($filename)
{
 // ファイルを開く
	if (! $f1 = fopen($filename,"rb")) return FALSE;

 // 読み込み1
	$FILE = unpack("vfile_type/Vfile_size/Vreserved/Vbitmap_offset", fread($f1,14));
	if ($FILE['file_type'] != 19778) return FALSE;

 // 読み込み2 
	$BMP = unpack('Vheader_size/Vwidth/Vheight/vplanes/vbits_per_pixel'.
		  '/Vcompression/Vsize_bitmap/Vhoriz_resolution'.
		  '/Vvert_resolution/Vcolors_used/Vcolors_important', fread($f1,40));
	$BMP['colors'] = pow(2,$BMP['bits_per_pixel']);
	if ($BMP['size_bitmap'] == 0) $BMP['size_bitmap']
		 = $FILE['file_size'] - $FILE['bitmap_offset'];
	$BMP['bytes_per_pixel'] = $BMP['bits_per_pixel']/8;
	$BMP['bytes_per_pixel2'] = ceil($BMP['bytes_per_pixel']);
	$BMP['decal'] = ($BMP['width']*$BMP['bytes_per_pixel']/4);
	$BMP['decal'] -= floor($BMP['width']*$BMP['bytes_per_pixel']/4);
	$BMP['decal'] = 4-(4*$BMP['decal']);
	if ($BMP['decal'] == 4) $BMP['decal'] = 0;

 // パレット
	$PALETTE = array();
	if ($BMP['colors'] < 16777216)
	{
	 $PALETTE = unpack('V'.$BMP['colors'], fread($f1,$BMP['colors']*4));
	}

 // 本体部分の変換 
	$IMG = fread($f1,$BMP['size_bitmap']);
	$VIDE = chr(0);

	$res = imagecreatetruecolor($BMP['width'],$BMP['height']);
	$P = 0;
	$Y = $BMP['height']-1;
	while ($Y >= 0)
	{
	 $X=0;
	 while ($X < $BMP['width'])
	 {
	  if ($BMP['bits_per_pixel'] == 24)
		  $COLOR = unpack("V",substr($IMG,$P,3).$VIDE);
	  elseif ($BMP['bits_per_pixel'] == 16)
	  {  
		  $COLOR = unpack("n",substr($IMG,$P,2));
		  $COLOR[1] = $PALETTE[$COLOR[1]+1];
	  }
	  elseif ($BMP['bits_per_pixel'] == 8)
	  {  
		  $COLOR = unpack("n",$VIDE.substr($IMG,$P,1));
		  $COLOR[1] = $PALETTE[$COLOR[1]+1];
	  }
	  elseif ($BMP['bits_per_pixel'] == 4)
	  {
		  $COLOR = unpack("n",$VIDE.substr($IMG,floor($P),1));
		  if (($P*2)%2 == 0) $COLOR[1] = ($COLOR[1] >> 4) ;
			else $COLOR[1] = ($COLOR[1] & 0x0F);
		  $COLOR[1] = $PALETTE[$COLOR[1]+1];
	  }
	  elseif ($BMP['bits_per_pixel'] == 1)
	  {
		  $COLOR = unpack("n",$VIDE.substr($IMG,floor($P),1));
		  if	  (($P*8)%8 == 0) $COLOR[1] =  $COLOR[1]		  >>7;
		  elseif (($P*8)%8 == 1) $COLOR[1] = ($COLOR[1] & 0x40)>>6;
		  elseif (($P*8)%8 == 2) $COLOR[1] = ($COLOR[1] & 0x20)>>5;
		  elseif (($P*8)%8 == 3) $COLOR[1] = ($COLOR[1] & 0x10)>>4;
		  elseif (($P*8)%8 == 4) $COLOR[1] = ($COLOR[1] & 0x8)>>3;
		  elseif (($P*8)%8 == 5) $COLOR[1] = ($COLOR[1] & 0x4)>>2;
		  elseif (($P*8)%8 == 6) $COLOR[1] = ($COLOR[1] & 0x2)>>1;
		  elseif (($P*8)%8 == 7) $COLOR[1] = ($COLOR[1] & 0x1);
		  $COLOR[1] = $PALETTE[$COLOR[1]+1];
	  }
	  else
		  return FALSE;
	  imagesetpixel($res,$X,$Y,$COLOR[1]);
	  $X++;
	  $P += $BMP['bytes_per_pixel'];
	 }
	 $Y--;
	 $P+=$BMP['decal'];
	}

 // ファイルを閉じる
	fclose($f1);

 return $res;
}
?>







  GD => BMP



If you happen to need a way to output a Windows BMP file
<?
header("Content-type: image/bmp");
header("Content-Disposition: attachment; filename=winofsql.bmp");
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );

$im = imagecreatefrompng("winofsql.png");
imagebmp($im);
imagedestroy($im);

// *********************************************************
// GD のリソースから Windows BMP に変換する
// http://www.php.net/manual/ja/ref.image.php#63689
// 第二引数を省略すると、ブラウザに出力します
// *********************************************************
function imagebmp ($im, $fn = false) {
	if (!$im) return false;
			
	if ($fn === false) $fn = 'php://output';
	$f = fopen ($fn, "w");
	if (!$f) return false;
			
	//Image dimensions
	$biWidth = imagesx ($im);
	$biHeight = imagesy ($im);
	$biBPLine = $biWidth * 3;
	$biStride = ($biBPLine + 3) & ~3;
	$biSizeImage = $biStride * $biHeight;
	$bfOffBits = 54;
	$bfSize = $bfOffBits + $biSizeImage;
			
	//BITMAPFILEHEADER
	fwrite ($f, 'BM', 2);
	fwrite ($f, pack ('VvvV', $bfSize, 0, 0, $bfOffBits));
			
	//BITMAPINFO (BITMAPINFOHEADER)
	fwrite (
		$f,
		pack (
			'VVVvvVVVVVV',
			40,
			$biWidth,
			$biHeight,
			1,
			24,
			0,
			$biSizeImage, 0, 0, 0, 0
		)
	);
			
	$numpad = $biStride - $biBPLine;
	for ($y = $biHeight - 1; $y >= 0; --$y)
	{
		for ($x = 0; $x < $biWidth; ++$x)
		{
			$col = imagecolorat ($im, $x, $y);
			fwrite ($f, pack ('V', $col), 3);
		}
		for ($i = 0; $i < $numpad; ++$i)
			fwrite ($f, pack ('C', 0));
	}
	fclose ($f);
	return true;
}
?>

















   SQLの窓    create:2009/10/30  update:2018/02/23   管理者用(要ログイン)





フリーフォントツール

SQLの窓ツール

SQLの窓フリーソフト

写真素材

一般ツールリンク

SQLの窓

フリーソフト

JSライブラリ