2012-05-06 38 views
3

このスタックの質問は修正されました:Applying watermarks on pdf files when users try to download the filesしかし、修正方法についてのコメントがありましたが、それほど精巧ではありませんでしたが、エラーが発生しました。ここでFPDI/FPDF:ウォーターマークと複数のページの印刷

はコードです:私は、2以上のものを持っているPDFファイルをロードすると

require_once('fpdf/fpdf.php'); 
require_once('fpdi/fpdi.php'); 

class WaterMark 

{ 
    public $pdf, $file, $newFile, 
     $wmText = "STACKOVERFLOW"; 

/** $file and $newFile have to include the full path. */ 
public function __construct($file, $newFile) 
{ 
    $this->pdf = new FPDI(); 
    $this->file = $file; 
    $this->newFile = $newFile; 
} 

/** $file and $newFile have to include the full path. */ 
public static function applyAndSpit($file, $newFile) 
{ 
    $wm = new WaterMark($file, $newFile); 

    if($wm->isWaterMarked()) 
     return $wm->spitWaterMarked(); 
    else{ 
     $wm->doWaterMark(); 
     return $wm->spitWaterMarked(); 
    } 
} 

/** @todo Make the text nicer and add to all pages */ 
public function doWaterMark() 
{ 
    $currentFile = $this->file; 
    $newFile = $this->newFile; 

    $this->pdf->addPage(); 
    $pagecount = $this->pdf->setSourceFile($currentFile); 

    for($i = 1; $i <= $pagecount; $i++){ 
     $tplidx = $this->pdf->importPage($i); 
     $this->pdf->useTemplate($tplidx, 10, 10, 100); 
     // now write some text above the imported page 
     $this->pdf->SetFont('Arial', 'I', 40); 
     $this->pdf->SetTextColor(255,0,0); 
     $this->pdf->SetXY(25, 135); 
     $this->_rotate(55); 
     $this->pdf->Write(0, $this->wmText); 
    } 

    $this->pdf->Output($newFile, 'F'); 
} 

public function isWaterMarked() 
{ 
    return (file_exists($this->newFile)); 
} 

public function spitWaterMarked() 
{ 
    return readfile($this->newFile); 
} 

protected function _rotate($angle,$x=-1,$y=-1) { 

    if($x==-1) 
     $x=$this->pdf->x; 
    if($y==-1) 
     $y=$this->pdf->y; 
    if($this->pdf->angle!=0) 
     $this->pdf->_out('Q'); 
    $this->pdf->angle=$angle; 

    if($angle!=0){ 
     $angle*=M_PI/180; 
     $c=cos($angle); 
     $s=sin($angle); 
     $cx=$x*$this->pdf->k; 
     $cy=($this->pdf->h-$y)*$this->pdf->k; 

     $this->pdf->_out(sprintf(
      'q %.5f %.5f %.5f %.5f %.2f %.2f cm 1 0 0 1 %.2f %.2f cm', 
      $c,$s,-$s,$c,$cx,$cy,-$cx,-$cy)); 
    } 
    } 

} 
header('Content-type: application/pdf'); 
//header('Content-Disposition: attachment; filename="downloaded.pdf"'); 
WaterMark::applyAndSpit('C:\xampp\htdocs\tst\test0.pdf','C:\xampp\htdocs\tst\output0.pdf'); 

ページのすべて1つのページにマージします。この投稿に画像を添付しました。 enter image description here

ありがとうございました。

+0

@vascowhiteこれに対処する方法はありますか? –

+0

実際はそうではありませんが、挿入されているものを確認することから始めます。ページ全体が回転したように見えます。申し訳ありませんが、私はfpdfの経験が豊富です。私はそれを使用しましたが、非常に基本的なもののためだけです。後で今日遊ぶチャンスがあれば、私は何を見つけることができるでしょう。がんばろう。 – vascowhite

+0

あなたはこれを見ましたか? http://www.setasign.de/products/pdf-php-solutions/setapdf-stamper/ – vascowhite

答えて

6

私は、このスクリプトにいくつか間違っていることを発見しました。それはこれにdoWatermark()方法を変更する作業を取得するには: -

