忍者ブログ

VB.NET-TIPS などプログラミングについて

VB.NETのTIPS(小技集)を中心に、Javascript、PHP その他のプログラミングについて少し役に立つ情報を発信します。いわゆる個人的な忘備録ですが、みなさんのお役に立てれば幸いです。

PHP TCPDFの画像ファイルの出力について(imageメソッド)

PHP PDF出力の方法について・マージンとヘッダ/フッタ(TCPDF)」 の記事ではいきなり Image メソッド使いましたが、今回はこのメソッドについてどの位使えるのかをテストしたいと思います。
Image メソッドの引数は以下の様になっています。

// Imageメソッド
public function Image($file, $x=null, $y=null, $w=0, $h=0, $type='', $link='', $align='', 
					   $resize=false, $dpi=300, $palign='', $ismask=false, $imgmask=false, 
					   $border=0, $fitbox=false, $hidden=false, $fitonpage=false, $alt=false, 
					   $altimgs=array())
// $file      : 画像ファイル名
// $x         : 領域左上のX座標[指定しない場合、現在のX座標位置]
// $y         : 領域左上のY座標[指定しない場合、現在のY座標位置]
// $w         : 領域の幅 [指定しない場合、自動計算される]
// $h         : 領域の高さ [指定しない場合、自動計算される]
// $type      : 画像フォーマット("JPEG", "PNG")
// $link      : AddLink()で作成したリンク識別子
// $align     : 次の画像を表示する位置
//             [T]: top-right for LTR or top-left for RTL
//             [M]: middle-right for LTR or middle-left for RTL
//             [B]: bottom-right for LTR or bottom-left for RTL
//             [N]: next line
// $resize    : [true]画像サイズを$wや$hに合わせてリサイズ
// $dpi       : 解像度(dot per inch)
// $palign    : 画像を現在の行のどこに配置するか
//             [L] : 左端
//             [C] : 中央
//             [R] : 右端
//             ['']: 左端(RTLの場合は右端)
// $ismask    : [true]画像をマスクする場合
// $imgmask   : 画像オブジェクトをメソッドの戻り値として取得する
//              (描画しない、w、h、x、yは無視される)場合true
// $border    : 境界線表示(0:枠無し,1:枠有 または "LRTB"の文字列で「左右上下」を指定)
// $fitbox    : [ture]($w, $h)で指定する領域に合わせて拡縮
// $hidden    : [ture]画像を画面に表示しない
// $fitonpage : [ture]ページの大きさに拡大する
// $alt       : If true the image will be added as alternative and not directly printed
//              (the ID of the image will be returned).
// $altimgs   : Array of alternate images IDs. Each alternative image must be an array with two values: 
//              an integer representing the image ID (the value returned by the Image method)
//              and a boolean value to indicate if the image is the default for printing. 



以下の各種のテストをしてみます。




■画像の大きさ・リサイズ

画像データは以下のものを使います。画像の大きさは「100×30」ピクセルです。


この画像を使って以下の表示をテストします。

  • 画像の横幅・高さを指定しないでそのまま表示
  • 画像の横幅・高さを指定して表示(20×6 mm)
  • 画像の横幅・高さを指定して表示(100×30 mm)
  • 画像の横幅・高さを指定して表示(100×30 mm) リサイズ指定有り

<?php
require_once('../tcpdf/tcpdf.php');
// クラス生成
$pdf = new TCPDF();
// デフォルトで用意されている日本語フォント[小塚ゴシックPro M]
$strFont = "kozgopromedium";
// ヘッダ・フッタ出力設定(特にいらないが)
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
// 本文の日本語フォント[小塚ゴシックPro M]
$pdf->SetFont($strFont, "", 10);

// 新しいpdfページを追加
$pdf->AddPage();

// HTMLの定義
$strOut = '<h1>HTML Imageテスト</h1>';
$pdf->writeHTML($strOut, true, false, true, false, '');

$strOut = '画像の横幅・高さを指定しないでそのまま表示(100×30 px)';
$pdf->cell(0, 0, $strOut, 0, 1);

$pdf->Image('test-logo.png', null, null, 0, 0, 'PNG', '', 'N');

$unit = $pdf->pixelsToUnits(100);//px => mm
$strOut = '画像の横幅(100px ==> mm 換算):'.$unit.'mm (pixelsToUnitsメソッド使用)';
$pdf->cell(0, 0, $strOut, 0, 1);
$pdf->cell(0, 0, '', 0, 1);

$strOut = '画像の横幅・高さを指定して表示(20×6 mm)';
$pdf->cell(0, 0, $strOut, 0, 1);
$pdf->Image('test-logo.png', null, null, 20, 6, 'PNG', '', 'N', false,300);
$pdf->cell(0, 0, '', 0, 1);

$strOut = '画像の横幅・高さを指定して表示(100×30 mm)';
$pdf->cell(0, 0, $strOut, 0, 1);
$pdf->Image('test-logo.png', null, null, 100, 30, 'PNG', '', 'N', false);
$strOut = '画像の横幅・高さを指定して表示(100×30 mm) (resize:true 指定)';
$pdf->cell(0, 0, $strOut, 0, 1);
$pdf->Image('test-logo.png', null, null, 100, 30, 'PNG', '', 'N', true, 300);

