аналог PILS Image.paste в PHP - PullRequest
       4

аналог PILS Image.paste в PHP

0 голосов
/ 27 февраля 2012

Меня попросили перенести приложение Python на PHP (и я не очень люблю PHP).

В части, с которой у меня возникают проблемы при портировании, используется набор монохроматических "шаблонных" изображений на основена замечательной карте икон коллекции от Николас Молле .Эти шаблонные изображения используются для создания иконки с пользовательскими цветами фона и переднего плана.Image.paste в PIL используется для «вставки» переднего плана значка с выбранным цветом с использованием шаблона Image в качестве альфа-маски.Например:

icon creation

Как я могу повторить это в PHP?Есть ли альтернатива, кроме как попиксельное?

[обновление]

Я не горжусь своими навыками PHP ... Что я получил до сих пор:

<?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);
}

?>

Это работает, а производительность - нетплохой.

1 Ответ

1 голос
/ 27 февраля 2012

Согласно моим комментариям, ImageMagick сможет это сделать. Однако вы указали, что это может быть неоптимальным для вашего варианта использования, поэтому рассмотрите возможность использования GD2. На сайте PHP есть демоверсия о том, как объединить изображения .

Я бы предположил, что это можно сделать при любой (довольно недавней) установке PHP по умолчанию.

...