您问题的第二部分,如何让折痕“很好地”显示出来可能是个坏主意。尝试它有两个问题:
i) T 恤的变形是物理位移。尽管您可以让折痕照明显示出来,但如果没有相同的物理位移,很难让徽标看起来很逼真。
ii) 颜色的表现确实不一致。只是让徽标变亮/变暗与 T 恤折痕相同的量可能会产生不切实际的效果。例如深色 T 恤 + 折痕 = 亮 50% 的背景。明亮的蓝色徽标 + 50% 更亮的折痕效果 = 看起来不真实的蓝色高光。
我建议使用平底 T 恤作为背景,因为不切实际的效果往往会分散人们的注意力。但你可以这样做:
function getAverageColorString(\Imagick $imagick) {
$tshirtCrop = clone $imagick;
$tshirtCrop->cropimage(100, 100, 90, 50);
$stats = $tshirtCrop->getImageChannelStatistics();
$averageRed = $stats[\Imagick::CHANNEL_RED]['mean'];
$averageRed = intval(255 * $averageRed / \Imagick::getQuantum());
$averageGreen = $stats[\Imagick::CHANNEL_GREEN]['mean'];
$averageGreen = intval(255 * $averageGreen / \Imagick::getQuantum());
$averageBlue = $stats[\Imagick::CHANNEL_BLUE]['mean'];
$averageBlue = intval(255 * $averageBlue / \Imagick::getQuantum());
$colorString = "rgb($averageRed, $averageGreen, $averageBlue)";
return $colorString;
}
$tshirt = new \Imagick(realpath("../images/tshirt/tshirt.jpg"));
$logo = new \Imagick(realpath("../images/tshirt/Logo.png"));
$logo->resizeImage(100, 100, \Imagick::FILTER_LANCZOS, 1, TRUE);
$tshirt->setImageFormat('png');
//First lets find the creases
//Get the average color of the tshirt and make a new image from it.
$colorString = getAverageColorString($tshirt);
$creases = new \Imagick();
$creases->newpseudoimage(
$tshirt->getImageWidth(),
$tshirt->getImageHeight(),
"XC:".$colorString
);
//Composite difference finds the creases
$creases->compositeimage($tshirt, \Imagick::COMPOSITE_DIFFERENCE, 0, 0);
$creases->setImageFormat('png');
//We need the image negated for the maths to work later.
$creases->negateimage(true);
//We also want "no crease" to equal 50% gray later
//$creases->brightnessContrastImage(-50, 0); //This isn't in Imagick head yet, but is more sensible than the modulate function.
$creases->modulateImage(50, 100, 100);
//Copy the logo into an image the same size as the shirt image
//to make life easier
$logoCentre = new \Imagick();
$logoCentre->newpseudoimage(
$tshirt->getImageWidth(),
$tshirt->getImageHeight(),
"XC:none"
);
$logoCentre->setImageFormat('png');
$logoCentre->compositeimage($logo, \Imagick::COMPOSITE_SRCOVER, 110, 75);
//Save a copy of the tshirt sized logo
$logoCentreMask = clone $logoCentre;
//Blend the creases with the logo
$logoCentre->compositeimage($creases, \Imagick::COMPOSITE_MODULATE, 0, 0);
//Mask the logo so that only the pixels under the logo come through
$logoCentreMask->compositeimage($logoCentre, \Imagick::COMPOSITE_SRCIN, 0, 0);
//Composite the creased logo onto the shirt
$tshirt->compositeimage($logoCentreMask, \Imagick::COMPOSITE_DEFAULT, 0, 0);
//And Robert is your father's brother
header("Content-Type: image/png");
echo $tshirt->getImageBlob();
生成如下图像: