如何在PHP的resizeImageTo1MB图片缩放函数中添加水印?
给缩放后的图片添加水印的解决方案
直接修改你的resizeImageTo1MB函数,在图片缩放完成后、保存到临时文件前插入水印处理逻辑,同时修复原函数中忽略图片格式直接存为JPG的问题。以下是完整的修改后代码:
private function resizeImageTo1MB($imageData) { $maxSize = 1024 * 1024; // 1MB $tmpFilePath = $imageData['tmp_name']; list($width, $height) = getimagesize($tmpFilePath); $zdroj = getimagesize($tmpFilePath); $mime = $zdroj['mime']; $aspectRatio = $width / $height; // 计算新尺寸,保持宽高比 $newWidth = sqrt($maxSize * $aspectRatio); $newHeight = $newWidth / $aspectRatio; // 创建新画布,处理PNG透明问题 $newImage = imagecreatetruecolor($newWidth, $newHeight); if ($mime === 'image/png') { imagealphablending($newImage, false); imagesavealpha($newImage, true); $transparent = imagecolorallocatealpha($newImage, 255, 255, 255, 127); imagefill($newImage, 0, 0, $transparent); } // 根据图片类型创建源图像 switch($mime){ case 'image/jpeg': $source = imagecreatefromjpeg($tmpFilePath); break; case 'image/png': $source = imagecreatefrompng($tmpFilePath); break; case 'image/gif': $source = imagecreatefromgif($tmpFilePath); break; default: $source = imagecreatefromjpeg($tmpFilePath); } // 缩放图片 imagecopyresampled($newImage, $source, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height); // --- 添加水印逻辑(文字水印示例)--- $watermarkText = "你的水印文字"; $fontPath = __DIR__ . '/fonts/arial.ttf'; // 替换为你的字体文件路径 $fontSize = 16; // 设置水印颜色(半透明白色,最后一个参数是透明度0-127,127全透明) if ($mime === 'image/png') { $textColor = imagecolorallocatealpha($newImage, 255, 255, 255, 50); } else { $textColor = imagecolorallocate($newImage, 255, 255, 255); imagettftext($newImage, $fontSize, 0, $newWidth - 150, $newHeight - 20, imagecolorallocate($newImage, 0,0,0), $fontPath, $watermarkText); // 黑色描边增强可读性 } // 计算文字位置(右下角,预留10px边距) $textBox = imagettfbbox($fontSize, 0, $fontPath, $watermarkText); $textWidth = $textBox[2] - $textBox[0]; $textHeight = $textBox[1] - $textBox[7]; $x = $newWidth - $textWidth - 10; $y = $newHeight - $textHeight - 10; // 添加文字水印 imagettftext($newImage, $fontSize, 0, $x, $y, $textColor, $fontPath, $watermarkText); // --- 如果需要图片水印,替换上面的文字水印逻辑为以下代码 --- /* $watermarkPath = __DIR__ . '/watermark.png'; // 水印图片路径(建议用带透明通道的PNG) $watermark = imagecreatefrompng($watermarkPath); list($wmWidth, $wmHeight) = getimagesize($watermarkPath); // 设置水印位置(右下角,预留10px边距) $wmX = $newWidth - $wmWidth - 10; $wmY = $newHeight - $wmHeight - 10; // 处理水印透明效果 imagealphablending($newImage, true); imagesavealpha($newImage, true); imagecopy($newImage, $watermark, $wmX, $wmY, 0, 0, $wmWidth, $wmHeight); imagedestroy($watermark); */ // 根据原图片格式保存处理后的图片 switch($mime){ case 'image/jpeg': imagejpeg($newImage, $tmpFilePath, 85); // 第三个参数是质量,0-100,数值越高质量越好 break; case 'image/png': imagepng($newImage, $tmpFilePath, 6); // 第三个参数是压缩级别,0-9,数值越高压缩率越高 break; case 'image/gif': imagegif($newImage, $tmpFilePath); break; default: imagejpeg($newImage, $tmpFilePath, 85); } // 释放图像资源,避免内存泄漏 imagedestroy($source); imagedestroy($newImage); $imageData['size'] = filesize($tmpFilePath); return $imageData; }
关键修改点说明:
- PNG透明修复:创建新画布时添加透明色填充,避免PNG图片缩放后丢失透明背景
- 格式匹配保存:不再强制将所有图片存为JPG,根据原图片的MIME类型选择对应的保存函数,保留原格式特性
- 水印插入时机:在图片缩放完成后、保存到临时文件前操作
$newImage画布,确保水印直接添加到最终缩放后的图片上 - 双水印方案:提供文字水印和图片水印两种实现,按需选择即可
注意事项:
- 文字水印需要指定服务器上真实存在的字体文件路径,若没有Arial字体可替换为其他可用字体
- 图片水印建议使用带透明通道的PNG格式,保证水印效果自然不突兀
- 保存图片时的质量/压缩级别可根据实际需求调整,平衡图片大小与清晰度
内容的提问来源于stack exchange,提问作者viyrag
相关产品推荐
相关产品推荐

