Bild zuschneiden

dsNDesign

Erfahrenes Mitglied
Hei,
ich möchte ein Bild auf eine bestimmte Größe verkleinern (180x140px).
Dazu verkleiner ich es zunächst auf eine Größe, in welcher die Proportionen behalten werden. Also kommt nach dem ersten Schritt z.B. ein Bild der Größe 195x140px raus.

Bei diesem Bild möchte ich nun noch den Rand abschneiden, dass es am Ende 180x140px groß ist. Jedoch will das nicht so ganz funktionieren.

Mein Code:
PHP:
list($img_width, $img_height) = @getimagesize($file_path);
        if (!$img_width || !$img_height) {
            return false;
        }
        $scale = max(
            $options['max_width'] / $img_width,
            $options['max_height'] / $img_height
        );
        if ($scale >= 1) {
            if ($file_path !== $new_file_path) {
                return copy($file_path, $new_file_path);
            }
            return true;
        }
        $new_width = $img_width * $scale;
        $new_height = $img_height * $scale;
		$dstX = 0.5 * ($options['max_width'] - $new_width);
		$dstY = 0.5 * ($options['max_height'] - $new_height);
        $new_img = @imagecreatetruecolor($new_width, $new_height);
        switch (strtolower(substr(strrchr($file_name, '.'), 1))) {
            case 'jpg':
            case 'jpeg':
                $src_img = @imagecreatefromjpeg($file_path);
                $write_image = 'imagejpeg';
                $image_quality = isset($options['jpeg_quality']) ?
                    $options['jpeg_quality'] : 75;
                break;
            case 'gif':
                @imagecolortransparent($new_img, @imagecolorallocate($new_img, 0, 0, 0));
                $src_img = @imagecreatefromgif($file_path);
                $write_image = 'imagegif';
                $image_quality = null;
                break;
            case 'png':
                @imagecolortransparent($new_img, @imagecolorallocate($new_img, 0, 0, 0));
                @imagealphablending($new_img, false);
                @imagesavealpha($new_img, true);
                $src_img = @imagecreatefrompng($file_path);
                $write_image = 'imagepng';
                $image_quality = isset($options['png_quality']) ?
                    $options['png_quality'] : 9;
                break;
            default:
                $src_img = null;
        }
		@imagecopyresampled(
            $new_img,
            $src_img,
            0, 0, 0, 0,
            $new_width,
            $new_height,
            $img_width,
            $img_height
        );
		$final_img = @imagecreatetruecolor($options['max_width'], $options['max_height']);
        $success = $new_img && @imagecopyresampled(
			$final_img,
			$new_img,
			0, 0,
			$dstX,
			$dstY,
			$options['max_width'],
			$options['max_height'],
			$new_width,
			$new_height
		) && $write_image($final_img, $new_file_path, $image_quality);
		
        @imagedestroy($src_img);
        @imagedestroy($new_img);
		@imagedestroy($final_img);
        return $success;

Hier noch das Ergebnis des Skripts:
verkleinert.jpg

Und das Original:
Winter1.jpg

Wie man sieht, wird das Bild zwar auf die 180x140px verkleinert, jedoch verzerrt. Außerdem ist ein schwarzer Balken am Rand.
Woran liegt das?

Gruß
 
Keiner einer ne Idee?

Im Grunde geht es ja nur darum, wie man ein Bild zuschneidet bzw. abschneidet. Den Schritt mit dem Verkleinern machts das Skript ja richtig. Also die Proportionen dabei stimmen.
 
ok, Danke. Habe jetzt mein Glück in "imagecopy" gefunden.

Sieht jetzt so aus:
PHP:
$success = $new_img && @imagecopy(
			$final_img,
			$new_img,
			0, 0,
			$dstX,
			$dstY,
			$options['max_width'],
			$options['max_height']
		) && $write_image($final_img, $new_file_path, $image_quality);

wobei $dstX und $dstY die Startposition im Ausgangsbild ist (Damit der Ausschnitt mittig vom Original genommen wird).
 
