2

我目前正在构建一个电子商务网站(使用 Drupal Commerce)。我们销售定制的运动服装。客户可以选择一种款式、两种颜色和一种尺寸。对于每种样式,有超过三百种颜色组合可供选择。

我正在为 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 来创建一个将选项传递给 product-image.php 的 URL:

<?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,以前从未研究过 GD。我在这里发布了一个粗略的演示(还有一个链接可以下载该页面上使用的所有文件)。

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

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

4

2 回答 2

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;
}
于 2013-08-17T14:05:06.987 回答
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 使所有这些都变得更好。

我已经更新了我的示例页面,所有代码都可以在那里下载。

尽管这个问题没有收到任何回复,但如果不浏览本网站上的许多其他问题,我就不会明白这一点,所以感谢在这里发帖的每个人!

于 2013-08-16T12:11:39.360 回答