DomPDF生成含二维码发票PDF时二维码偶尔模糊的问题求助
解决DomPDF生成PDF时二维码偶尔模糊的问题
可能的原因及对应解决方案
1. 云存储文件读取不完整(核心大概率原因)
你当前用file_get_contents配合Google Storage stream wrapper读取文件,这种方式偶尔会出现读取截断的情况,导致图片内容不完整,渲染后模糊。建议改用Google Storage官方的文件读取方法:
function cloud_get($path, $filename) { $keyFile = json_decode(file_get_contents("KEYFILE"), true); $storage = new Google\Cloud\Storage\StorageClient(['keyFile' => $keyFile]); $bucket = $storage->bucket('BUCKETNAME'); $object = $bucket->object($path . $filename); try { // 用官方方法读取文件内容,稳定性更高 return $object->downloadAsString(); } catch (\Google\Cloud\Core\Exception\GoogleException $e) { // 记录错误日志方便排查 error_log('云存储文件读取失败:' . $e->getMessage()); return null; } }
2. 验证图片内容完整性
每次获取图片后,对比本地内容和云存储文件的MD5值,确认是否读取完整:
$qrImg = cloud_get('qrcodes/', 'qr-' . UNIQUE_ID . '.png'); if (!empty($qrImg)) { // 获取云存储文件的MD5 $keyFile = json_decode(file_get_contents("KEYFILE"), true); $storage = new Google\Cloud\Storage\StorageClient(['keyFile' => $keyFile]); $bucket = $storage->bucket('BUCKETNAME'); $object = $bucket->object('qrcodes/qr-' . UNIQUE_ID . '.png'); $cloudMd5 = $object->info()['md5Hash']; // 计算本地内容的MD5(云存储返回的是base64编码的MD5,需对应处理) $localMd5 = base64_encode(md5($qrImg, true)); if ($cloudMd5 !== $localMd5) { error_log('图片内容不完整,MD5不匹配'); // 重试读取一次 $qrImg = cloud_get('qrcodes/', 'qr-' . UNIQUE_ID . '.png'); } $base64 = 'data:image/png;base64,' . base64_encode($qrImg); }
3. 改用本地临时文件替代base64嵌入
base64编码解码过程偶尔可能出问题,把图片保存到服务器临时目录,用本地路径给DomPDF渲染:
$qrImg = cloud_get('qrcodes/', 'qr-' . UNIQUE_ID . '.png'); $tempPath = null; if (!empty($qrImg)) { // 创建临时文件 $tempPath = tempnam(sys_get_temp_dir(), 'qr_'); file_put_contents($tempPath, $qrImg); } ?> <?php if ($tempPath): ?> <img src="<?php echo $tempPath; ?>" width="99" height="99"> <?php endif; ?> <?php // 渲染PDF后删除临时文件 if ($tempPath) { unlink($tempPath); }
4. 提升二维码原始分辨率
生成二维码时,直接生成更高分辨率的图片(比如300x300像素),在PDF里仍用99x99的尺寸渲染,这样即使有轻微渲染损耗,也不会导致二维码模糊。
5. 调整DomPDF的相关配置
确保DomPDF的图片渲染配置正确:
$dompdf->set_option('isHtml5ParserEnabled', true); $dompdf->set_option('dpi', 96); // 尝试使用接近屏幕分辨率的96DPI $dompdf->set_option('defaultFont', 'Arial'); // 确保字体加载正常,避免影响布局
内容的提问来源于stack exchange,提问作者user1664803
相关产品推荐
相关产品推荐

