function ImagePngWithAlpha($file, $x, $y, $w=0, $h=0, $link='')
{
    $tmp_alpha = tempnam('.',  'mska');
    $this->tmpFiles[] = $tmp_alpha;
    $tmp_plain = tempnam('.',  'mskp');
    $this->tmpFiles[] = $tmp_plain;
    
    list($wpx,  $hpx) = getimagesize($file);
    $img = imagecreatefrompng($file);
    $alpha_img = imagecreate( $wpx,  $hpx );
    
    // generate gray scale pallete
    for($c=0;$c<256;$c++) ImageColorAllocate($alpha_img,  $c,  $c,  $c);
    
    // extract alpha channel
    $xpx=0;
    while ($xpx<$wpx){
        $ypx = 0;
        while ($ypx<$hpx){
            $color_index = imagecolorat($img,  $xpx,  $ypx);
            $alpha = 255-($color_index>>24)*255/127; // GD alpha component: 7 bit only,  0..127!
            imagesetpixel($alpha_img,  $xpx,  $ypx,  $alpha);
        ++$ypx;
        }
        ++$xpx;
    }

    imagepng($alpha_img,  $tmp_alpha);
    imagedestroy($alpha_img);
    
    // extract image without alpha channel
    $plain_img = imagecreatetruecolor ( $wpx,  $hpx );
    imagecopy ($plain_img,  $img,  0,  0,  0,  0,  $wpx,  $hpx );
    imagepng($plain_img,  $tmp_plain);
    imagedestroy($plain_img);
    
    //first embed mask image (w,  h,  x,  will be ignored)
    $maskImg = $this->Image($tmp_alpha,  0, 0, 0, 0,  'PNG',  '',  true); 
    
    //embed image,  masked with previously embedded mask
    $this->Image($tmp_plain, $x, $y, $w, $h, 'PNG', $link,  false,  $maskImg);
}