1

We are trying to implement a PHP server script that will allow the user to change the color on part of a product image. For example, if you had a wooden chair with a red fabric seat, and wanted to change only the fabric color.

We had previously implemented a system in Flash; the product images are JPGs, and the color-editable regions are defined by masks stored as separate PNGs with transparency. A copy of the original image is made using the alpha values of the mask, and placed on a new layer above the original image, in effect copying the color-editable region onto a new layer. The user can then color-edit this new layer.

Since we already have the PNG masks, we are trying to accomplish the same functionality in PHP to make it accessible to more end-users. I've tried modifying the script from PHP GD Use one image to mask another image, including transparency , and came up with the following

<?php
// Load source and mask
$source = imagecreatefromjpeg( 'source' );
$mask = imagecreatefrompng( 'destination' );
// Apply mask to source
imagealphamask( $source, $mask );
// Output
header( "Content-type: image/png");
imagepng( $source );

function imagealphamask( &$picture, $mask ) {
    // Get sizes and set up new picture
    $xSize = imagesx( $picture );
    $ySize = imagesy( $picture );
    $newPicture = imagecreatetruecolor( $xSize, $ySize );
    imagesavealpha( $newPicture, true );
    imagefill( $newPicture, 0, 0, imagecolorallocatealpha( $newPicture, 0, 0, 0, 127 ) );

    // Resize mask if necessary
    //if( $xSize != imagesx( $mask ) || $ySize != imagesy( $mask ) ) {
       // $tempPic = imagecreatetruecolor( $xSize, $ySize );
       // imagecopyresampled( $tempPic, $mask, 0, 0, 0, 0, $xSize, $ySize, imagesx( $mask ), imagesy( $mask ) );
       // imagedestroy( $mask );
       // $mask = $tempPic;
    //}

    // Perform pixel-based alpha map application
    for( $x = 0; $x < $xSize; $x++ ) {
        for( $y = 0; $y < $ySize; $y++ ) {
            $alpha = imagecolorsforindex( $mask, imagecolorat( $mask, $x, $y ) );
            $alpha = $alpha['alpha'];
            $color = imagecolorsforindex( $picture, imagecolorat( $picture, $x, $y ) );
            //preserve alpha by comparing the two values
            //if ($color['alpha'] > $alpha)
               //$alpha = $color['alpha'];
            //kill data for fully transparent pixels
            if ($alpha == 127) {
                $color['red'] = 0;
                $color['blue'] = 0;
                $color['green'] = 0;
            }
        imagesetpixel( $newPicture, $x, $y, imagecolorallocatealpha( $newPicture, $color[ 'red' ], $color[ 'green' ], $color[ 'blue' ], $alpha ) );
        }
    }

    //TODO: colorize the new layer in some way here, e.g. imagefilter($newPicture, IMG_FILTER_COLORIZE, 150, 90, 0);

    //place the new layer above the original image
   imagecopymerge($picture,$newPicture,0,0,0,0,$xSize,$ySize,100);

}

?>

I don't know any PHP, but the above script seems like it should do what we want. Instead, it cuts out the correct region but surrounds it with black.

I really don't know what the problem is, unless it's related to the source image being a JPG instead of a PNG. I tried converting to truecolor but it didn't affect the output.

Also... this code is way too slow. It takes over five seconds to generate the image. Should we be taking a completely different approach/using a different framework? I don't really know anything about web development, but I was assigned this job and have to complete it.

Community
  • 1
  • 1
user45623
  • 621
  • 4
  • 18
  • I should have read the comments for imagecopymerge. The documentation incorrectly suggests the function supports alpha, but it does not. There are solutions in the comments at http://www.php.net/manual/en/function.imagecopymerge.php It still takes over 10 seconds to generate the image, which is unacceptable, so if anyone has any suggestions in that regard we'd much appreciate them. – user45623 Feb 19 '13 at 01:11
  • Did you have any luck finding a solution? – Louis W Feb 12 '14 at 15:01
  • I did, but to be honesty it's been so long I can't remember the solution. They stopped paying me on time and I stopped working for them, so I no longer have access to those files. – user45623 Mar 15 '14 at 07:04

0 Answers0