如何将PHP GD及图像函数应用于从MySQL数据库获取的图片?
问题分析与解决方案
你的代码存在几个核心问题,导致模糊后的图片无法正常渲染:
- 直接将数据库返回的Blob二进制数据传给GD库函数,而GD库需要的是图像资源对象,不是原始二进制数据
- 模糊函数返回的是图像资源,不能直接作为
<img>标签的src值,需要转换为base64编码的Data URI格式 - 调用
blur()函数时未输出返回值,且原<img>标签未闭合
1. 修复模糊处理函数(blurimage.php)
修改函数,先把Blob二进制数据转为图像资源,处理完成后再转回二进制数据,同时兼容不同图片类型:
<?php function blur($imageBlob, $imageType = 'jpg') { // 将二进制Blob转为GD图像资源 $imageResource = imagecreatefromstring($imageBlob); if (!$imageResource) { return false; } // 获取原图实际尺寸,避免硬写固定值 $originalWidth = imagesx($imageResource); $originalHeight = imagesy($imageResource); // 第一步:缩小到25%并高斯模糊 $smallWidth = $originalWidth * 0.25; $smallHeight = $originalHeight * 0.25; $s_img1 = imagecreatetruecolor($smallWidth, $smallHeight); imagecopyresampled($s_img1, $imageResource, 0, 0, 0, 0, $smallWidth, $smallHeight, $originalWidth, $originalHeight); imagefilter($s_img1, IMG_FILTER_GAUSSIAN_BLUR); // 第二步:放大到50%并再次模糊 $mediumWidth = $originalWidth * 0.5; $mediumHeight = $originalHeight * 0.5; $s_img2 = imagecreatetruecolor($mediumWidth, $mediumHeight); imagecopyresampled($s_img2, $s_img1, 0, 0, 0, 0, $mediumWidth, $mediumHeight, $smallWidth, $smallHeight); imagedestroy($s_img1); imagefilter($s_img2, IMG_FILTER_GAUSSIAN_BLUR); // 第三步:放大回原尺寸并最后一次模糊 imagecopyresampled($imageResource, $s_img2, 0, 0, 0, 0, $originalWidth, $originalHeight, $mediumWidth, $mediumHeight); imagedestroy($s_img2); imagefilter($imageResource, IMG_FILTER_GAUSSIAN_BLUR); // 将处理后的图像资源转回二进制数据 ob_start(); switch(strtolower($imageType)) { case 'png': imagepng($imageResource); break; case 'gif': imagegif($imageResource); break; default: // 处理jpg/jpeg imagejpeg($imageResource); } $blurredBlob = ob_get_clean(); imagedestroy($imageResource); return $blurredBlob; } ?>
2. 修改页面渲染代码
调整读取数据库的逻辑,获取图片类型并生成合法的Data URI:
<?php require_once 'dbConfig.php'; include 'blurimage.php'; // 新增读取filename,用于解析图片类型 $sql = "SELECT filename, image FROM images ORDER BY id DESC"; $result = $db->query($sql); ?> <!DOCTYPE html> <html lang="en-US"> <head> <title>Retrieve Images from Database using PHP</title> <meta charset="utf-8"> <link rel="stylesheet" href="css/style.css"> </head> <body> <div class="container"> <h1>Retrieve Images from Database using PHP</h1> <div class="gallery"> <?php if ($result->num_rows > 0) { ?> <?php while ($row = $result->fetch_assoc()) { ?> <?php $imageBlob = $row['image']; // 从文件名提取图片类型 $imageType = pathinfo($row['filename'], PATHINFO_EXTENSION); // 调用模糊函数 $blurredBlob = blur($imageBlob, $imageType); // 生成Data URI,处理失败则 fallback 到原图 if ($blurredBlob) { $dataUri = "data:image/{$imageType};base64," . base64_encode($blurredBlob); } else { $dataUri = "data:image/{$imageType};base64," . base64_encode($imageBlob); } ?> <div class="img-box"> <img src="<?php echo $dataUri; ?>" alt="Blurred gallery image" /> </div> <?php } ?> <?php } else { ?> <p class="status error">Image(s) not found...</p> <?php } ?> </div> <a href="index.php">Upload images</a> </div> </body> </html>
3. 额外优化建议
- 修复SQL注入风险:你的上传代码直接拼接SQL语句,存在严重安全问题,建议改用预处理语句:
// 替换上传部分的INSERT逻辑 $stmt = $db->prepare("INSERT into images (filename, image, page, created) VALUES (?, ?, ?, NOW())"); $stmt->bind_param("sss", $name, $imgContent, $page); if ($stmt->execute()) { $status = 'success'; $statusMsg = "File uploaded successfully."; } else { $statusMsg = "File upload failed, please try again."; } $stmt->close();
- 提升性能:每次页面加载都重新模糊图片会消耗服务器资源,建议在上传阶段就完成模糊处理,将模糊后的图片存入数据库(新增
blurred_image字段)或本地文件系统,页面直接读取处理好的内容即可。
内容的提问来源于stack exchange,提问作者GSinIL
相关产品推荐
相关产品推荐

