我拼凑了一个PHP类,使用PHP的GD函数执行各种与图像相关的函数。
适用于所有图像类型。旋转,翻转,调整大小,裁剪水印等。
除了后者之外的所有工作都很完美。例如,经过一些更改后,旋转的PNG图像保持其透明度,而在它们丢失之前,背景变黑。看来常见的问题。但现在都在工作。
我仍然陷入困境的是将PNG图像与另一个PNG图像加水印。它似乎与JPG和其他图像一起使用。这是代码(简化):
public function writeWatermarkSimple()
{
$watermarkFile = 'watermark.png';
$watermarkImage = imagecreatefrompng($watermarkFile);
imagealphablending($watermarkImage, false);
imagesavealpha($watermarkImage, true);
$imageFile = 'image.png';
$baseImage = imagecreatefrompng($imageFile);
imagealphablending($baseImage, false);
imagesavealpha($baseImage, true);
$marginH = imagesx($baseImage) - imagesx($watermarkImage);
$marginV = imagesy($baseImage) - imagesy($watermarkImage);
$cut = imagecreatetruecolor(imagesx($watermarkImage), imagesy($watermarkImage));
imagecopy($cut, $baseImage, 0, 0, $marginH, $marginV, imagesx($watermarkImage), imagesy($watermarkImage));
imagecopy($cut, $watermarkImage, 0, 0, 0, 0, imagesx($watermarkImage), imagesy($watermarkImage));
imagecopymerge($baseImage, $cut, $marginH, $marginV, 0, 0, imagesx($watermarkImage), imagesy($watermarkImage), 80);
if (!imagepng($baseImage, 'watermarked_image.png'))
{
return false;
}
return true;
}
这与人们根据类似问题提供的各种指南和建议拼凑在一起。再次,与JPG图像和PNG水印完美配合,但不是PNG& PNG。
一些示例图片:
http://i.imgur.com/hHRWinj.png - 这是我正在使用的水印。 http://i.imgur.com/6sy8Ncs.png - 这是我正在应用水印的图像。 http://i.imgur.com/ghovYLm.png - 这是最终结果。
我觉得有趣的是,覆盖在图像的非透明部分上的水印的任何部分都能正常工作。其余部分都是黑色背景。
这让我相信自己很亲密,我希望你这些优秀人才的专业知识可以帮助我找到解决方案。
非常感谢您阅读。
答案 0 :(得分:1)
所以,我并没有放弃使用GD来找到正确的答案。但是,我非常高兴地发现,使用ImageMagick时,使用GD可以实现最多需要30行代码的代码:
$image = new Imagick();
$image->readimage($this->_image);
$watermark = new Imagick();
$watermark->readimage($this->_watermark->_getImage());
$watermark->evaluateImage(Imagick::EVALUATE_DIVIDE, 2, Imagick::CHANNEL_ALPHA);
$image->compositeImage($watermark, imagick::COMPOSITE_OVER, $marginH, $marginV);
所以这是之前(使用GD): http://i.imgur.com/AlS0TcO.png
之后(使用ImageMagick和上面的代码): http://i.imgur.com/zBxlC3R.png
如果有人的答案纯粹是GD,那么我会非常感激。
答案 1 :(得分:1)
最近遇到了一些类似的问题,虽然这可能无法解决你的问题,但这些都是我发现的一些有用的发现。
在我的情况下,我有一张原始.jpg
图片和一张水印.png
图片。水印图像具有完全透明的背景。我想在我的脚本中指定不透明度,并在将其置于原始图像顶部之前更改水印不透明度。关于PHP水印的大多数帖子假设原始水印.png
文件已经将实心水印部分设置为正确的不透明度,而不是通过脚本更改它。
gd
并不喜欢24位.png
并导致一些愚蠢的问题。使用gd
切换到8位解析。另一方面,imagick
与24位.png
的效果非常好,最终结果似乎更好。gd
并使用.png
设置水印透明度,则使用imagecopymerge()
工作正常。但是,如果我首先尝试缩放原始水印.png
(具有透明背景),那么我会得到与水印图像所在的黑色或白色背景部分类似的结果。首先使用透明矩形填充新的wm图像,查看How do I resize pngs with transparency in PHP?的部分解决方案。对我来说,无论我尝试什么,这仍然会在最终结果上产生不透明的白色背景。imagick
并使用setImageOpacity()
更改了我的水印.png
的透明度,然后将其应用于我的原始图像之前,我仍然获得相同的效果黑色背景。最后请在setImageOpacity()
中查看.png
,如果原始evaluateImage()
有任何透明像素,并且您尝试降低不透明度,那么这些像素将变为不透明(黑色)并应用新的透明度。相反,需要使用gd
函数。这将仅改为评估每个像素的alpha通道并除以特定数字。imagick
的黑/白背景问题可能是由于与gd
相比,在缩放/合并时处理Alpha通道的方式类似,并且如果您想在alpha
中执行此操作{1}}您只需要找到一些类似的方法来评估和操作每像素imagick
频道,因为" easy"方式似乎采用已经透明的背景并使其不透明。所以,解决方案:
假设您要以45%的不透明度应用水印并且使用$watermark->setImageOpacity(.45);
,那么请改为:
$watermark->evaluateImage(Imagick::EVALUATE_DIVIDE, (1/.45), Imagick::CHANNEL_ALPHA);
这样做
1
您需要将1/.45
除以不透明度,以获得该函数将为每个像素划分Alpha通道值的示范器。在这种情况下,2.2222
= 2.2222
,那么函数会将每个像素的Alpha通道除以1
。这意味着完整时,实体像素(1/2.2222
的alpha)将导致.45
或0
alpha或透明度。任何已经透明的像素(alpha 0
)都会保持透明,因为compositeImage()
除以任何东西总是如此?零!
更改水印透明度后,您可以使用df = df.replace({'diag_1' : {'(1-139)' : 0, '(140-239)' : 1}})
将水印合并到原始图像上。