public function doWaterMark() 
{ 
    $currentFile = $this->file; 
    $newFile = $this->newFile; 

    $pagecount = $this->pdf->setSourceFile($currentFile); 

    for($i = 1; $i <= $pagecount; $i++){ 
     $this->pdf->addPage();//<- moved from outside loop 
     $tplidx = $this->pdf->importPage($i); 
     $this->pdf->useTemplate($tplidx, 10, 10, 100); 
     // now write some text above the imported page 
     $this->pdf->SetFont('Arial', 'I', 40); 
     $this->pdf->SetTextColor(255,0,0); 
     $this->pdf->SetXY(25, 135); 
     $this->_rotate(55); 
     $this->pdf->Write(0, $this->wmText); 
     $this->_rotate(0);//<-added 
    } 

    $this->pdf->Output($newFile, 'F'); 
} 

そうでない場合は、すべてが1ページに出力されるように私は、ループにライン$this->pdf->addPage();を移動しました。また、保存する前に書類を直立状態に戻すために$this->_rotate(0);を追加しました。本当にシンプル。私はあなたのために変更された行をコメントしました。

私はそれを32ページpdfでテストしたところ、問題なく動作していたようです。

+0

どのように透明性を設定する上でのアイデア?私はこれに似た値を変更しましたが、結果はありませんでした。 http://www.fpdf.org/en/script/script9.php –

+0

透明ではなく、淡い色で、最初に透かしを入れて、その上にページのテキストを置くことで騙されました。 http://www.fpdf.org/en/script/watermark.pdf – vascowhite

+0

このトリックは、pdfがスキャンされたコピーである場合は機能しません。 –

2

この投稿は、物事を開始するのに大きな助けとなりました。しかし、私はすぐにFPDFにいくつかの落とし穴があることを発見しました。私にとっては、透かしは一部のブラウザインスタンスの最初のページに表示されるだけでなく、Adobe Acrobat(Acrobat X Pro)から開くことにも気付きました。

代わりに、私は含めていない、さまざまな問題を解決した、TCPDFを使用してに切り替え:

  • エラーなしの角度に透明
  • カスタムフォントを設定する
  • 持つ能力を設定するとき
  • 更新機能:テキストを更新する