// pdf表示設定
$pdf->Output('pdf-img-5-1.pdf', 'I');
?>

これの実行結果は以下の通りです。


「画像の横幅・高さを指定しないでそのまま表示」の場合は実際PDF上でどのくらいの大きさで表示されるのかと言いますと、 画像データのピクセル値から DPI を加味して以下の計算で分かります。 (pixelsToUnits メソッドを使用すればピクセルからPDF上の長さが分かります。)

「画像のPDF上の横幅(mm)」=「画像の横幅ピクセル値」/(「PDFでの指定DPI」/「25.4」)

この画像の場合は、以下の計算となります。
「画像のPDF上の横幅(mm)」=「100px」/(「72」/「25.4」)=「35.2777…」
(「DPI」のデフォルトは「72」になっています)

「画像の横幅・高さを指定して表示(20×6 mm)」では指定通り「20×6 mm」に縮小された表示になっています。
また、「画像の横幅・高さを指定して表示(100×30 mm)」では指定通り「100×30 mm」に拡大された表示になっています。
最後のリサイズ指定を「true」にした場合ですが、指定しない場合との違いが良くわかりませんでした。 指定の仕方が悪いのかそれともテストした画像データが適切ではなかったのか?機会があればもう少し調べたいと思います。

■次の画像位置指定・現在行の表示位置

「次の画像位置指定」は「$align」の引数ですが指示内容は以下の通りです。

  • 'T' 画像TOPでかつ右端
  • 'M' 画像縦方向の中央でかつ右端
  • 'T' 画像BOTTOMでかつ右端
  • 'N' 次の行


この指定は、画像表示が終わった時点でカレントのX,Y座標をどの位置にするかを示します。

「現在行の表示位置」は「$palign」の引数ですが指示内容は以下の通りです。

  • 'L' 左揃え
  • 'C' 中央揃え
  • 'R' 右揃え
  • '' 左揃え(RTLの場合は右端)

<?php
require_once('../tcpdf/tcpdf.php');
// クラス生成
$pdf = new TCPDF();
// デフォルトで用意されている日本語フォント[小塚ゴシックPro M]
$strFont = "kozgopromedium";
// ヘッダ・フッタ出力設定(特にいらないが)
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
// 本文の日本語フォント[小塚ゴシックPro M]
$pdf->SetFont($strFont, "", 10);

// 新しいpdfページを追加
$pdf->AddPage();

// HTMLの定義
$strOut = '<h1>HTML Imageテスト</h1>';
$pdf->writeHTML($strOut, true, false, true, false, '');

// 元の画像そのまま
$pdf->writeHTML('<h4>元の画像(サイズ指定無し)</h4>', true, false, true, false, '');
$pdf->Image('test-logo.png', null, null, 0, 0, 'PNG');

// $align : 次の画像を表示する位置
$pdf->SetXY(0, 35);
$pdf->writeHTML('<h4>次の画像の表示位置「$align」</h4>', true, false, true, false, '');
$pdf->Image('test-logo.png', null,   40, 0, 0, 'PNG', '', 'T'); //top-right
$pdf->Image('test-logo.png', null, null, 0, 0, 'PNG', '', 'M'); //middle-right
$pdf->Image('test-logo.png', null, null, 0, 0, 'PNG', '', 'B'); //bottom-right
$pdf->Image('test-logo.png', null, null, 0, 0, 'PNG', '', 'N'); //next line
$pdf->Image('test-logo.png', null, null, 0, 0, 'PNG', '', 'N'); //next line

// $palign    : 画像を現在の行のどこに配置するか
$pdf->SetXY(0, 80);
$pdf->writeHTML('<h4>現在行の配置指定「$palign」</h4>', true, false, true, false, '');
$pdf->writeHTML('<h4>・幅[50mm]指定・左寄せ</h4>', true, false, true, false, '');
$pdf->Image('test-logo.png', null, null, 40, 0, 'PNG', '', 'N', false, 300, 'L');
$pdf->writeHTML('<h4>・幅[50mm]指定・中央揃え</h4>', true, false, true, false, '');
$pdf->Image('test-logo.png', null, null, 40, 0, 'PNG', '', 'N', false, 300, 'C');
$pdf->writeHTML('<h4>・幅[50mm]指定・右寄せ</h4>', true, false, true, false, '');
$pdf->Image('test-logo.png', null, null, 40, 0, 'PNG', '', 'N', false, 300, 'R');

// pdf表示設定
$pdf->Output('pdf-img-5-2.pdf', 'I');
?>
?>

実行結果は以下の様な表示になります。



■幅・高さ($w, $h)指定領域に合わせて拡縮

幅・高さ($w, $h)指定領域に合わせて拡縮を行う引数である「$fitbox」についてテストを行います。

「$fitbox」は2文字で指定し、1文字目は水平方向の配置指定で、2文字目は垂直方向の配置指定となります。

