2012-05-06 4 views
3

이 스택 질문을 수정했습니다 : Applying watermarks on pdf files when users try to download the files 그러나 오류가 발생했습니다. 수정 방법에 대한 설명이 있지만 정교하지는 못했습니다. 내가 페이지 이상이 모두 한 페이지에 병합되어있는 PDF 파일을로드 할 때FPDI/FPDF : 워터 마크 및 여러 페이지 인쇄

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'); 

: 여기

는 코드입니다. 이 게시물에 이미지를 첨부했습니다. 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'); 
} 

내가 루프에 선 $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

Ok. 이 트릭은 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

도와 줬습니다. 당신은 생명의 은인입니다! ² =) –