質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.52%

TCPDFで日本語テキストと画像を出力する場合の文字化けについて

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,060

shinjism

score 9

Unityで作成したWindows PCアプリから、PDF生成を行うPHPスクリプトに対して日本語テキストと100KB未満の画像(バイナリデータ)をpostし、PDF出力を行っています。

日本語テキストのみpostした場合は、文字化けなく正常に出力されます。
日本語テキストと画像1点をpostした場合は、画像は正常に出力されますが、日本語テキストの文字化けが発生します。
PHPスクリプトの画像出力箇所をコメントアウトして、日本語テキストと画像1点をpostした場合も、日本語テキストの文字化けが発生します。

メモリ不足が問題ではないかと思い、ini_set関数やphp.iniなどでmemory_limitを128M、256M、512Mと変えてみましたが、結果は変わりませんでした。

もし、上記の現象や原因に関する情報やヒントがございましたら、ご教示よろしくお願い致します。
環境は次のとおりです。

Windows 10 Pro 64bit
XAMPP 5.6.15 (PHP 5.6.15)
TCPDF 6.2.12
Unity 5.2.3f1
※Windows PCアプリとXAMPP環境は同一PC内に共存

送信側サンプルコード

private IEnumerator PostWithBinary2(byte[] byteData, System.Action<WWW> callback)
{
    string url = "http://localhost/report/sample.php";

    WWWForm form = new WWWForm();
    form.AddField("title", "日本語タイトル");
    form.AddField("date", "2016-01-01");
    form.AddField("copyright", "Copyright (C) 2016 日本語著作者. All Rights Reserved");
    form.AddBinaryData("picture", byteData, "picture.png", "image/png");

    WWW www = new WWW(url, form);
    yield return www;

    if (callback != null)
    {
        callback(www);
    }
}


受信側サンプルコード

<?php
ini_set('memory_limit','128M');
require_once('./tcpdf/tcpdf.php');

// Extend the TCPDF class to create custom Header and Footer
class MYPDF extends TCPDF
{
    private $hTitle='';
    private $hDate='';
    private $fCopyright='';

    //Constructor
    function __construct($orientation,$unit,$format,$unicode,$encoding,$diskcache,$pdfa,$title,$date,$copyright)
    {
        parent::__construct($orientation,$unit,$format,$unicode,$encoding,$diskcache,$pdfa);
        $this->hTitle=$title;
        $this->hDate=$date;
        $this->fCopyright=$copyright;
    }

    //Page header
    public function Header() {
        // Logo
        $imageFile=dirname(__FILE__).'/logo.jpg';
        if(file_exists($imageFile))
        {
            $this->Image($imageFile,10,15,32,0,'JPG','','T',false,150,'',false,false,0,false,false,false);
        }
        // Title
        $this->SetXY(50,22.5);
        $this->SetFont('cid0jp','B',16);
        $this->Cell(110,20,$this->hTitle,0,false,'C',0,'',0,false,'L','M');
        // Date
        $this->SetX(190);
        $this->SetFont('cid0jp','',14);
        $this->Cell(0,20,$this->hDate,0,false,'R',0,'',0,false,'L','M');
     }

    // Page footer
    public function Footer() {
        // Copyright
        $this->SetY(-15);
        $this->SetFont('cid0jp','',10);
        $this->Cell(0,10,$this->fCopyright,0,false,'C',0,'',0,false,'T','M');
    }
}

// check Image
function checkImage($file)
{
    if($file['type']!='image/png')
    {
        return false;
    }
    if($file['error']>0)
    {
        return false;
    }
    if(!move_uploaded_file($file['tmp_name'],dirname(__FILE__).'/images/'.$file['name']))
    {
        return false;
    }
    return true;
}

// create new PDF document
$pdf=new MYPDF(PDF_PAGE_ORIENTATION,PDF_UNIT,PDF_PAGE_FORMAT,true,'UTF-8',false,false,$_POST['title'],$_POST['date'],$_POST['copyright']);
$pdf->setHeaderData(PDF_HEADER_LOGO,PDF_HEADER_LOGO_WIDTH,PDF_HEADER_TITLE,PDF_HEADER_STRING);
$pdf->setHeaderFont(Array('cid0jp','',14));
$pdf->AddPage();
$pdf->SetFont('cid0jp','',14);
$pdf->SetFillColor(230);

// output Image
if(array_key_exists('picture',$_FILES))
{
    $file=$_FILES['picture'];
    if (checkImage($file))
    {
        $x=10;
        $y=125;
        $pdf->Image(dirname(__FILE__).'/images/'.$file['name'],$x,$y,92,0,'PNG','','',true,200,'',false,false,1,false,false,false);
    }
}

// save PDF
$reportFile=dirname(__FILE__).'/report.pdf';
if(file_exists($reportFile))
{
    unlink($reportFile);
}
$pdf->Output($reportFile,'F');

// return JSON
$json = array(
    'resultReportFile'=>(empty($_SERVER['HTTPS'])?'http://':'https://').$_SERVER['HTTP_HOST'].(dirname($_SERVER['SCRIPT_NAME']).'/report.pdf'),
    'error'=>'',
);
header('Content-Type: application/json');
echo json_encode($json);
?>


文字化けしなかった例
ヘッダー部とフッター部に日本語テキスト出力。左上の青い箇所はPHPスクリプトと同じ場所にある画像を出力。
文字化けした例
ヘッダー部とフッター部に日本語テキスト出力。中央の画像がpostしたもの。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

+1

自己解決です。

multipart/form-dataでファイルをアップすると文字化けするという情報が、随分前のものでしたがありました。
マルチパートフォームの挙動に注意する

そこでひとまず、php.iniを次のように変更しました。

変更前: mbstring.http_input = auto
変更後: mbstring.http_input = UTF-8

こちらを参考にしました。
mbstring.encoding_translationが原因で文字化け

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.52%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる