PHP中imagepng调整图像后未存盘前获取内容及报错解决
问题原因解析
imagecreatefrompng(1): failed to open stream
这个报错的核心是imagepng()函数的返回值逻辑:
- 只传入第一个GD资源参数时,
imagepng()会直接输出图像二进制流,返回值为布尔类型:成功返回true(输出时会被自动转为字符串1)、失败返回false - 你把布尔返回值传给
imagecreatefrompng(),相当于尝试读取名为1的本地文件,自然会报错找不到流。
最优解决方案
你完全不需要把图像转成PNG再读回来,调整大小后得到的$dst_img本身就是内存中可用的GD图像资源,直接用它处理水印即可,完全符合你减少资源消耗的诉求,示例代码逻辑如下:
// 原有调整大小的代码,执行完成后得到$dst_img // .... // 直接用$dst_img获取尺寸,不需要额外转码读取 $sx = imagesx($dst_img); $sy = imagesy($dst_img); // 接下来直接在$dst_img上叠加水印即可,示例逻辑: $watermark = imagecreatefrompng('你的水印本地路径.png'); $watermark_width = imagesx($watermark); $watermark_height = imagesy($watermark); // 计算水印位置,示例为右下角留10px边距 $pos_x = $sx - $watermark_width - 10; $pos_y = $sy - $watermark_height - 10; // 合并水印和主图 imagecopy($dst_img, $watermark, $pos_x, $pos_y, 0, 0, $watermark_width, $watermark_height); imagedestroy($watermark); // 最后再把加完水印的图像存到目标文件夹 imagepng($dst_img, '目标存储路径/最终文件名.png'); // 销毁内存资源 imagedestroy($dst_img);
特殊场景方案:需要获取PNG数据流不落地
如果有特殊逻辑需要拿到PNG的二进制流不存文件,可以用PHP输出缓冲区捕获,示例:
// 开启缓冲区 ob_start(); imagepng($dst_img); // 获取缓冲区里的PNG二进制内容 $png_data = ob_get_clean(); // 从数据流创建GD资源 $im = imagecreatefromstring($png_data);
这个方案对你的水印需求来说性能冗余,仅做特殊场景参考。
内容的提问来源于stack exchange,提问作者Said Erraoudy
相关产品推荐
相关产品推荐

