如何动态生成两个颜色的产品图像?

时间:2013-08-14 23:48:57

标签: image dynamic colors product variations

我目前正在建立一个电子商务网站(使用Drupal Commerce)。我们出售定制的运动服装。客户可以选择一种风格,两种颜色和一种尺寸。对于每种风格,可以选择超过300种颜色组合。

我正在为Illustrator中的产品创建图稿。它们是相当简单的矢量,仅使用两种平面颜色,顶部带有黑色轮廓。

我试图找到一种方法来为每种风格生成所有颜色组合,最好是动态的。我看过GD,但我不确定它会在这里发挥作用。我想知道是否有办法使用SVG(因为我已经有矢量)或堆叠3个可以应用颜色叠加的透明PNG并保持透明度? 完成。

为了动态创建图像,我创建了一个包含白色背景的GIF和一个纯红色和纯蓝色区域来定义主要和次要区域。这是通过GD运行的,它将红色和蓝色更改为用户选择的颜色。然后在顶部合并透明PNG,其中包含黑色轮廓和公司徽标。

在index.php上我有一个表单,允许用户选择一种样式和两种颜色:

    <form method="post" action="index.php">
    <label for="style">Style:</label>
    <select id="style" name="style" required>
        <option value="0001">Vertical Stripe</option>
        <option value="0002">V Neck</option>
        <option value="0003">Contrast Side</option>
        ...
    </select>
    <br><br>
    <label for="color1">Color 1:</label>
    <select id="color1" name="color1" required>
        <option></option>
        <option value="134,84,66">Retro Brown</option>
        <option value="115,51,68">Claret</option>
        <option value="167,57,52">Deep Red</option>
        <option value="213,69,54">Bright Red</option>
        ...
    </select>
    ...
</form>

表单提交后,有一些PHP用于创建一个URL,将选项传递给product-image.php:

<?php
    $url = "product-image.php";

    if (isset($_POST["style"])) {
        $url = $url . "?style=" . $_POST["style"]; 
    }
    if (isset($_POST["color1"])) {
        $url = $url . "&color1=" . $_POST["color1"];
    }
    if (isset($_POST["color2"])) {
        $url = $url . "&color2=" . $_POST["color2"];
    }

?>

<img class="product" src="<?php echo $url; ?>">

然后大部分工作由product-image.php完成:

// Set some dummy values to avoid errors
$style = "0001";
$color1 = array(255,255,0);
$color2 = array(0,0,200);

if (isset($_GET["style"])) {
    $style = $_GET["style"];
}

$colorFile = $style . "colors.gif";
$outlineFile = $style . "outline.png";

// Load image with coloured sections
$image_1 = imagecreatefromgif($colorFile);
// Load image with outlines 
$image_2 = imagecreatefrompng($outlineFile);            

imagealphablending($image_1, true);
imagesavealpha($image_1, true);

imagetruecolortopalette($image_1, false, 255);

// Import $color1 values to create an RGB array
if (isset($_GET["color1"])) {
    $color1 = explode(',', $_GET["color1"]);                
}
// Import $color2 values to create an RGB array
if (isset($_GET["color2"])) {               
    $color2 = explode(',', $_GET["color2"]);
}

// Define Primary (red) region
$region1 = imagecolorclosest ( $image_1, 255,0,0);

// Set new colour for $region1 using the values passed into $color1
imagecolorset($image_1, $region1, $color1[0], $color1[1], $color1[2]); 

// Get Secondary (blue) region
$region2 = imagecolorclosest ( $image_1, 0,0,255);

// Set new colour for $region2 using the values passed into $color2
imagecolorset($image_1, $region2, $color2[0], $color2[1], $color2[2]);

// Create a true color canvas, this seems to retain transparency when merging PNG & GIF
$merged_image = imagecreatetruecolor(339, 390);

// Merge the newly coloured sections
imagecopy($merged_image, $image_1, 0, 0, 0, 0, 339, 390);

// Merge the outlines on top    
imagecopy($merged_image, $image_2, 0, 0, 0, 0, 339, 390);   

// Tell browser to expect PNG
header("Content-type: image/png");

// Output new PNG                       
imagepng($merged_image);        

// Tidy up
imagedestroy($image_1);                                     
imagedestroy($image_2);
imagedestroy($merged_image);

我对结果很满意,因为我还在学习PHP,之前从未考虑过G​​D。我发布了rough demo here(还有一个链接可以下载该页面上使用的所有文件)。

