Laravel中使用Intervention Image处理Base64图片时抛出NotReadableException异常的问题排查
Laravel中使用Intervention Image处理Base64图片时抛出NotReadableException异常的问题排查
嘿,我一眼就看出问题所在啦!你存储在数据库里的Base64图片字符串带了data:image/jpeg;base64,这样的MIME类型前缀,而Intervention Image的make方法默认只认纯Base64编码内容,不认带前缀的格式,这就是为啥会抛出「Image source not readable」异常的原因~
解决方案:剥离Base64前缀再处理
我们只需要把字符串里的前缀部分去掉,提取出真正的Base64编码内容即可,具体步骤如下:
分割并提取纯Base64内容
用explode函数把前缀和编码内容分开,同时加个判断避免无前缀的字符串出错:$imageData = $file->voucher_file_base64; // 剥离Base64前缀 if (strpos($imageData, ';base64,') !== false) { list(, $imageData) = explode(';base64,', $imageData); }创建Image实例并压缩
用处理后的纯Base64内容创建Image实例,再执行压缩操作:$image = Image::make($imageData); $originalSize = strlen($file->voucher_file_base64); $compressedImage = $image->encode('jpg', 75); $newSize = strlen($compressedImage);修正数据库更新的变量问题
你代码里更新数据库时用到的$newBase64变量未定义,需要把压缩后的图片实例转成字符串(也就是Base64格式),直接强转即可:DB::table('app_payment_reports') ->where('id', $file->id) ->update([ 'new_voucher_file_size' => $newSize, 'voucher_file_base64' => (string)$compressedImage ]);
完整修正后的compress方法代码
public function compress() { $files = DB::table('app_payment_reports') ->where(function ($query) { $query->where('voucher_file_type', '=', 'image/jpeg') ->orWhere('voucher_file_type', '=', 'image/png'); }) ->whereNull('new_voucher_file_size') ->get(); foreach ($files as $file) { $imageData = $file->voucher_file_base64; // 剥离Base64前缀 if (strpos($imageData, ';base64,') !== false) { list(, $imageData) = explode(';base64,', $imageData); } $image = Image::make($imageData); $originalSize = strlen($file->voucher_file_base64); $compressedImage = $image->encode('jpg', 75); $newSize = strlen($compressedImage); DB::table('app_payment_reports') ->where('id', $file->id) ->update([ 'new_voucher_file_size' => $newSize, 'voucher_file_base64' => (string)$compressedImage ]); } }
额外小提示
如果你的PNG图片有透明区域,转成JPG时透明部分会变成黑色,若需要保留透明效果,可以把编码格式改成png:
$compressedImage = $image->encode('png', 75);
备注:内容来源于stack exchange,提问作者xJosAntonio A
相关产品推荐
相关产品推荐