「1文字目は水平方向」

  • 'L' 左寄せ
  • 'C' 中央揃え
  • 'R' 右寄せ

「2文字目は垂直方向」

  • 'T' 上寄せ
  • 'M' 中央揃え
  • 'B' 下寄せ


3種類ずつなので9種類の組み合わせがります。 但し、画像のサイズと描画領域($w, $h)の値により表示がいろいろあります。

<?php
require_once('../tcpdf/tcpdf.php');
// クラス生成
$pdf = new TCPDF();
// デフォルトで用意されている日本語フォント[小塚ゴシックPro M]
$strFont = "kozgopromedium";
// ヘッダ・フッタ出力設定(特にいらないが)
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
// 本文の日本語フォント[小塚ゴシックPro M]
$pdf->SetFont($strFont, "", 10);

// 新しいpdfページを追加
$pdf->AddPage();

// HTMLの定義
$strOut = '<h1>HTML Imageテスト</h1>';
$pdf->writeHTML($strOut, true, false, true, false, '');

$pdf->Image('test-logo.png', null, null, 0, 0, 'PNG', '', 'N');
$unit = $pdf->pixelsToUnits(100);//px => mm
$strOut = '画像の横幅(100px ==> mm 換算):'.$unit.'mm (pixelsToUnitsメソッド使用)';
$pdf->MultiCell( 0, 0, $strOut, 0, '', false, 1, 50, 18);
$unit = $pdf->pixelsToUnits(30);//px => mm
$strOut = '画像の高さ( 30px ==> mm 換算):'.$unit.'mm (pixelsToUnitsメソッド使用)';
$pdf->MultiCell( 0, 0, $strOut, 0, '', false, 1, 50, 23);

// 引数「fitbox」用alignment
$h_align = array('L', 'C', 'R');
$v_align = array('T', 'M', 'B');

$x = 15;
$y = 32;
$w = 30;
$h = 7;
// 横方向のアライメント
for ($i = 0; $i < 3; ++$i) {
	$x = 15;
	for ($j = 0; $j < 3; ++$j) {
		$fitbox = $h_align[$i].$v_align[$j];
		$pdf->Rect($x, $y, $w, $h, 'F', array(), array(128,255,128));
		$pdf->Image('test-logo.png', $x, $y, $w, $h, 'PNG', '', '', false, 300, '', false, false, 0,
                       $fitbox, false, false);
        $pdf->MultiCell( 0, 0, '$fitbox = '.$fitbox, 0, '', false, 1, $x, $y + $h);
		$x += 62; // カラムを右へ
	}
	$y += 14; // 次の行
}


$x = 15;
$y += 2;
$w = 30;
$h = 15;
// 縦方向のアライメント
for ($i = 0; $i < 3; ++$i) {
	$x = 15;
	for ($j = 0; $j < 3; ++$j) {
		$fitbox = $h_align[$i].$v_align[$j];
		$pdf->Rect($x, $y, $w, $h, 'F', array(), array(255,128,128));
		$pdf->Image('test-logo.png', $x, $y, $w, $h, 'PNG', '', '', false, 300, '', false, false, 0,
                       $fitbox, false, false);
        $pdf->MultiCell( 0, 0, '$fitbox = '.$fitbox, 0, '', false, 1, $x, $y + $h);
		$x += 62; // カラムを右へ
	}
	$y += ($h + 6); // 次の行
}

// pdf表示設定
$pdf->Output('pdf-img-5-3.pdf', 'I');
?>

実行結果は以下の様な表示になります。


この表示領域の配置指定は、画像のサイズと描画領域($w, $h)の値により表示のされ方が独特です。

最初の9個のブロック(背景が黄緑色)は1文字目の指定の水平方向しか動作していない様に見えます。
また、その下の9個のブロック(背景が薄赤色)は2文字目の指定の垂直方向しか動作していない様に見えます。

最初のブロックの場合、「$w = 30」「$h = 7」(単位はmm)で指定しています。
画像の大きさは「100×30px」ですので横を基準とした場合の「縦」を計算します。
「縦」=「30($w)」×(「30px」/「100px」)=「9」mm
「縦=9mm」では指定の「$h = 7」を超えてしまうので、逆に「$h = 7」を基準にして「横」を計算します。
「横」=「7($h)」×(「100px」/「30px」)=「23.3…」mm
「横=23.3…mm」で指定の「$w = 30」におさまります。 よって、垂直方向は一杯になり水平方向しか配置が動作しない様に見えるわけです。


2番目のブロックの場合、「$w = 30」「$h = 15」(単位はmm)で指定しています。
画像の大きさは「100×30px」ですので横を基準とした場合の「縦」を計算します。
「縦」=「30($w)」×(「30px」/「100px」)=「9」mm
さらにに「$h = 15」を基準にして「横」を計算します。
「横」=「15($h)」×(「100px」/「30px」)=「50」mm
「横=50mm」のため「$w = 30」の指定を超えてしまいます。 よって、「縦=9mm」の画像として、水平方向は一杯になり垂直方向しか配置が動作しない様に見えるわけです。












PR

コメント

コメントを書く