有任何改进建议吗?最终,我希望用户在下拉列表中选择两种颜色,然后脚本将查看是否存在具有这些选项的图像,如果不存在,则通过设置两个区域的颜色来动态创建它,然后存储新创建的图像面向未来的用户。

如何在不需要提交按钮的情况下自动更新?

2 个答案:

答案 0 :(得分:1)

所有上述工作现在我已经得到它来存储它创建的图像并添加一个检查,以确定图像是否在那里尝试创建它之前。链接的示例已使用所有代码进行了更新,但这里是感兴趣的任何人的新product-image.php文件。

$style = "0001";                    // Dummy values to avoid errors
$color1 = array(247,228,064);
$color2 = array(031,076,146);

$templatePath = "../templates/";        // Relative path from this file to your templates

if (isset($_GET["style"])) {
    $style = $_GET["style"];                    // Replace $style with real value if recieved
}

if (isset($_GET["color1"])) {
    $color1 = explode(',', $_GET["color1"]);    // Replace $color1 with real RGB array if recieved
}

if (isset($_GET["color2"])) {               
    $color2 = explode(',', $_GET["color2"]);    // Replace $color2 with real RGB array if recieved
}

// Create unique output file name by concatenating all numerical values eg:0001247228522562146.png
$outputFileName = $style . implode("", $color1) . implode("", $color2) . ".png";

// Check if the image we want already exists
if (file_exists($outputFileName)) {

    // If it does then open the file in a binary mode
    $fp = fopen($outputFileName, 'rb');

    // send the right headers
    header("Content-Type: image/png");
    header("Content-Length: " . filesize($outputFileName));

    // dump the picture and stop the script
    fpassthru($fp);
    exit;

} else {        // If it doesn't already exist then lets create the image...

    $colorFile = $templatePath . $style . "colors.gif";
    $outlineFile = $templatePath . $style . "outline.png";

    $image_1 = imagecreatefromgif($colorFile);              // Load image with coloured sections
    $image_2 = imagecreatefrompng($outlineFile);            // Load image with outlines

    imagealphablending($image_1, true);
    imagesavealpha($image_1, true);

    imagetruecolortopalette($image_1, false, 255);

    $region1 = imagecolorclosest ( $image_1, 255,0,0);                          // Get Primary (red) region
    imagecolorset($image_1, $region1, $color1[0], $color1[1], $color1[2]);      // Set new colour for $region1

    $region2 = imagecolorclosest ( $image_1, 0,0,255);                          // Get Secondary (blue) region
    imagecolorset($image_1, $region2, $color2[0], $color2[1], $color2[2]);      // Set new colour for $region2

    $merged_image = imagecreatetruecolor(339, 390);             // Create a true color canvas

    imagecopy($merged_image, $image_1, 0, 0, 0, 0, 339, 390);   // Merge the newly coloured sections
    imagecopy($merged_image, $image_2, 0, 0, 0, 0, 339, 390);   // Merge the outlines on top

    header("Content-type: image/png");                          // Tell browser to expect PNG
    imagepng($merged_image, $outputFileName);                   // Save new PNG to server

    imagedestroy($image_1);                                     // Tidy up
    imagedestroy($image_2);
    imagedestroy($merged_image);

    // open the image we just created in a binary mode
    $fp = fopen($outputFileName, 'rb');

    // send the right headers
    header("Content-Type: image/png");
    header("Content-Length: " . filesize($outputFileName));

    // dump the picture and stop the script
    fpassthru($fp);
    exit;
}

答案 1 :(得分:0)

使用上面的代码并添加几行jQuery,我终于实现了我的最初目标。

jQuery:

    $('select').click(function() {
        var style = $("select#style").val();
        var color1 = $("select#color1").val();
        var color2 = $("select#color2").val();
        var productImgURL = 'product-image.php?style='+ style + '&color1=' + color1 + '&color2=' + color2;
        $('.product').attr('src',productImgURL);
    });

只要修改了选择框,jQuery就会通过附加值来从product-image.php请求不同的图像。互动很顺利,完全符合我的要求。

现在我只需要弄清楚如何存储生成的图像并添加一个检查以查看它们是否已经生成。然后我必须使用Drupal Commerce使这一切都很好。

我已更新my example page,所有代码均可在此处下载。

虽然这个问题没有收到任何回复,但如果没有在网站上搜索其他许多问题,我就不会想到这一点,所以感谢在这里发帖的所有人!