counterpart to PIL's Image.paste in PHP

回眸只為那壹抹淺笑 提交于 2019-12-12 03:19:32

问题


I was asked to port a Python application to PHP (and I'm not very fond of PHP).

The part I'm having trouble to port uses a set of monochromatic "template" images based on the wonderful Map Icons Collection by Nicolas Mollet. These template images are used to create an icon with custom background and foreground colors. PIL's Image.paste is used to "paste" the icon foreground with the selected color using the template Image as alpha mask. For example:

How can I replicate this in PHP? Is there any alternative besides doing it pixel-by-pixel?

[update]

I'm not proud of my PHP skills... What I've got so far:

<?php

header('Content-type: image/png');

// read parameters: icon file, foreground and background colors
$bgc = sscanf(empty($_GET['bg']) ? 'FFFFFF' : $_GET['bg'], '%2x%2x%2x');
$fgc = sscanf(empty($_GET['fg']) ? '000000' : $_GET['fg'], '%2x%2x%2x');
$icon = empty($_GET['icon']) ? 'base.png' : $_GET['icon'];

// read image information from template files
$shadow = imagecreatefrompng("../static/img/marker/shadow.png");
$bg = imagecreatefrompng("../static/img/marker/bg.png");
$fg = imagecreatefrompng("../static/img/marker/" . $icon);
$base = imagecreatefrompng("../static/img/marker/base.png");
imagesavealpha($base, true); // for the "shadow"

// loop over every pixel
for($x=0; $x<imagesx($base); $x++) {
    for($y=0; $y<imagesy($base); $y++) {
        $color = imagecolorsforindex($bg, imagecolorat($bg, $x, $y));
        // templates are grayscale, any channel serves as alpha
        $alpha = ($color['red'] >> 1) ^ 127; // 127=transparent, 0=opaque.
        if($alpha != 127) { // if not 100% transparent
            imagesetpixel($base, $x, $y, imagecolorallocatealpha($base, $bgc[0], $bgc[1], $bgc[2], $alpha));
        }
        // repeat for foreground and shadow with foreground color
        foreach(array($shadow, $fg) as $im) {
            $color = imagecolorsforindex($im, imagecolorat($im, $x, $y));
            $alpha = ($color['red'] >> 1) ^ 127;
            if($alpha != 127) {
                imagesetpixel($base, $x, $y, imagecolorallocatealpha($base, $fgc[0], $fgc[1], $fgc[2], $alpha));
            }
        }       
    }
}
// spit image
imagepng($base);
// destroy resources
foreach(array($shadow, $fg, $base, $bg) as $im) {
    imagedestroy($im);
}

?>

It's working and performance is not bad.


回答1:


As per my comments, ImageMagick would be able to do this. However you've indicated that this may not be non-optimal for your use case, so consider using GD2. There's a demo on how to do image merging on the PHP site.

I would guess that this can be done on any (fairly recent) default PHP installation.



来源:https://stackoverflow.com/questions/9467257/counterpart-to-pils-image-paste-in-php

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!