wenn du es noch nicht hinbekommen hast nutze ich immer diese funktion um bilder:
a) von der Auflösung her umzurechnen ... (und)
b) die Bilder im zweifelsfall mittig beschneiden

Ist die Auflösung der Quelldatei = der Zielwerte (Auflösung) so wird die Datei nur kopiert ...

Die Funktion ist kommentiert und die parameter sollten klar sein ...
PHP:
function createJpegFromFile($width, $height, $src, $target, $proportional, $quality, $override = false, $mayCrop = false, $pullUp = false, $forceWidth = false, $forceHeight = false, $maxWidth = 56, $forceCreate = false){
		$crop_x = 0; $crop_y = 0;
		$target_width = $width;
		$target_height = $height;
		@list($width_ori, $height_ori) = getimagesize($src);
		
		if (($width_ori != $width && $height_ori != $height) || $forceCreate) {
			if ($width_ori != NULL || $width_ori != 0)
			{
				# Zieldatei erzeugen
				touch($target);
				
				# Wird das Bild proportional zu den Originalmaßen angelegt?
				if ($proportional)
				{
					# Sind die Quellmaße des Bildes größer als die Zielmaße, oder wird das Bild gezwungen?
					if ($width_ori > $width || $height_ori > $height || $override)
					{
						# Bild ist Querformat => Höhe anpassen
						if (($width_ori > $height_ori && !$forceWidth)){
							$height = ceil(($width / $width_ori) * $height_ori);
						}
						
						# Bild ist Hochformat => Breite anpassen
						if ($width_ori < $height_ori || $forceHeight){
							$width = ceil(($height / $height_ori) * $width_ori);
							
							// Maximale Breite trotz allem beachten
							if ($forceHeight && $width > $maxWidth) {
								$width = $maxWidth;
							}
						}
						
						# Kleinere Dimension wird an die Zielbreite hochgezogen
						if ($pullUp){
							# Ist die Breite kleiner als die Mindestzielbreite?
							if($width < $target_width){
								$width = $target_width;
								$height = ceil(($width / $width_ori) * $height_ori);
							}
							# Ist die Höhe kleiner als die Mindestzielhöhe?
							if($height < $target_height){
								$height = $target_height;
								$width = ceil(($height / $height_ori) * $width_ori);
							}
						}
						
						# Bild wird automatisch mittig beschnitten
						if ($mayCrop){
							# $width = originalBildBreite
							# cropWidth = Breite des gewählten Ausschnitts im originalBild
							# crop_x = Differenz der obigen / 2
							
							# Seiten hochziehen
							$cropWidth = $width_ori;
							$cropHeight = $cropWidth * ($target_height/$target_width);
							
							# Überschreitet eine der Seiten das Format?
							if ($cropHeight > $height_ori){
								$cropHeight = $height_ori;
								$cropWidth = $cropHeight * ($target_width/$target_height);
							}
							
							$crop_x = ($width_ori - $cropWidth)/2;
							$crop_y = ($height_ori - $cropHeight)/2;
							
							if ($crop_x < 0) $crop_x = 0;
							if ($crop_y < 0) $crop_y = 0;
						}
					}
					else
					{
						# Quellbild an Ziel kopieren, da zu klein
						copy($src, $target);
						return;
					}
				}
		
				$oldimg = imagecreatefromjpeg($src);
				
				if ($mayCrop){
					$newimg = imagecreatetruecolor($target_width, $target_height);
					imagecopyresampled($newimg, $oldimg, 0, 0, $crop_x, $crop_y, $target_width, $target_height, $cropWidth, $cropHeight);
				}else{
					$newimg = imagecreatetruecolor($width, $height);
					imagecopyresampled($newimg, $oldimg, 0, 0, 0, 0, $width, $height, $width_ori, $height_ori);
				}
				
				imagejpeg($newimg, $target, $quality);
					
				imagedestroy($oldimg);
				imagedestroy($newimg);
			}
		} else {
			copy($src, $target);
		}		
	}
 
Zuletzt bearbeitet:
Zurück