phpenis: png skalierungsproblem (farben crashen)

moin!

ich schreibe gerade an einer klasse, die bilder-krimskrams managed. hierbei soll die klasse ausschl. jpegs und pngs verwenden.jetzt das eigentliche problem:

in der methode imageScale() ziehe ich mir binärdaten aus einem x-beliebigen file und  kreiere ein neues, skaliertes mit imagecreatfromstring(). wenn ich nun die methode imagePreview() verwende und einen skalierungsfaktor angebe, der über 60px höhe liegt, crashen die farben des pngs. wenn das bild noch grösser skalieren soll, stellt der browser dieses überhaupt nicht mehr dar. bei jpegs funktioniert alles tadellos.

hier die klasse:

Blob.php

<?php /*   Class Blob   experimental ... */

class Blob {   function Blob (){     // coming soon ...   }

/* This function takes the information given from a form field that posts a single file.     It returns an associative array with the values: "Name", "Type", "Size", "Data", "IsFile", "Reason".

You may use the array for feeding the other methods to manipulate the uploaded file.

The "IsFile" and "Reason" values also appear in many methods of this class for more comfortable bugfixing.     If you want to use the debugging output, you may additionally set $exit_on_empty_file to TRUE.

If you don't want the Data to be slashed for database, you have to set $raw to TRUE. On the calling side, of course!

This function may be the constructor someday ... */   function prepareBlob ($file="", $file_name="", $file_type="", $file_size="", $exit_on_empty_file=FALSE, $raw=FALSE){

$file_data["Name"]    = $file_name;     $file_data["Type"]    = $file_type;     $file_data["Size"]    = $file_size;

if($file!="" && $file!="none"){

$file = @fopen($file, "r");

if(!$raw)         $data = @addslashes(@fread($file, $file_data["Size"]));       else         $data = @fread($file, $file_data["Size"]);

@fclose($file);

$file_data["Data"]  = $data;       $file_data["IsFile"] = TRUE;       $file_data["Reason"] = "<b>File successfully prepared for adding into the db!</b><br>";       return $file_data;

}else{       $text = "<b>WARNING: File seems to be empty or not uploaded!</b><br>";       if($exit_on_empty_file){         echo $text;         exit;       }else{         $ret["IsFile"] = FALSE;         $ret["Reason"] = $text;         return $ret;       }     }

}

/* Checks wether the file's size fits with given max size */   function checkBlobSize ($file_size, $max_size, $exit_on_large_file = FALSE){     if($file_size>$max_size){       $text = "<b>File is too big (".$file_size." bytes) but maximum filesize is set to ".$max_size." bytes!</b><br>";       if($exit_on_large_file){         echo $text;         exit;       }else{         $ret["IsFile"] = FALSE;         $ret["Reason"] = $text;         return $ret;       }     }else{       $ret["IsFile"] = TRUE;       $ret["Reason"] = "<b>Filesize is ".$file_size." bytes. And this seems to fit with the maximum filesize       of ".$max_size." bytes.</b><br>";       return $ret;     }   }

/* Check allowed images. needs array with supported_mime_types and the given mime_type.     checks if they match with given mime type. maybe we could also call it mimeTypeCheck() ... */   function checkIfIsImage ($mime_type, $supported_mime_types, $exit_on_wrong_mime_type = FALSE){     $mime_count = count($supported_mime_types);     $text1 = "<b>The given mime type ".$mime_type." doesn't fit with settings for supported mime types!</b><br>";     $text2 = "<b>The mime type is ".$mime_type." and fits with the settings for supported mime types!</b><br>";

$mime_count = count($supported_mime_types);

for($i=0;$i<$mime_count;$i++){       $list .= trim($supported_mime_types[$i])."|";     }     // cut the last | (vertical line) for correct regexp     $list = substr($list,0,-1);

if(ereg($list,$mime_type)){       $ret["IsFile"] = TRUE;       $ret["Reason"] = $text2;       return $ret;     }else{       if($exit_on_wrong_mime_type){         echo $text1." <b>Quitting now ...</b><br>";         exit;       }else{         $ret["IsFile"] = FALSE;         $ret["Reason"] = $text1;         return $ret;       }     }

}

/* Add binary data to a temporary file */   function imagePreviewMaker ($data){     $tmpfname = @tempnam ("/tmp", "ImgPre.");

$file = @fopen($tmpfname, "w");     @fwrite($file, $data);     @fclose($file);

$ret["IsFile"] = TRUE;     $ret["Reason"] = "<b>Temporary file has been successfully created!</b><br>";     $ret["File"]  = $tmpfname;

return $ret;   }

/* Throws the binary contents to a file for streamimg to browser. If width and height are set,     the image will be scaled. If you're using jpegs, you may additionally take use of the quality     option. */   function imagePreview ($file, $width=FALSE, $height=FALSE, $quality = 20, $filename = FALSE){     $mime_type = $this->testMimeType($file);

header("Content-Type: ".$mime_type);     if($filename!=FALSE){       header("Content-Disposition: filename=".$filename);     }     if($width!=FALSE && $height!=FALSE){       $imgB = $this->imageScale($file, $width, $height);       switch ($mime_type){         case "image/jpeg": ImageJPEG($imgB,'',$quality); break;         case "image/png" : ImagePNG($imgB);  break;       }     }else{       $fp=fopen($file,"r");       $data = stripslashes(fread($fp,filesize($file)));       fclose($fp);       echo $data;     }

}

/* Delete a single file and get unique response */   function unlinkPreview ($file){     if(unlink($file)){       $ret["IsFile"] = TRUE;       $ret["Reason"] = "<b>File $file successfully deleted!</b><br>";       return $ret;     }else{       $ret["IsFile"] = FALSEE;       $ret["Reason"] = "<b>WARNING: Error while deleting file $file!</b><br>";       return $ret;     }   }

/* Simple image scaling directly from a file. png causes some colour output errors if using scaling,     but jpg works fine. thanks to php.net documentation ;) */   function imageScale ($filename, $maxbreite, $thumbhoehe){     $file = @fopen($filename, "r");     $data = stripslashes(@fread($file, @filesize($filename)));     @fclose($file);

$imgA = @imagecreatefromstring($data);     $breite1 = @imagesx($imgA);     $hoehe1 = @imagesy($imgA);

// enable this if compiled with bc_math     //bcscale(2);     $verhaeltnis = $hoehe1 / $breite1;     $zwischenbreite = @round($thumbhoehe / $verhaeltnis);

if ($zwischenbreite > $maxbreite){       $hoehe2 = @round($maxbreite * $verhaeltnis);       $breite2 = $maxbreite;     }else{       $hoehe2 = $thumbhoehe;       $breite2 = $zwischenbreite;     }

$imgB = @imagecreate($breite2,$hoehe2);     @imagecopyresized($imgB, $imgA, 0,0, 0,0, $breite2,$hoehe2, $breite1,$hoehe1);

return $imgB;   }

/* Simple workaround for buggy GetImageSize(). My PHP Version is 4.2.1,     so maybe in the future the bug will be fixed ...*/   function testIfJpeg ($file){     $fp = @fopen($file,"r");     $testbyte = stripslashes(@fread($fp, 2));     @fclose($fp);

if(ereg("ffd8", bin2hex($testbyte)))       return TRUE;     else       return FALSE;   }

/*  Test the supported mimetypes based on GetImageSize().       This function really looks for the file to be compatible to the gdlib*/   function testMimeType ($file){     $image_infos = GetImageSize($file);     $type = $image_infos[2];     switch($type){       case "2": return "image/jpeg"; break;       case "3": return "image/png"; break;       /* due to a bug in GetImageSize() the 2nd array       for JPG stays empty, so we have to do a       workaround ... */       default: if($this->testIfJpeg($file))           return "image/jpeg";           else             return "application/octet-stream";     }   } } ?>