Laravel处理Base64图片生成双版本带水印时提示Image source not readable
问题:Base64图片处理报错「Image source not readable」
我想要上传Base64格式图片并生成两个版本:一个250px的缩略图,另一个650px带水印的图片,但出现错误提示:Image source not readable。
代码如下
$path = public_path().'/seller/uploads/'. $seller->id .'/'. $adsid; $watermark = public_path().'/watermark.png'; $Image = explode(";base64,", $img); $ImageName = $date; $ImageDecode = base64_decode($Image[1]); $thumb_name = $ImageName.'-thumb.jpg'; $resize_name = $ImageName.'-resized.jpg'; Image::make($ImageDecode)->encode('jpg', 80)->orientate()->resize(250, null, function ($constraint) { $constraint->aspectRatio(); })->save($path.'/'.$thumb_name); Image::make($ImageDecode)->encode('jpg', 80)->orientate()->resize(650, null, function ($constraint) { $constraint->aspectRatio(); })->insert($watermark, 'bottom-right', 10, 10)->save($path.'/'.$resize_name);
错误信息
exception: "Intervention\Image\Exception\NotReadableException"
file: "E:\vendor\intervention\image\src\Intervention\Image\AbstractDecoder.php"
line: 351 message: "Image source not readable"
环境信息
xampp PHP Version 8.1.12 Laravel Framework 8.83.23
解决思路
1. 避免提前解码Base64数据
Intervention Image的make()方法支持直接解析Base64字符串,不需要手动调用base64_decode。提前解码后的二进制数据无法被正确识别,修改代码如下:
// 移除$ImageDecode = base64_decode($Image[1]);这一行 // 直接使用分割后的Base64内容生成图片 Image::make($Image[1])->encode('jpg', 80)->orientate()->resize(250, null, function ($constraint) { $constraint->aspectRatio(); })->save($path.'/'.$thumb_name); // 水印版本同理 Image::make($Image[1])->encode('jpg', 80)->orientate()->resize(650, null, function ($constraint) { $constraint->aspectRatio(); })->insert($watermark, 'bottom-right', 10, 10)->save($path.'/'.$resize_name); // 更简洁的方式:直接传入完整的$img(前提是$img包含data:image/xxx;base64,前缀) // Image::make($img)->encode('jpg', 80)...
2. 验证Base64格式有效性
确保$img变量格式正确,必须包含;base64,分隔符。添加校验逻辑避免解析失败:
$Image = explode(";base64,", $img); if (count($Image) !== 2) { // 处理无效格式,比如返回错误响应 return response()->json(['error' => '无效的Base64图片格式'], 400); }
3. 确保存储目录存在
如果$path对应的目录不存在,保存图片会失败,甚至间接导致解析报错。提前创建目录:
use Illuminate\Support\Facades\File; $path = public_path().'/seller/uploads/'. $seller->id .'/'. $adsid; if (!File::exists($path)) { File::makeDirectory($path, 0755, true); // 递归创建目录并设置权限 }
4. 检查水印文件路径
确认$watermark指向的watermark.png文件真实存在,路径无误。可以用以下代码验证:
if (!file_exists($watermark)) { throw new \Exception('水印文件不存在'); }
内容的提问来源于stack exchange,提问作者Jack The Baker
相关产品推荐
相关产品推荐

