PHP - 较小图像的透明度问题
因此,我正在使用前几天在这里遇到的一种重新调整图像大小的方法,它对于它处理的初始图像非常有效,但我第二次使用该过程来创建一个较小的图像以用于缩略图。当创建第二个缩略图时,它会出现黑色背景,而它应该是透明的。我知道这是一个常见问题,因为我在这里看到过很多有类似抱怨的帖子。当我昨晚查看 php 错误日志时,它说 imagecolorat 试图命中超出范围的像素......
PHP Notice: imagecolorat(): 0,28 is out of bounds in C:\inetpub\
至少我知道发生了什么,但我现在需要知道的是如何修复它。真的很奇怪,对于同一图像的较大副本,我根本没有收到此错误,并且它可以很好地生成较大上传副本的漂亮副本。这是我用来调整所有内容大小的代码:
$image_source = imagecreatefromstring($markericon); //original image
$imgHead = "image/jpeg"; //tag for image to be pulled later. images go in are png's
//code to make sure image is never larger than certain size
$image_width = imagesx($image_source);
$image_height = imagesy($image_source);
if($image_width>$max_upload_large_side || $image_height >$max_upload_large_side){
$proportionslarge = $image_width/$image_height;
if($image_width>$image_height){
$new_large_width = $max_upload_large_side;
$new_large_height = round($max_upload_large_side/$proportionslarge);
}
else{
$new_large_height = $max_upload_large_side;
$new_large_width = round($max_upload_large_side*$proportionslarge);
}
$new_large_image = imagecreatetruecolor($new_large_width , $new_large_height);
//code used to retain image transparency
//over write alpha chanel of image destination
imagealphablending($new_large_image, false); // Overwrite alpha
imagesavealpha($new_large_image, true);
// Create a separate alpha channel to blend images with
$alpha_image = imagecreatetruecolor($image_width, $image_height);
imagealphablending($alpha_image, false); // Overwrite alpha
imagesavealpha($alpha_image, true);
//copy data at every pixel in image
for ($x = 0; $x < $image_width; $x++) {
for ($y = 0; $y < $image_height; $y++) {
$alpha = (imagecolorat($image_source, $x, $y) >> 24) & 0xFF;
$color = imagecolorallocatealpha($alpha_image, 0, 0, 0, $alpha);
imagesetpixel($alpha_image, $x, $y, $color);
}
}
// Resize image to destination, using gamma correction
imagegammacorrect($image_source, 2.2, 1.0);
imagecopyresampled($new_large_image, $image_source, 0, 0, 0, 0, $new_large_width, $new_large_height, $image_width, $image_height);
imagegammacorrect($new_large_image, 1.0, 2.2);
// Resize alpha channel
$alpha_resized_image = imagecreatetruecolor($new_large_width, $new_large_height);
imagealphablending($alpha_resized_image, false);
imagesavealpha($alpha_resized_image, true);
imagecopyresampled($alpha_resized_image, $alpha_image, 0, 0, 0, 0, $new_large_width, $new_large_height, $image_width, $image_height);
// Copy alpha channel back to resized image
for ($x = 0; $x < $new_large_width; $x++) {
for ($y = 0; $y < $new_large_height; $y++) {
$alpha = (imagecolorat($alpha_resized_image, $x, $y) >> 24) & 0xFF;
$rgb = imagecolorat($new_large_image, $x, $y);
$r = ($rgb >> 16 ) & 0xFF;
$g = ($rgb >> 8 ) & 0xFF;
$b = $rgb & 0xFF;
$color = imagecolorallocatealpha($new_large_image, $r, $g, $b, $alpha);
imagesetpixel($new_large_image, $x, $y, $color);
}
}
// end of first run//
ob_start(); // Start capturing stdout.
imagePNG($new_large_image);
$lBinaryThumbnail = ob_get_contents(); // the raw jpeg image data.
ob_end_clean(); // Dump the stdout so it does not screw other output.
$lBinaryThumbnail = addslashes($lBinaryThumbnail);
imagedestroy($new_large_image);
} else $lBinaryThumbnail = $imgData;
//start of second image run
if($image_width>$max_upload_small_side || $image_height >$max_upload_small_side){
$proportionssmall = $image_width/$image_height;
if($image_width>$image_height){
$new_small_width = $max_upload_small_side;
$new_small_height = round($max_upload_small_side/$proportionssmall);
}
else{
$new_small_height = $max_upload_small_side;
$new_small_width = round($max_upload_small_side*$proportionssmall);
}
$new_small_image = imagecreatetruecolor($new_small_width , $new_small_height);
//////////////////////////////////////////////////////////////////////////////////
//over write alpha chanel of image destination
imagealphablending($new_small_image, false); // Overwrite alpha
imagesavealpha($new_small_image, true);
// Create a separate alpha channel to blend images with
$alpha_image = imagecreatetruecolor($image_width, $image_height);
imagealphablending($alpha_image, false); // Overwrite alpha
imagesavealpha($alpha_image, true);
//copy data at every pixel in image
for ($x = 0; $x < $image_width; $x++) {
for ($y = 0; $y < $image_height; $y++) {
$alpha = (imagecolorat($image_source, $x, $y) >> 24) & 0xFF;
$color = imagecolorallocatealpha($alpha_image, 0, 0, 0, $alpha);
imagesetpixel($alpha_image, $x, $y, $color);
}
}
// Resize image to destination, using gamma correction
imagegammacorrect($image_source, 2.2, 1.0);
imagecopyresampled($new_small_image, $image_source, 0, 0, 0, 0, $new_small_width , $new_small_height, $image_width, $image_height);
imagegammacorrect($new_small_image, 1.0, 2.2);
// Resize alpha channel
$alpha_resized_image = imagecreatetruecolor( $image_width, $image_height);
imagealphablending($alpha_resized_image, false);
imagesavealpha($alpha_resized_image, true);
imagecopyresampled($alpha_resized_image, $alpha_image, 0, 0, 0, 0, $new_small_width ,$new_small_height, $image_width, $image_height);
// Copy alpha channel back to resized image
for ($x = 0; $x < $new_small_width; $x++) {
for ($y = 0; $y < $new_small_height; $y++) {
$alpha = (imagecolorat($alpha_resized_image, $x, $y) >> 24) & 0xFF;
$rgb = imagecolorat($new_small_image, $x, $y); //this is the line that throws the error first and gives a out of bounds related error.
$r = ($rgb >> 16 ) & 0xFF;
$g = ($rgb >> 8 ) & 0xFF;
$b = $rgb & 0xFF;
$color = imagecolorallocatealpha($new_small_image, $r, $g, $b, $alpha);
imagesetpixel($new_small_image, $x, $y, $color);
}
}
// end of new code //
//imagecopyresampled($new_small_image, $image_source, 0, 0, 0, 0, $new_small_width, $new_small_height, $image_width, $image_height);
ob_start(); // Start capturing stdout.
imagePNG($new_small_image);
$sBinaryThumbnail = ob_get_contents(); // the raw jpeg image data.
ob_end_clean(); // Dump the stdout so it does not screw other output.
$sBinaryThumbnail = addslashes($sBinaryThumbnail);
imagedestroy($new_small_image);
} else $sBinaryThumbnail = $lBinaryThumbnail;
imagedestroy($image_source);
就像我说的,第一次运行时一切正常,但由于某种原因,在第二次运行时它会放屁并抛出越界错误。它从 0,28 开始,一直持续到循环过程在 50,50 结束
So I'm using a method for re-sizing images that I came across on here the other day and it works great for the initial image it processes but I use the process a second time to create a smaller image to use for a thumb nail. When this second thumb nail is created it comes out with a black background where it should be transparent. I know this is a common problem as I have seen plenty of threads on here with similar complaints. When I was looking last night in the php error logs it was saying that imagecolorat was trying to hit pixels which were out of bounds.....
PHP Notice: imagecolorat(): 0,28 is out of bounds in C:\inetpub\
At least I know whats happening but what I need to know now is how to fix it. Its really strange that for the larger copy of the same image I dont get this error at all and it works just fine producing a nice copy of the larger uploaded copy. Heres the code that Im using to resize everything:
$image_source = imagecreatefromstring($markericon); //original image
$imgHead = "image/jpeg"; //tag for image to be pulled later. images go in are png's
//code to make sure image is never larger than certain size
$image_width = imagesx($image_source);
$image_height = imagesy($image_source);
if($image_width>$max_upload_large_side || $image_height >$max_upload_large_side){
$proportionslarge = $image_width/$image_height;
if($image_width>$image_height){
$new_large_width = $max_upload_large_side;
$new_large_height = round($max_upload_large_side/$proportionslarge);
}
else{
$new_large_height = $max_upload_large_side;
$new_large_width = round($max_upload_large_side*$proportionslarge);
}
$new_large_image = imagecreatetruecolor($new_large_width , $new_large_height);
//code used to retain image transparency
//over write alpha chanel of image destination
imagealphablending($new_large_image, false); // Overwrite alpha
imagesavealpha($new_large_image, true);
// Create a separate alpha channel to blend images with
$alpha_image = imagecreatetruecolor($image_width, $image_height);
imagealphablending($alpha_image, false); // Overwrite alpha
imagesavealpha($alpha_image, true);
//copy data at every pixel in image
for ($x = 0; $x < $image_width; $x++) {
for ($y = 0; $y < $image_height; $y++) {
$alpha = (imagecolorat($image_source, $x, $y) >> 24) & 0xFF;
$color = imagecolorallocatealpha($alpha_image, 0, 0, 0, $alpha);
imagesetpixel($alpha_image, $x, $y, $color);
}
}
// Resize image to destination, using gamma correction
imagegammacorrect($image_source, 2.2, 1.0);
imagecopyresampled($new_large_image, $image_source, 0, 0, 0, 0, $new_large_width, $new_large_height, $image_width, $image_height);
imagegammacorrect($new_large_image, 1.0, 2.2);
// Resize alpha channel
$alpha_resized_image = imagecreatetruecolor($new_large_width, $new_large_height);
imagealphablending($alpha_resized_image, false);
imagesavealpha($alpha_resized_image, true);
imagecopyresampled($alpha_resized_image, $alpha_image, 0, 0, 0, 0, $new_large_width, $new_large_height, $image_width, $image_height);
// Copy alpha channel back to resized image
for ($x = 0; $x < $new_large_width; $x++) {
for ($y = 0; $y < $new_large_height; $y++) {
$alpha = (imagecolorat($alpha_resized_image, $x, $y) >> 24) & 0xFF;
$rgb = imagecolorat($new_large_image, $x, $y);
$r = ($rgb >> 16 ) & 0xFF;
$g = ($rgb >> 8 ) & 0xFF;
$b = $rgb & 0xFF;
$color = imagecolorallocatealpha($new_large_image, $r, $g, $b, $alpha);
imagesetpixel($new_large_image, $x, $y, $color);
}
}
// end of first run//
ob_start(); // Start capturing stdout.
imagePNG($new_large_image);
$lBinaryThumbnail = ob_get_contents(); // the raw jpeg image data.
ob_end_clean(); // Dump the stdout so it does not screw other output.
$lBinaryThumbnail = addslashes($lBinaryThumbnail);
imagedestroy($new_large_image);
} else $lBinaryThumbnail = $imgData;
//start of second image run
if($image_width>$max_upload_small_side || $image_height >$max_upload_small_side){
$proportionssmall = $image_width/$image_height;
if($image_width>$image_height){
$new_small_width = $max_upload_small_side;
$new_small_height = round($max_upload_small_side/$proportionssmall);
}
else{
$new_small_height = $max_upload_small_side;
$new_small_width = round($max_upload_small_side*$proportionssmall);
}
$new_small_image = imagecreatetruecolor($new_small_width , $new_small_height);
//////////////////////////////////////////////////////////////////////////////////
//over write alpha chanel of image destination
imagealphablending($new_small_image, false); // Overwrite alpha
imagesavealpha($new_small_image, true);
// Create a separate alpha channel to blend images with
$alpha_image = imagecreatetruecolor($image_width, $image_height);
imagealphablending($alpha_image, false); // Overwrite alpha
imagesavealpha($alpha_image, true);
//copy data at every pixel in image
for ($x = 0; $x < $image_width; $x++) {
for ($y = 0; $y < $image_height; $y++) {
$alpha = (imagecolorat($image_source, $x, $y) >> 24) & 0xFF;
$color = imagecolorallocatealpha($alpha_image, 0, 0, 0, $alpha);
imagesetpixel($alpha_image, $x, $y, $color);
}
}
// Resize image to destination, using gamma correction
imagegammacorrect($image_source, 2.2, 1.0);
imagecopyresampled($new_small_image, $image_source, 0, 0, 0, 0, $new_small_width , $new_small_height, $image_width, $image_height);
imagegammacorrect($new_small_image, 1.0, 2.2);
// Resize alpha channel
$alpha_resized_image = imagecreatetruecolor( $image_width, $image_height);
imagealphablending($alpha_resized_image, false);
imagesavealpha($alpha_resized_image, true);
imagecopyresampled($alpha_resized_image, $alpha_image, 0, 0, 0, 0, $new_small_width ,$new_small_height, $image_width, $image_height);
// Copy alpha channel back to resized image
for ($x = 0; $x < $new_small_width; $x++) {
for ($y = 0; $y < $new_small_height; $y++) {
$alpha = (imagecolorat($alpha_resized_image, $x, $y) >> 24) & 0xFF;
$rgb = imagecolorat($new_small_image, $x, $y); //this is the line that throws the error first and gives a out of bounds related error.
$r = ($rgb >> 16 ) & 0xFF;
$g = ($rgb >> 8 ) & 0xFF;
$b = $rgb & 0xFF;
$color = imagecolorallocatealpha($new_small_image, $r, $g, $b, $alpha);
imagesetpixel($new_small_image, $x, $y, $color);
}
}
// end of new code //
//imagecopyresampled($new_small_image, $image_source, 0, 0, 0, 0, $new_small_width, $new_small_height, $image_width, $image_height);
ob_start(); // Start capturing stdout.
imagePNG($new_small_image);
$sBinaryThumbnail = ob_get_contents(); // the raw jpeg image data.
ob_end_clean(); // Dump the stdout so it does not screw other output.
$sBinaryThumbnail = addslashes($sBinaryThumbnail);
imagedestroy($new_small_image);
} else $sBinaryThumbnail = $lBinaryThumbnail;
imagedestroy($image_source);
Like I said everything works fine for the first run but for some reason on the second run it farts and throws a out of bounds error. it starts at 0,28 and goes on until the end of the loop process at 50,50
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我想通了:)我把上面的代码创建了alpha正确的副本,并将其全部变成了它自己的函数,现在它工作得很好。
I figured it out :) I took the code I had up above that created the alpha correct copy and turned it all into its own function and now it works just fine.