Opencart 2.3.0.2 PNG图片缩放异常问题求助(附修改后Image.php代码)
Fix for PNG Image Scaling Glitch in OpenCart 2.3.0.2
I recently hit a frustrating snag with PNG image scaling in OpenCart 2.3.0.2—scaled PNGs were showing broken transparency (often black backgrounds instead of clear areas) or weird color distortion. After digging into the core code, I realized the default image handling logic in catalog/model/tool/image.php wasn't properly accounting for PNG's alpha channel.
Here's the full modified version of the file that resolved the issue:
<?php class ModelToolImage extends Model { public function resize($filename, $width, $height, $type = "f") { if (!file_exists(DIR_IMAGE . $filename) || !is_file(DIR_IMAGE . $filename)) { return; } $info = pathinfo($filename); $extension = $info['extension']; $old_image = $filename; $new_image = 'cache/' . utf8_substr($filename, 0, utf8_strrpos($filename, '.')) . '-' . (int)$width . 'x' . (int)$height . '.' . $extension; if (!file_exists(DIR_IMAGE . $new_image) || (filemtime(DIR_IMAGE . $old_image) > filemtime(DIR_IMAGE . $new_image))) { $path = ''; $directories = explode('/', dirname(str_replace('../', '', $new_image))); foreach ($directories as $directory) { $path = $path . '/' . $directory; if (!file_exists(DIR_IMAGE . $path)) { mkdir(DIR_IMAGE . $path, 0777); } } list($width_orig, $height_orig) = getimagesize(DIR_IMAGE . $old_image); if ($width_orig != $width || $height_orig != $height) { $image = false; switch ($extension) { case 'jpg': case 'jpeg': $image = imagecreatefromjpeg(DIR_IMAGE . $old_image); break; case 'png': $image = imagecreatefrompng(DIR_IMAGE . $old_image); // Preserve original PNG transparency imagealphablending($image, false); imagesavealpha($image, true); break; case 'gif': $image = imagecreatefromgif(DIR_IMAGE . $old_image); break; } if ($image) { $width_new = $width; $height_new = $height; switch ($type) { case 'w': $height_new = $height_orig * ($width_new / $width_orig); break; case 'h': $width_new = $width_orig * ($height_new / $height_orig); break; default: $ratio_orig = $width_orig / $height_orig; if ($width / $height > $ratio_orig) { $width_new = $height * $ratio_orig; } else { $height_new = $width / $ratio_orig; } break; } $image_new = imagecreatetruecolor($width_new, $height_new); // Set up transparency for the resized PNG if ($extension == 'png') { imagealphablending($image_new, false); imagesavealpha($image_new, true); $transparent = imagecolorallocatealpha($image_new, 255, 255, 255, 127); imagefill($image_new, 0, 0, $transparent); } imagecopyresampled($image_new, $image, 0, 0, 0, 0, $width_new, $height_new, $width_orig, $height_orig); switch ($extension) { case 'jpg': case 'jpeg': imagejpeg($image_new, DIR_IMAGE . $new_image, 80); break; case 'png': imagepng($image_new, DIR_IMAGE . $new_image); break; case 'gif': imagegif($image_new, DIR_IMAGE . $new_image); break; } imagedestroy($image); imagedestroy($image_new); } } else { copy(DIR_IMAGE . $old_image, DIR_IMAGE . $new_image); } } if ($this->request->server['HTTPS']) { return $this->config->get('config_ssl') . 'image/' . $new_image; } else { return $this->config->get('config_url') . 'image/' . $new_image; } } }
Key Fixes Explained:
- Original PNG Transparency Preservation: When loading a PNG with
imagecreatefrompng, we addimagealphablending($image, false);andimagesavealpha($image, true);to make sure the source image's alpha channel isn't discarded during processing. - Resized PNG Transparency Setup: Before copying the resampled image, we configure the new truecolor image to support transparency, then fill it with a fully transparent background—this stops black areas from popping up in transparent regions.
- Proper PNG Saving: We ensure the resized image is saved as a PNG without altering its alpha channel settings, keeping transparency intact from start to finish.
内容的提问来源于stack exchange,提问作者Danil
相关产品推荐
相关产品推荐

