| <?php namespace services\info; use services\CommonService; use services\users\UserService; use setasign\Fpdi\Fpdi; use yii\db\Exception; use yii\helpers\FileHelper; /** * PDF文件处理服务类 * Class Pdf2PicService * @package services\info * @author: luwc * @Time: 2022/2/7 10:45 */ class Pdf2PicService { /** * 将pdf每页转化为图并增加水印(优化版) * @param $pdf_file * @param string $warter_text * @param int $quality * @param string $picExtension * @return string * @throws Exception * @throws \ImagickException * @throws \setasign\Fpdi\PdfParser\CrossReference\CrossReferenceException * @throws \setasign\Fpdi\PdfParser\Filter\FilterException * @throws \setasign\Fpdi\PdfParser\PdfParserException * @throws \setasign\Fpdi\PdfParser\Type\PdfTypeException * @throws \setasign\Fpdi\PdfReader\PdfReaderException * @throws \yii\base\Exception * @author: luwc * @Time: 2022/2/7 9:31 */ public static function pdf2PngAllWarterAndOss($pdf_file, $warter_text = 'xxxxxxx资料', $quality = 100, $picExtension = 'png') { $path = PROJECT_PATH . "/data/pdftmp/pic/"; FileHelper::createDirectory(PROJECT_PATH . "/data/pdftmp/"); FileHelper::createDirectory($path); $pdf = new Fpdi(); //获取页数 $pageCount = $pdf->setSourceFile($pdf_file); @ini_set('memory_limit', '1024M'); $ossPath = []; //遍历所有页面 for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) { //导入页面 $templateId = $pdf->importPage($pageNo); //获取导入页面的大小 $size = $pdf->getTemplateSize($templateId); //创建页面(横向或纵向取决于导入的页面大小) if ($size['width'] > $size['height']) { $pdf->AddPage('L', array($size['width'], $size['height'])); } else { $pdf->AddPage('P', array($size['width'], $size['height'])); } echo '第' . $pageNo . '页' . PHP_EOL; $pic = self::pdf2png($pdf_file, PROJECT_PATH . "/data/pdftmp/pic/", ($pageNo - 1), $quality, $picExtension); if (!empty($warter_text)) { $canvas = new \Imagick($pic); $width = $canvas->getImageWidth(); $height = $canvas->getImageHeight(); $fontsize = 26; $imagickPixel = new \ImagickPixel('rgba(204, 204, 204, 0.5)'); $font = VENDOR_PATH . '/../common/services/font/simsun.ttc'; for ($i = 0; $i < ceil($height / 96); $i++) { $x = max([rand(0, $width / 2), rand(0, $width / 2)]) - 48; $y = $i * 200 + 96; $draw = new \ImagickDraw(); $draw->setFont($font); $draw->setFontSize($fontsize); $draw->setFillColor($imagickPixel); $canvas->annotateImage($draw, $x, $y, -22, $warter_text); } $canvas->writeImage($pic); } $fileInfo = pathinfo($pic); $ossPath[] = CommonService::uploadFile($pic, $fileInfo['basename']); } FileHelper::removeDirectory(PROJECT_PATH . "/data/pdftmp/pic/"); @unlink($pdf_file); unset($pdf); return $ossPath; } /** * 处理PDF文件 * 将PDF内容生成图片并将图片传OSS(质量差) * @param $pdf_file * @param string $warter_text * @param int $type * @return array * @throws \Exception * @author: luwc * @Time: 2022/2/7 15:46 */ public static function pdfWarter2PicAndOss($pdf_file, $warter_text = 'xxxxxx资料', $type = 2) { try { FileHelper::createDirectory(PROJECT_PATH . "/data/pdftmp/"); FileHelper::createDirectory(PROJECT_PATH . "/data/pdftmp/pic/"); $pdf = new Fpdi(); $pdf_new = new Fpdi(); //获取页数 $pageCount = $pdf->setSourceFile($pdf_file); $flag = false; @ini_set('memory_limit', '1024M'); //遍历所有页面 for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) { //导入页面 $templateId = $pdf->importPage($pageNo); //获取导入页面的大小 $size = $pdf->getTemplateSize($templateId); //创建页面(横向或纵向取决于导入的页面大小) if ($size['width'] > $size['height']) { $pdf->AddPage('L', array($size['width'], $size['height'])); $pdf_new->AddPage('L', array($size['width'], $size['height'])); } else { $pdf->AddPage('P', array($size['width'], $size['height'])); $pdf_new->AddPage('P', array($size['width'], $size['height'])); } echo '第' . $pageNo . '页' . PHP_EOL; $pic = self::pdf2png($pdf_file, PROJECT_PATH . "/data/pdftmp/pic/", ($pageNo - 1), 50); $pdf_new->Image($pic, 0, 0, $size['width']); if ($flag === false) { self::pngThumb($warter_text, $size['width'] * 25, $size['height'] * 25); } $flag = true; //使用导入的页面 $pdf->useTemplate($templateId); /*// Set font $pdf->SetFont('Arial', 'B', 16); // Move to 8 cm to the right $pdf->Cell(80); // Centered text in a framed 20*10 mm cell and line break $pdf->Cell(20, 10, 'Title', 1, 1, 'C');*/ if ($type == 1) { //文字水印 //不能调整角色,放弃它了 //设置字体 //$pdf->SetFont('Arial','B','24'); $family = ['courier', 'helvetica', 'times', 'symbol', 'zapfdingbats']; $pdf_new->SetFont('helvetica', 'U', '50'); //设置位置 - 加在中间位置 $center_x = $size['width'] / 2; $center_y = $size['height'] / 2; $pdf_new->SetXY($center_x - 200, $center_y + 50); //写入水印 - 中文会乱码 建议使用中文图片 $pdf_new->Write(7, 'ROOT_ICO'); } else { //图片水印 // $center_x = $size['width'] / 2 - 40; // $center_y = $size['height'] / 2; // $pdf->image(PROJECT_PATH."/public/warter.png", $center_x, $center_y, 80);//中间水印 $pdf_new->image(PROJECT_PATH . "/data/pdftmp/warter.png", 0, 0, $size['width']);//全屏背景水印 } } unset($pdf); // I输出output,D下载download,F保存file_put_contents,S返回return // $pdf->Output('I','测试水印',true); $info = pathinfo($pdf_file); $newFile = $info['dirname'] . '/1_' . $info['basename']; @unlink($newFile); $pdf_new->Output('F', $newFile, true); unset($pdf_new); $pdf = new Fpdi(); //获取页数 $pageCount = $pdf->setSourceFile($newFile); @ini_set('memory_limit', '1024M'); //遍历所有页面生成图片地址 $ossPath = []; for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) { //导入页面 $templateId = $pdf->importPage($pageNo); //获取导入页面的大小 $size = $pdf->getTemplateSize($templateId); //创建页面(横向或纵向取决于导入的页面大小) if ($size['width'] > $size['height']) { $pdf->AddPage('L', array($size['width'], $size['height'])); } else { $pdf->AddPage('P', array($size['width'], $size['height'])); } echo '第2-' . $pageNo . '页' . PHP_EOL; $localUrl = self::pdf2png($newFile, PROJECT_PATH . "/data/pdftmp/pic/", ($pageNo - 1), 50); $fileInfo = pathinfo($localUrl); $ossPath[] = CommonService::uploadFile($localUrl, $fileInfo['basename']); } // FileHelper::removeDirectory(PROJECT_PATH . "/data/pdftmp/pic/"); @unlink(PROJECT_PATH . "/data/pdftmp/warter.png"); @unlink($newFile); @unlink($pdf_file); unset($pdf); echo '完成' . PHP_EOL; return $ossPath; } catch (\Exception $e) { throw new \Exception($e->getMessage()); } } /** * 处理PDF文件 * 将PDF内容生成图片并生成新的加密 * @param $pdf_file * @param string $warter_text * @param int $type * @return string * @throws \Exception * @author: luwc * @Time: 2022/2/7 15:46 */ public static function pdfWarter2Pic($pdf_file, $warter_text = 'xxxxxxx资料', $type = 2) { try { FileHelper::createDirectory(PROJECT_PATH . "/data/pdftmp/"); FileHelper::createDirectory(PROJECT_PATH . "/data/pdftmp/pic/"); $pdf = new Fpdi(); $pdf_new = new Fpdi(); //获取页数 $pageCount = $pdf->setSourceFile($pdf_file); $flag = false; @ini_set('memory_limit', '1024M'); //遍历所有页面 for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) { //导入页面 $templateId = $pdf->importPage($pageNo); //获取导入页面的大小 $size = $pdf->getTemplateSize($templateId); //创建页面(横向或纵向取决于导入的页面大小) if ($size['width'] > $size['height']) { $pdf->AddPage('L', array($size['width'], $size['height'])); $pdf_new->AddPage('L', array($size['width'], $size['height'])); } else { $pdf->AddPage('P', array($size['width'], $size['height'])); $pdf_new->AddPage('P', array($size['width'], $size['height'])); } echo '第' . $pageNo . '页' . PHP_EOL; $pic = self::pdf2png($pdf_file, PROJECT_PATH . "/data/pdftmp/pic/", ($pageNo - 1), 50); $pdf_new->Image($pic, 0, 0, $size['width']); if ($flag === false) { self::pngThumb($warter_text, $size['width'] * 25, $size['height'] * 25); } $flag = true; //使用导入的页面 $pdf->useTemplate($templateId); /*// Set font $pdf->SetFont('Arial', 'B', 16); // Move to 8 cm to the right $pdf->Cell(80); // Centered text in a framed 20*10 mm cell and line break $pdf->Cell(20, 10, 'Title', 1, 1, 'C');*/ if ($type == 1) { //文字水印 //不能调整角色,放弃它了 //设置字体 //$pdf->SetFont('Arial','B','24'); $family = ['courier', 'helvetica', 'times', 'symbol', 'zapfdingbats']; $pdf_new->SetFont('helvetica', 'U', '50'); //设置位置 - 加在中间位置 $center_x = $size['width'] / 2; $center_y = $size['height'] / 2; $pdf_new->SetXY($center_x - 200, $center_y + 50); //写入水印 - 中文会乱码 建议使用中文图片 $pdf_new->Write(7, 'ROOT_ICO'); } else { //图片水印 // $center_x = $size['width'] / 2 - 40; // $center_y = $size['height'] / 2; // $pdf->image(PROJECT_PATH."/public/warter.png", $center_x, $center_y, 80);//中间水印 $pdf_new->image(PROJECT_PATH . "/data/pdftmp/warter.png", 0, 0, $size['width']);//全屏背景水印 } } unset($pdf); // I输出output,D下载download,F保存file_put_contents,S返回return // $pdf->Output('I','测试水印',true); $info = pathinfo($pdf_file); $newFile = $info['dirname'] . '/1_' . $info['basename']; @unlink($newFile); $pdf_new->Output('F', $newFile, true); unset($pdf_new); // 安全处理 $pdf_new = new \setasign\Fpdi\Tcpdf\Fpdi(); $pdf_new->SetAuthor('xxxx', true); $pdf_new->SetCreator('xxx', true); $pdf_new->SetSubject('xxx', true); $pdf_new->SetKeywords('xxx', true); $pdf_new->SetTitle($warter_text, true); $pdf_new->SetCompression(true); $pdf_new->setSourceFile($newFile); $pdf_new->SetProtection(['print', 'modify', 'copy', 'annot-forms', 'fill-forms', 'extract', 'assemble', 'print-high'], '', 'xxxx');//遍历所有页面 for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) { //导入页面 $templateId = $pdf_new->importPage($pageNo); //获取导入页面的大小 $size = $pdf_new->getTemplateSize($templateId); //创建页面(横向或纵向取决于导入的页面大小) if ($size['width'] > $size['height']) { $pdf_new->AddPage('L', array($size['width'], $size['height'])); } else { $pdf_new->AddPage('P', array($size['width'], $size['height'])); } //使用导入的页面 $pdf_new->useTemplate($templateId); } $newFile2 = $info['dirname'] . '/2_' . $info['basename']; $pdf_new->Output($newFile2, 'F'); // FileHelper::removeDirectory(PROJECT_PATH . "/data/pdftmp/pic/"); @unlink(PROJECT_PATH . "/data/pdftmp/warter.png"); @unlink($newFile); unset($pdf_new); // echo '完成' . PHP_EOL; return $newFile2; } catch (\Exception $e) { throw new \Exception($e->getMessage()); } } /** * 将某页PDF文件转成图片 * @param $pdf PDF文件绝对路径 * @param $path 图片临时目录 * @param int $page pdf页 * @param int $quality 质量默认100 * @param string $picExtension 图片文件扩展名 * @return array|string * @throws Exception * @throws \ImagickException * @author: luwc * @Time: 2022/1/24 13:18 */ public static function pdf2png($pdf, $path, $page = 0, $quality = 100, $picExtension = 'jpg') { try { $im = new \Imagick(); $im->setResolution(120, 120); //设置图像分辨率 $im->setCompressionQuality($quality); //压缩比 $im->readImage($pdf . "[" . $page . "]"); //设置读取pdf的第一页 //$im->thumbnailImage(200, 100, true);//改变图像的大小 //$im->scaleImage(200,100,true);//缩放大小图像 $filename = $path . "/" . md5(time()) . '-' . $page . '.' . $picExtension; if ($im->writeImage($filename) == true) { $Return = $filename; } return $Return; } catch (PDOException $e) { throw new Exception('数据处理失败' . $e->getMessage()); } } /** * 暂没用 * 将pdf转化为一个大长图 * @param $pdf pdf所在路径 (/www/pdf/abc.pdf pdf所在的绝对路径) * @param $path 新生成图片所在路径 (/www/pngs/) * @param int $quality * @param string $picExtension * @return string * @throws \ImagickException * @author: luwc * @Time: 2022/2/7 9:31 */ public static function pdf2PngAll($pdf, $path, $quality = 100, $picExtension = 'jpg') { $im = new \Imagick(); $im->setCompressionQuality($quality); $im->setResolution(120, 120);//设置分辨率 值越大分辨率越高 $im->readImage($pdf); $canvas = new \Imagick(); $imgNum = $im->getNumberImages(); foreach ($im as $k => $sub) { $sub->setImageFormat($picExtension); //$sub->setResolution(120, 120); $sub->stripImage(); $sub->trimImage(0); $width = $sub->getImageWidth() + 10; $height = $sub->getImageHeight() + 10; if ($k + 1 == $imgNum) { $height += 10; } //最后添加10的height $canvas->newImage($width, $height, new \ImagickPixel('white')); $canvas->compositeImage($sub, \Imagick::COMPOSITE_DEFAULT, 5, 5); } $canvas->resetIterator(); $picPath = sprintf('%s%s.%s', $path, self::getRandStr(), $picExtension); $canvas->appendImages(true)->writeImage($picPath); return $picPath; } /** * 暂没用 * @return false|string * @author: luwc * @Time: 2022/2/7 10:59 */ public static function getRandStr() { $str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890'; $randStr = str_shuffle($str);//打乱字符串 $rands = substr($randStr, 0, 6); return $rands; } /** * 水印图片 * @param string $warter_text * @param $width * @param $heigh * @author: luwc * @Time: 2022/1/24 12:40 */ public static function pngThumb($warter_text = 'xxxxx', $width, $heigh) { $fontsize = 140; $font = VENDOR_PATH . '/../common/services/font/simsun.ttc'; $warter = imagecreatetruecolor($width, $heigh); $src_white = imagecolorallocatealpha($warter, 255, 255, 255, 127); imagefill($warter, 0, 0, $src_white);//替换成白色 imagecolortransparent($warter, $src_white); //将原图颜色替换为透明色 imagealphablending($warter, false);//这里很重要,意思是不合并颜色,直接用$img图像颜色替换,包括透明色; imagesavealpha($warter, true);//这里很重要,意思是不要丢了$thumb图像的透明色; $fontcolor = imagecolorallocate($warter, 204, 204, 204); for ($i = 0; $i < ceil($heigh / 1200); $i++) { $x = max([rand(0, $width / 2), rand(0, $width / 2)]) - 400; $y = $i * 1200 + 400; imagettftext($warter, $fontsize, 22, $x, $y, $fontcolor, $font, mb_convert_encoding($warter_text, 'HTML-ENTITIES', 'UTF-8')); } imagepng($warter, PROJECT_PATH . '/data/pdftmp/warter.png'); imagedestroy($warter); } } |