senti ti assicuro che funziona... ti posto una classe che scrissi tempo fa e fa esattamente quello che chiedi più una serie di features per la creazione di thumbnail per le immagini.

codice:
<?
/**
 * @author Fernando Marinò
 * Ridimensiona un'immagine e ne sceglie la destinazione
 * last build: 18-07-2003
 */
class Thumbnail {
	var $path;
	var $GD;
	var $error = false; // flag booleano
	
	/** $imageSize index:
	 * [0] => width
	 * [1] => height
	 * [2] => type (constant)
	 * [3] => size IMG tag
	 */
	var $imageSize;
	
	/**
	 * formati ammessi in lettura:
	 * IMG_JPG, IMG_PNG, IMG_GIF
	 */
	
	function Thumbnail($path) {
		$this->path = $path;
		$this->imageSize = @getImageSize($path);
		
		if(!$this->imageSize) 				$this->_error("immagine non~trovata o~formato file~errato");
		if($this->imageSize[2] > IMG_PNG)	$this->_error("formato~immagine non~supportato");
	} // end CONSTRUCT
	
	function resize($maxsize, $percent = 100) {
		if($this->error) return;
		
		// calcolo il lato dell'immagine
		$widthSource = ($this->imageSize[0] * $percent) / 100;
		$heightSource = ($this->imageSize[1] * $percent) / 100;
		// calcolo offset
		$offsetW = @(($this->imageSize[0] * (100 - $percent)) / 100);
		$offsetH = @(($this->imageSize[1] * (100 - $percent)) / 100);
		$offsetW /= 2;
		$offsetH /= 2;
		
		// determina il lato maggiore
		if($widthSource > $heightSource && !$fisso) {
			$height = ($heightSource * $maxsize) / $widthSource; // applico la proporzione
			$width 	= $maxsize;
		} else {
			$width 	= ($widthSource * $maxsize) / $heightSource; // applico la proporzione
			$height = $maxsize;
		}
		// carico in memoria l'immagine originale
		switch($this->imageSize[2]) {
			case IMG_GIF:
				$im = imageCreateFromGif($this->path);
				break;
			case IMG_JPG:
				$im = imageCreateFromJpeg($this->path);
				break;
			case IMG_PNG:
				$im = imageCreateFromPng($this->path);
				break;
		}

		$this->GD = imagecreatetruecolor($width, $height);
		imagefilledrectangle($this->GD, 0, 0, $width, $height, imagecolorallocate($im, 255, 255, 255));

		imagecopyresampled($this->GD, $im, 0, 0, $offsetW, $offsetH, $width, $height, $widthSource, $heightSource);
		imagedestroy($im);
	}
	
	// private <==
	function _error($msg) {
		$this->error = true;
		// allocazione immagine e colori fondamentali
		$im = imagecreate(120, 120);
		$white = imagecolorallocate($im, 255, 255, 255);
		$red = imagecolorallocate($im, 255, 0, 0);
		$black = imagecolorallocate($im, 0, 0, 0);	
		
		imagestring($im, 3, 10, 10, "-- Error --", $red);
		
		$token = explode('~', $msg);
		$y = 25;
		for($i = 0; $i < count($token); $i++) {
			imagestring($im, 3, 12, $y, $token[$i], $black);
			$y += 12;
		}
		
		$this->GD = $im;
	}
	
	function getGD() {
		// ritorna un flusso GD per la thumbnail
		return $this->GD;
	}
	
	/**
	 * parametri consentiti per $format:
	 * IMG_JPG, IMG_PNG
	 */ 
	function saveAt($destination, $format = IMG_JPG) {
		if(!isset($this->GD))
			// carico in memoria l'immagine originale
			switch($this->imageSize[2]) {
				case IMG_GIF:
					$this->GD = imageCreateFromGif($this->path);
					break;
				case IMG_JPG:
					$this->GD = imageCreateFromJpeg($this->path);
					break;
				case IMG_PNG:
					$this->GD = imageCreateFromPng($this->path);
					break;
			}
	
		
		// salva la thumbnail in una cartella
		switch($format) {
			case IMG_JPG:
				imagejpeg($this->GD, $destination);
				break;
			case IMG_PNG:
				imagePng($this->GD, $destination);
				break;
		}
	}
	
	function quadro($quadro, $percent = 100) {
		if($this->error) return;
		
		$cornice = @imagecreatefromgif($quadro);
		if(!$cornice) {
			$this->_error("quadro non~trovata o~formato file~errato");
			return;
		}
		
		if(imagesx($cornice) > imagesy($cornice))
			$this->resize(imagesx($cornice), $percent, imagesy($cornice));
		else 
			$this->resize(imagesy($cornice), $percent, imagesx($cornice));
		
		imagecopyresampled($this->GD, $cornice, 0, 0, 0, 0, imagesx($cornice), imagesy($cornice), imagesx($cornice), imagesy($cornice));
	}
	
	function adattata() {
		if($this->error) return;
		
		// carico in memoria l'immagine originale
		switch($this->imageSize[2]) {
			case IMG_GIF:
				$im = imageCreateFromGif($this->path);
				break;
			case IMG_JPG:
				$im = imageCreateFromJpeg($this->path);
				break;
			case IMG_PNG:
				$im = imageCreateFromPng($this->path);
				break;
		}
		
		if(max($this->imageSize[0], $this->imageSize[1]) <= 600) {
			$this->GD = $im;
			return;
		}
		
		$this->resize(600);
	}	
		
	function addLogo($logo) {
		// carico in memoria l'immagine originale
		switch($this->imageSize[2]) {
			case IMG_GIF:
				$im = imageCreateFromGif($this->path);
				break;
			case IMG_JPG:
				$im = imageCreateFromJpeg($this->path);
				break;
			case IMG_PNG:
				$im = imageCreateFromPng($this->path);
				break;
		}
		
		// carico il logo
		$logo = imagecreatefromgif($logo);
		imagecopyresampled($im, $logo, imagesx($im) - 20 - imagesx($logo),
									   imagesy($im) - 20 - imagesy($logo), 0, 0, imagesx($logo), 
									   imagesy($logo), imagesx($logo), imagesy($logo));
		
		$this->GD = $im;
	} // end addLogo
} // end Thumbnail
?>
il metodo in questione è l'ultimo, addLogo, ed è studiato appositamente per consentire immagini con trasparenze, a suo tempo ebbi lo stesso problema

per utilizzarla:
$obj = new Thumbnail("path/dell'immagine/di/sfondo.jpg");
$obj->addLogo("path/del/logo.png-gif");
per salvare l'immagine puoi usare il metodo saveAt o ritornare direttamente il reference dell'immagine e utilizzarlo come ti piace con getGD. Se non ti funziona dimmi che errore ti da, versione di php e librerie GD