カスタムフォントを使用するには、以下のカスタムフォントブロックのコメントを外してください( http://www.tcpdf.org/fonts.php)。

また、標準FPDIパッケージはPDFバージョン1.4のみをサポートしています。したがって、それ以上のPDFをインポートすると、インポートは機能しなくなり、爆発します。商用版(https://www.setasign.com/products/fpdi-pdf-parser/details/)を購入するか、バージョン1.4でPDFを保存するだけで済みます。

ここに私の更新されたコードです:

require_once(APPPATH . 'third_party/tcpdf/tcpdf.php'); 
require_once(APPPATH . 'third_party/fpdi/fpdi.php'); 

class WatermarkerTCPDF extends FPDI { 
    public $pdf, $file, $newFile, 
      $wmText = "STACKOVERFLOW", 
      $fontsize = 24, 
      $fontfamily = 'ptsansnarrow400'; 

    /** $file and $newFile have to include the full path. */ 
    public function __construct($file = null, $newFile = null) { 
     $this->pdf = new FPDI(); 
     //custom fonts 
     //$this->fontfamily = $this->pdf->addTTFfont(APPPATH . 'third_party/tcpdf/ttf/ptsansnarrow400.ttf', 'TrueTypeUnicode', ''); 
     if (!empty($file)) { 
      $this->file = $file; 
     } 
     if (!empty($newFile)) { 
      $this->newFile = $newFile; 
     } 
    } 

    /** $file and $newFile have to include the full path. */ 
    public static function applyAndSpit($file, $newFile = null) { 
     $wm = new Watermarker($file, $newFile); 

     if ($wm->isWaterMarked()) 
      return $wm->spitWaterMarked(); 
     else { 
      $wm->doWaterMark(); 
      return $wm->spitWaterMarked(); 
     } 
    } 

    /** @todo Make the text nicer and add to all pages */ 
    public function doWaterMark() { 
     $currentFile = $this->file; 
     $newFile = $this->newFile; 

     $pagecount = $this->pdf->setSourceFile($currentFile); 

     for ($i = 1; $i <= $pagecount; $i++) { 
      $tplidx = $this->pdf->importPage($i); 
      $specs = $this->pdf->getTemplateSize($tplidx); 
      $this->pdf->SetPrintHeader(false); 
      $this->pdf->SetPrintFooter(false); 
      $this->pdf->addPage($specs['h'] > $specs['w'] ? 'P' : 'L'); 
      $this->pdf->useTemplate($tplidx, null, null, 0, 0, true); 

      // now write some text above the imported page 
      $this->pdf->SetFont($this->fontfamily, '', $this->fontsize); 
      $this->pdf->SetTextColor(204, 204, 204); 
      //$this->pdf->SetXY($specs['w']/2, $specs['h']/2); 
      $_x = ($specs['w']/2) - ($this->pdf->GetStringWidth($this->wmText, $this->fontfamily, '', $this->fontsize)/2.8); 
      $_y = $specs['h']/2; 
      $this->pdf->SetXY($_x, $_y); 
      //$this->pdf->SetXY(0, 0); 
      $this->pdf->setAlpha(0.3); 
      $this->_rotate(45, 100, 100); 
      $this->pdf->Write(0, $this->wmText); 
      //$this->pdf->writeHTMLCell($w=0, $h=0, $x='', $y='', $this->wmText, $border=0, $ln=1, $fill=0, $reseth=true, $align='', $autopadding=true); 
     } 

     if (empty($newFile)) { 
      header('Content-Type: application/pdf'); 
      $this->pdf->Output(); 
     } else { 
      $this->pdf->Output($newFile, 'F'); 
     } 
    } 

    public function isWaterMarked() { 
     //return (file_exists($this->newFile)); 
     $_file = $this->newFile; 
     $file = file_get_contents($_file); 
     force_download($file); 
    } 

    public function spitWaterMarked() { 
     $_file = $this->newFile; 
     $file = file_get_contents($_file); 
     force_download($file); 
     //return readfile($this->newFile); 
    } 

    protected function _rotate($angle, $x = -1, $y = -1) { 
     if ($x == -1) 
      $x = $this->pdf->x; 
     if ($y == -1) 
      $y = $this->pdf->y; 
     //if ($this->pdf->angle != 0) 
      //$this->pdf->_out('Q'); 
     $this->pdf->angle = $angle; 

     if ($angle != 0) { 
      $angle*=M_PI/180; 
      $c = cos($angle); 
      $s = sin($angle); 
      $cx = $x * $this->pdf->k; 
      $cy = ($this->pdf->h - $y) * $this->pdf->k; 

      $this->pdf->_out(sprintf(
          'q %.5f %.5f %.5f %.5f %.2f %.2f cm 1 0 0 1 %.2f %.2f cm', $c, $s, -$s, $c, $cx, $cy, -$cx, -$cy)); 
     } 
    } 

    public function wmText($text = null) 
    { 
     $total = 20; 
     if (!empty($text)) { 
      $this->wmText = ''; 
      for ($i = 0; $i < $total; $i++) { 
       $this->wmText .= ' ' . $text; 
      } 

     } 

     return $this; 
    } 
} 

ただ、これを使用するには:

try { 
    //this is for CodeIgniter 
    $this->load->library('WatermarkerTCPDF'); 

    //if your using it as a standard class in vanilla PHP just do: 
    //require_once('PATH_TO_LIBRARY/WatermarkerPDF.php'); 

    //If you want to output the PDF to another file, you can supply 
    //a second parameter: new WatermarkerTCPDF($file_path, $new_file_path); 
    //just remember, the full path is required 
    $watermark = new WatermarkerTCPDF($file_path); 
    $watermark->wmText($this->session->userdata('email')); 
    $watermark->doWaterMark(); 
} catch (Exception $e) { 
    exit($e->getMessage()); 
} 

をとにかくが、これはいつか誰かを助けることを願っています!

+0

助けてください。あなたは命の恩人です! –

+0

助けてください。あなたは命の恩人です! ²=) –

関連する問題