示例#1
0
ImageObject *
CreateDropShadowMask(const ViewportInfo *vpInfo, int offx, int offy, int r)
{
    int rx2 = r * 2;
    int img_w = vpInfo->file->Width();
    int img_h = vpInfo->file->Height();

    ImageObject *mask = new ImageObject(
        offx + r + img_w, offy + r + img_h, 1);

    // Create the blur image
    float *blur = new float[rx2 * rx2];
    //float root2 = sqrt(2.);
    float blurSum = 0.;
    for (int i=0; i<rx2; i++)
    {
        for (int j=0; j<rx2; j++)
        {
            float u = float(i)/float(rx2-1);
            float v = float(j)/float(rx2-1);

            float gu = exp(-pow((4*(u - .5)), 2));
            float gv = exp(-pow((4*(v - .5)), 2));
            float a = gu * gv;
            blur[i*rx2+j] = a;
            blurSum += a;
        }
    }
    for(int j = 0; j < rx2; ++j)
        for(int i = 0; i < rx2; ++i)
            blur[j*rx2 + i] /= blurSum;

    if(vpInfo->opaqueMode == M_OPAQUE)
    {
        int white = 255;
        mask->SetBlockToColor(offx, offy, offx + img_w, offy + img_h, &white);
    }
    else if(vpInfo->opaqueMode == M_TRANSPARENT)
    {
        int gray = int(vpInfo->opacity * 255.);
        mask->SetBlockToColor(offx, offy, offx + img_w, offy + img_h, &gray);
    }
    else
    {
        unsigned char rr, rg, rb;
        rr = vpInfo->transparentColor[0];
        rg = vpInfo->transparentColor[1];
        rb = vpInfo->transparentColor[2];

        // Everywhere that does not match the bg color, color white.
        for(int y = 0; y < img_h; ++y)
        {
            for(int x = 0; x < img_w; ++x)
            {
                unsigned char *src = vpInfo->file->Pixel(x, y);
                unsigned char *dest = mask->Pixel(x+offx, y+offy);

                if(src[0] != rr || src[1] != rg || src[2] != rb)
                    *dest = 255;
            }
        }
    }

    // Blur the mask by convolving it with the blur kernel.
    for(int y = offy; y < offy + img_h; ++y)
    {
        for(int x = offx; x < offx + img_w; ++x)
        {
            int ksrcx = x - r;
            int ksrcy = y - r;
            float channelSum = 0.;
            for(int ky = 0; ky < rx2; ++ky)
            {
                for(int kx = 0; kx < rx2; ++kx)
                {
                    unsigned char *mask_ptr = mask->Pixel(ksrcx + kx, ksrcy + ky);
                    channelSum += float(*mask_ptr) * blur[ky*rx2+kx];
                }
            }
            unsigned char *dest = mask->Pixel(x, y);
            *dest = (unsigned char)(int)(channelSum);
        }
    }

    if(vpInfo->opaqueMode == M_TRANSPARENT)
    {
        int black = 0;
        mask->SetBlockToColor(0, 0, img_w, img_h, &black);
    }
    delete [] blur;

    return mask;
}