Problem with transparency

[email protected] (Brian Peschel) Fri, 26 Sep 2008 10:09:48 -0500
Newsgroups php.gd.devel
Message-ID <[email protected]>
I am having a bit of a problem with transparency with GD.  Basically, I 
am creating an image and I want to insert a smaller image into the one I 
am creating.  It is working if I use a GIF image.  It is failing if I 
use a XPM, JPG, or PNG image.  I am sure I am missing something, but not 
sure what it is.

In a nut shell, here is what I am doing.....

    _image = gdImageCreateTrueColor(xPixels, yPixels);
    // Allocate the first color
    gdImageColorAllocate(_image, backgroundColor.red(), 
backgroundColor.green(), backgroundColor.blue());

    // Fill the background
    setColor(backgroundColor);
    setLineWidth(1);
    setLineStyle(LINE_STYLE_SOLID);
    gdPoint* points = new gdPoint[4];
    points[0].x = xPixels;
    points[0].y = 0;
    points[1].x = xPixels;
    points[1].y = yPixels;
    points[2].x = 0;
    points[2].y = yPixels;
    points[3].x = 0;
    points[3].y = 0;
    gdImageFilledPolygon(_image, points, 4, gdStyled);
    delete[] points;

<snip>
    // Figure out what kind of image file it is
    std::string extension = fileName.substr(fileName.length() - 3, 
fileName.length());
    if (extension[0] == '.')
        extension = extension.substr(1, extension.length());
    imageType = ImageProcessor::getImageType(extension);

    if (imageType == ImageProcessor::Xpm || imageType == 
ImageProcessor::Pm || imageType == ImageProcessor::Ip)
    {
        // XPM
        char tmpFilename[fileName.length() + 1];
        strcpy(tmpFilename, fileName.c_str());
// TODO: Check future versions of GD to see if it accepts const char* 
here since 1.8.4 doesn't
        symbolImage = gdImageCreateFromXpm(tmpFilename);
    }
    else if (imageType == ImageProcessor::Jpeg)
    {
        FILE* jpgFile = fopen(fileName.c_str(), "rb");
        symbolImage = gdImageCreateFromJpeg(jpgFile);
        fclose(jpgFile);
    }
    else if (imageType == ImageProcessor::Png)
    {
        FILE* pngFile = fopen(fileName.c_str(), "rb");
        symbolImage = gdImageCreateFromPng(pngFile);
        fclose(pngFile);
    }
    else if (imageType == ImageProcessor::Gif)
    {
        FILE* gifFile = fopen(fileName.c_str(), "rb");
        symbolImage = gdImageCreateFromGif(gifFile);
        fclose(gifFile);
    }

    if (symbolImage == NULL)
    {
        return;
    }

    imageWidth = gdImageSX(symbolImage);
    imageHeight = gdImageSY(symbolImage);

    // adjust the start point to the left-top
    from.x() -= imageWidth / 2;
    int y = static_cast< int >( _pictureHeight - (from.y() + imageHeight 
/ 2 ));

    gdImageCopy(_image, symbolImage, (int)round(from.x()), y, 0, 0, 
(int)round(imageWidth), (int)round(imageHeight));
    gdImageDestroy(symbolImage);

If I add in a debug line after loading the image of:
std::cout << fileName << " Width " << imageWidth << " height " << 
imageHeight << " transparent " << gdImageGetTransparent(symbolImage) << 
std::endl;

after loading the image I get these results:
school.gif Width 20 height 10 transparent 3
school.xpm Width 20 height 10 transparent -1
school.jpg Width 20 height 10 transparent -1
school.png Width 20 height 10 transparent -1

The XPM was created first and I used the ImageMagick tool convert to 
change the XPM to each format.  The GIMP appears to show the transparent 
background for all 4 images.  Since it is small, here is the XPM:
/* XPM */
static char *school_xpm[] = {
"20 10 4 1",
". c None",
"0 c #ffff00",
"1 c #ff0000",
"2 c #0000ff",
"....................",
"22222222222222222222",
"......22222222...00.",
".....2222222222..00.",
"....222222222222.00.",
"...2222222222222211.",
"..22222222222222000.",
".222222222222220200.",
"22222222222222022020",
"....................",
} ;

As it stands, it works using a GIF.  But it would be convenient for me 
to use an XPM as everything else in my program uses XPMs.

This is on Fedora 8, using GD 2.0.35-1 and ImageMagick 6.3.5.9-1.

Thanks in advance,
Brian