我想知道是否可以使用PHP在用户上传的徽标上创建浮雕效果。
这个效果(根据Photoshop部门的说法)可以通过将logo的内容转换为全黑来实现(所以它将是一种颜色),并使该"图层"填充5%(所以基本上它变成了95%的透明度)。之后,他们会在logo的上/左/右边缘添加黑色边框,在logo的下边缘添加白色边框。只是边缘,而不是图像本身的外部;标志内容的边缘需要描摹。
由于我在图像处理方面并不出名,我想知道是否有一些PHP专家可以帮助我/指出我在正确的方向上如何做到这一点?
所以总结起来,我需要的是4件事:
- 将图像内容转换为全黑(但保持透明)
- 设置图像95%透明
- 在图片的上/左/右边缘添加黑色边框
- 在图片 内容的底部边缘添加一个白色边框
如果这可以在IE10及以上浏览器的CSS中实现,这将是一个很好的解决方案。提前感谢!
编辑
这是一个由艺术家创建的徽标的例子,在图像/背景/图案的顶部:http://picpaste.com/embos-example-ngxfSAj5.png -他们做的方式有点不同,因为他们第一次告诉我他们会这样做:)在Photoshop中,他们从上到下添加了黑色的内阴影,从下到上添加了白色的投影
看来我没有问对问题。当把荷兰语(Preeg)的效果翻译成英语时,我想我需要一个浮雕效果。但我发现PHP函数shadeImage是我想要的。为了帮助别人,我将把我做到这一点的方法贴出来。
要使用shadeImage,你必须提供一个黑白图像。这就是我第一次尝试这个函数时出错的地方。因此,我首先创建了一个函数,根据每个像素的alpha通道将图像转换为黑/灰/白。之后我使用了shadeImage。生成的图像确实有背景,必须删除。我尝试使用paintTransparentImage之类的东西,但这在我所有的测试中都不起作用,所以我创建了一个自定义函数,通过再次循环每个像素。最后,我将所有像素的alpha通道值设置为0.35,以使图像在背景上更"柔和"和可用。下面是完整的函数:
public function createEmbossedLogo($imagePath, $embossedFilePath) {
// initialize Imagick and load the image
$imagick = new Imagick(realpath($imagePath));
// make sure we are using PNG, so we can use the alpha channel
$imagick->setImageFormat('png');
// resize the logo, so we do not have to process too many pixels
$imagick->resizeImage(200, null,Imagick::FILTER_CATROM,1);
// if the image does not have any margin around the content,
// the shade would be cut off at the sides,
// so we add an invisible border of 5 pixels, to add some margin
$imagick->borderImage('rgba(255,0,0,0)',5, 5);
// now we have to convert the image to a black/white image, using only the alpha channel
// and use the alpha channel value as the R/G/B channel values
// load the pixels of the image
$imageIterator = $imagick->getPixelIterator();
foreach ($imageIterator as $row => $pixels) { /* Loop through pixel rows */
foreach ($pixels as $column => $pixel) { /* Loop through the pixels in the row (columns) */
/** @var $pixel ImagickPixel */
$nor_color = $pixel->getColor(true); //normalized color
// the alpha channel will be 0 if it is completely invisible and 1 if visibile
// but can be any value in between 0-1
// by using the alpha channel as the white/grey/black value, we create an alpha map
$alpha = $nor_color['a'];
$rgbValue = $alpha*255;
$pixel->setColor('rgba('.$rgbValue.','.$rgbValue.','.$rgbValue.',1');
}
$imageIterator->syncIterator(); /* Sync the iterator, this is important to do on each iteration */
}
// add the shading, the first parameter makes sure that all the 'to be removed' pixels
// are the same color, so we can find them in the next loop through all pixels
// they would otherwise be black, one of the colors we do need to keep in the result
$imagick->shadeImage(true,270,45);
// the shadeImage function will make all the pixels grey that should be transparent
// so we loop over all the pixels in the image once again to remove them
$imageIterator = $imagick->getPixelIterator();
$colorFound = false;
$colorRange = 10;
foreach ($imageIterator as $row => $pixels) { /* Loop through pixel rows */
foreach ($pixels as $column => $pixel) { /* Loop through the pixels in the row (columns) */
/** @var $pixel ImagickPixel */
$color = $pixel->getColor(); //normalized color
if (!$colorFound) {
// since added some margin around the image, we can take the first pixel
// of the top left corner, and use it as the color to make transparent
// and since the image is in black/white, we only need one 'color' channel
$colorFound = array();
$colorFound['r'] = $color['r'];
}
// the default alpha for pixels to keep is 1
$alpha = 1;
// see if the color of this pixel is close to that of the 'color to be deleted'
// if so, we will not totally delete it, but change the alpha channel accordingly
$diff = abs($color['r']-$colorFound['r']);
if ($diff<=$colorRange) {
// set alpha value for this pixel, based on the difference from the removed color
$alpha = $diff / $colorRange;
}
// the entire opacity of the image has to brought down, to make the image a bit 'softer'
$alpha *= 0.35;
// this pixel matches the 'to be removed' color, so we set it to a new value with alpha 0
$pixel->setColor('rgba('.$color['r'].','.$color['g'].','.$color['b'].','.$alpha.')');
}
$imageIterator->syncIterator(); /* Sync the iterator, this is important to do on each iteration */
}
// remove any excess margins that are not needed
$imagick->trimImage(0);
// store the image
$imagick->writeImage($embossedFilePath);
}