Bildercache Qualitätseinstellung functions.api.images.php

Gesperrt
ebengingsnoch
Beiträge: 5
Registriert: Mi 8. Jan 2014, 18:07
Kontaktdaten:

Bildercache Qualitätseinstellung functions.api.images.php

Beitrag von ebengingsnoch » Do 9. Jan 2014, 10:12

Liebes Forum,

ersteinmal möchte ich ein kompliment für die gute Inforamtionsdichte aussprechen. Ich habe viel gesucht und viel gefunden. Aber bei einer Sache bastel ich jetzt schon ewig rum, leider halfen mir sämtliche passende Forenbeiträge nicht weiter.
Ich benutze Contenido 4.6.15 auf einem Apache Server. Alles läuft wunderbar. Ein Problem ist nur das Cachen von Bildern. Die Qualität ist teilweise so mies, dass es peinlich ist, dass die Bilder (Banner, Teaser, etc.) online sind.

Daher meine Frage: Ist die Datei "functions.api.images.php" für die Komprimierung verantwortlich? Egal ob die Bilder in den richtigen Pixelmaßen hochgeladen werden, immer wird gecacht und die Bildqualität vermurkst. Sogar wenn die Dateigröße kleiner als nach dem Cachen ist und die Qualität blendent ist, wird das Bild gecacht und alles sieht wieder matschig aus.

Weiter unten habe ich mal die Datei "functions.api.images.php" gepostet. In dieser Datei habe ich versucht die Einstellungen zu verändern, leider immer ohne Erfolg.
Was muß ich einstellen? Welche Dateien sind dafür verantwortlich? Muß ich zusätzlichen Code eingeben?

Ich freu mich auf Euer Feedback.
Beste Grüße
Chris

Code: Alles auswählen

<?php

/*****************************************
* File      :   $RCSfile: functions.api.images.php,v $
* Project   :   Contenido
* Descr     :   Contenido Image API functions
*
* Author    :   Timo A. Hummel
*               
* Created   :   08.08.2003
* Modified  :   $Date: 2006/10/05 23:50:41 $
*
* © four for business AG, www.4fb.de
*
* $Id: functions.api.images.php,v 1.41 2006/10/05 23:50:41 bjoern.behrens Exp $
******************************************/

/* Info:
 * This file contains Contenido Image API functions.
 *
 * If you are planning to add a function, please make sure that:
 * 1.) The function is in the correct place
 * 2.) The function is documented
 * 3.) The function makes sense and is generically usable
 *
 */
 
 
/**
 * capiImgScaleGetMD5CacheFile: Returns the MD5 Filename used
 * for caching.
 *
 * @return string Path to the resulting image
 */
function capiImgScaleGetMD5CacheFile ($sImg, $iMaxX, $iMaxY, $bCrop, $bExpand)
{
	if (!file_exists($sImg))
	{
		return false;	
	}
	
	$iFilesize = filesize($sImg);
	
	if (function_exists("md5_file"))
	{
		$sMD5 = md5(implode("", array(
					$sImg,
					md5_file($sImg),
					$iFilesize,
					$iMaxX,
					$iMaxY,
					$bCrop,
					$bExpand)));
	} else {
		$sMD5 = md5(implode("", array(
					$sImg,
					$iFilesize,
					$iMaxX,
					$iMaxY,
					$bCrop,
					$bExpand)));		
	}
	
	return $sMD5;
}

/**
 * capiImgScaleLQ: Scales (or crops) an image.
 * If scaling, the aspect ratio is maintained.
 *
 * Returns the path to the scaled temporary image.
 *
 * Note that this function does some very poor caching;
 * it calculates an md5 hash out of the image plus the
 * maximum X and Y sizes, and uses that as the file name.
 * If the file is older than 10 minutes, regenerate it.
 *
 * @param $img string The path to the image (relative to the frontend)
 * @param $maxX int The maximum size in x-direction
 * @param $maxY int The maximum size in y-direction
 * @param $crop boolean If true, the image is cropped and not scaled.
 * @param $expand boolean If true, the image is expanded (e.g. really scaled).
 *                        If false, the image will only be made smaller. 
 * @param $cacheTime int The number of minutes to cache the image  
 *
 * @return string Path to the resulting image
 */
function capiImgScaleLQ ($img, $maxX, $maxY, $crop = false, $expand = false, $cacheTime = 10)
{
	global $cfgClient, $lang, $client;

	$filename = $img;
	$defaultCacheTime = $cacheTime;
	
	$filetype = substr($filename, strlen($filename) -4,4);
	$filesize = filesize($img);
	$md5 = capiImgScaleGetMD5CacheFile($img, $maxX, $maxY, $crop, $expand);
	
	/* Create the target file names for web and server */
	$cfileName = $md5.".jpg";
	$cacheFile = $cfgClient[$client]["path"]["frontend"]."cache/".$cfileName;
	$webFile = $cfgClient[$client]["path"]["htmlpath"]."cache/".$cfileName;
	
	/* Check if the file exists. If it does, check if the file is valid. */
	if (file_exists($cacheFile))
	{
		if (!function_exists("md5_file"))
		{
			if ((filemtime($cacheFile) + (60 * $defaultCacheTime)) < time())
			{
				/* Cache time expired, unlink the file */
				unlink($cacheFile);	
			} else {
				/* Return the web file name */
				return $webFile;
			}
		} else {
			return $webFile;	
		}
	}
	
	/* Get out which file we have */
	switch (strtolower($filetype))
	{
		case ".gif": $function = "imagecreatefromgif"; break;
		case ".png": $function = "imagecreatefrompng"; break;
		case ".jpg": $function = "imagecreatefromjpeg"; break;
		case "jpeg": $function = "imagecreatefromjpeg"; break;
		default: return false;
	}
	
	if (function_exists($function))
	{
		$imageHandle = @$function($filename);
	}
	
	/* If we can't open the image, return false */
	if (!$imageHandle)
	{
		return false;
	}


	$x = imagesx($imageHandle);
	$y = imagesy($imageHandle);
	
	/* Calculate the aspect ratio */	
	$aspectXY = $x / $y;
	$aspectYX = $y / $x;
	
	if (($maxX / $x) < ($maxY / $y))
	{
		$targetY = $y * ($maxX / $x);
		$targetX = round($maxX);
		
		// force wished height
		if ($targetY < $maxY)
		{
			$targetY = ceil($targetY);
		} else
		{
			$targetY = floor($targetY);
		}
		
	} else {
		$targetX = $x * ($maxY / $y);
		$targetY = round($maxY);
		
		// force wished width
		if ($targetX < $maxX)
		{
			$targetX = ceil($targetX);
		} else
		{
			$targetX = floor($targetX);
		}
	}

	if ($expand == false && (($targetX > $x) || ($targetY > $y)))
	{
		$targetX = $x;
		$targetY = $y;	
	}

	$targetX = ($targetX != 0) ? $targetX : 1;
   	$targetY = ($targetY != 0) ? $targetY : 1;
   	
	/* Create the target image with the target size, resize it afterwards. */
   if ($crop)
   {
      /* Create the target image with the max size, crop it afterwards. */
      $targetImage = imagecreate($maxX, $maxY);
      imagecopy($targetImage, $imageHandle, 0, 0, 0, 0, $maxX, $maxY);
   } else {
      /* Create the target image with the target size, resize it afterwards. */
      $targetImage = imagecreate($targetX, $targetY);
      imagecopyresized($targetImage, $imageHandle, 0, 0, 0, 0, $targetX, $targetY, $x, $y);
   }
	
	/* Output the file */
	imagejpeg($targetImage, $cacheFile,80);
	
	return ($webFile);
}

/**
 * capiImgScaleHQ: Scales (or crops) an image in high quality.
 * If scaling, the aspect ratio is maintained.
 *
 * Note: GDLib 2.x is required!
 *
 * Returns the path to the scaled temporary image.
 *
 * Note that this function does some very poor caching;
 * it calculates an md5 hash out of the image plus the
 * maximum X and Y sizes, and uses that as the file name.
 * If the file is older than the specified cache time, regenerate it.
 *
 * @param $img string The path to the image (relative to the frontend)
 * @param $maxX int The maximum size in x-direction
 * @param $maxY int The maximum size in y-direction
 * @param $crop boolean If true, the image is cropped and not scaled.
 * @param $cacheTime int The number of minutes to cache the image  
 *
 * @return string Path to the resulting image
 */
function capiImgScaleHQ ($img, $maxX, $maxY, $crop = false, $expand = false, $cacheTime = 10)
{
	global $cfgClient, $lang, $client;

	$filename = $img;
	$defaultCacheTime = $cacheTime;
	
	$filetype = substr($filename, strlen($filename) -4,4);
	$filesize = filesize($img);
	$md5 = capiImgScaleGetMD5CacheFile($img, $maxX, $maxY, $crop, $expand);
	
	/* Create the target file names for web and server */
	$cfileName = $md5.".jpg";
	$cacheFile = $cfgClient[$client]["path"]["frontend"]."cache/".$cfileName;
	$webFile = $cfgClient[$client]["path"]["htmlpath"]."cache/".$cfileName;
	
	/* Check if the file exists. If it does, check if the file is valid. */
	if (file_exists($cacheFile))
	{
		if (!function_exists("md5_file"))
		{
			if ((filemtime($cacheFile) + (60 * $defaultCacheTime)) < time())
			{
				/* Cache time expired, unlink the file */
				unlink($cacheFile);	
			} else {
				/* Return the web file name */
				return $webFile;
			}
		} else {
			return $webFile;	
		}
	}
	
	/* Get out which file we have */
	switch (strtolower($filetype))
	{
		case ".gif": $function = "imagecreatefromgif"; break;
		case ".png": $function = "imagecreatefrompng"; break;
		case ".jpg": $function = "imagecreatefromjpeg"; break;
		case "jpeg": $function = "imagecreatefromjpeg"; break;
		default: return false;
	}
	
	if (function_exists($function))
	{
		$imageHandle = @$function($filename); 
	}
	
	/* If we can't open the image, return false */
	if (!$imageHandle)
	{
		return false;
	}


	$x = imagesx($imageHandle);
	$y = imagesy($imageHandle);

	/* Calculate the aspect ratio */	
	$aspectXY = $x / $y;
	$aspectYX = $y / $x;
	
	if (($maxX / $x) < ($maxY / $y))
	{
		$targetY = $y * ($maxX / $x);
		$targetX = round($maxX);
		
		// force wished height
		if ($targetY < $maxY)
		{
			$targetY = ceil($targetY);
		} else
		{
			$targetY = floor($targetY);
		}
		
	} else {
		$targetX = $x * ($maxY / $y);
		$targetY = round($maxY);
		
		// force wished width
		if ($targetX < $maxX)
		{
			$targetX = ceil($targetX);
		} else
		{
			$targetX = floor($targetX);
		}
	}
	
	if ($expand == false && (($targetX > $x) || ($targetY > $y)))
	{
		$targetX = $x;
		$targetY = $y;	
	}	

	$targetX = ($targetX != 0) ? $targetX : 1;
   	$targetY = ($targetY != 0) ? $targetY : 1;
   	
	/* Create the target image with the target size, resize it afterwards. */
if ($crop)
   {
      /* Create the target image with the max size, crop it afterwards. */
      $targetImage = imagecreatetruecolor($maxX, $maxY);
      imagecopy($targetImage, $imageHandle, 0, 0, 0, 0, $maxX, $maxY);
   } else {
      /* Create the target image with the target size, resize it afterwards. */
      $targetImage = imagecreatetruecolor($targetX, $targetY);
      imagecopyresampled($targetImage, $imageHandle, 0, 0, 0, 0, $targetX, $targetY, $x, $y);
   }
	
	/* Output the file */
	imagejpeg($targetImage, $cacheFile,80);
	
	return ($webFile);
}

/**
 * capiImgScaleImageMagick: Scales (or crops) an image using ImageMagick.
 * If scaling, the aspect ratio is maintained.
 *
 * Note: ImageMagick is required!
 *
 * Returns the path to the scaled temporary image.
 *
 * Note that this function does some very poor caching;
 * it calculates an md5 hash out of the image plus the
 * maximum X and Y sizes, and uses that as the file name.
 * If the file is older than the specified cache time, regenerate it.
 *
 * @param $img string The path to the image (relative to the frontend)
 * @param $maxX int The maximum size in x-direction
 * @param $maxY int The maximum size in y-direction
 * @param $crop boolean If true, the image is cropped and not scaled.
 * @param $cacheTime int The number of minutes to cache the image  
 *
 * @return string Path to the resulting image
 */
function capiImgScaleImageMagick ($img, $maxX, $maxY, $crop = false, $expand = false, $cacheTime = 10)
{
	global $cfgClient, $lang, $client;

	$filename = $img;
	$defaultCacheTime = $cacheTime;
	
	$filetype = substr($filename, strlen($filename) -4,4);
	$filesize = filesize($img);
	$md5 = capiImgScaleGetMD5CacheFile($img, $maxX, $maxY, $crop, $expand);
	
	/* Create the target file names for web and server */
	$cfileName = $md5.".jpg";
	$cacheFile = $cfgClient[$client]["path"]["frontend"]."cache/".$cfileName;
	$webFile = $cfgClient[$client]["path"]["htmlpath"]."cache/".$cfileName;
	
	/* Check if the file exists. If it does, check if the file is valid. */
	if (file_exists($cacheFile))
	{
		if (!function_exists("md5_file"))
		{
			if ((filemtime($cacheFile) + (60 * $defaultCacheTime)) < time())
			{
				/* Cache time expired, unlink the file */
				unlink($cacheFile);	
			} else {
				/* Return the web file name */
				return $webFile;
			}
		} else {
			return $webFile;	
		}
	}

	list($x, $y) = getimagesize($filename);	

	/* Calculate the aspect ratio */	
	$aspectXY = $x / $y;
	$aspectYX = $y / $x;
	
	if (($maxX / $x) < ($maxY / $y))
	{
		$targetY = $y * ($maxX / $x);
		$targetX = round($maxX);
		
		// force wished height
		if ($targetY < $maxY)
		{
			$targetY = ceil($targetY);
		} else
		{
			$targetY = floor($targetY);
		}
		
	} else {
		$targetX = $x * ($maxY / $y);
		$targetY = round($maxY);
		
		// force wished width
		if ($targetX < $maxX)
		{
			$targetX = ceil($targetX);
		} else
		{
			$targetX = floor($targetX);
		}
	}
	
	if ($expand == false && (($targetX > $x) || ($targetY > $y)))
	{
		$targetX = $x;
		$targetY = $y;	
	}
	
	$targetX = ($targetX != 0) ? $targetX : 1;
   	$targetY = ($targetY != 0) ? $targetY : 1;	

	// if is animated gif resize first frame
	if ($filetype == ".gif")
    {
		if (isAnimGif($filename))
        {
			$filename .= "[0]";
        }
    }

	/* Try to execute convert */
	$output = array();
	$retVal = 0;
	if ($crop)
	{
		exec ("convert -gravity center -quality 75 -crop {$maxX}x{$maxY}+1+1 \"$filename\" $cacheFile", $output, $retVal);
	} else {
		exec ("convert -quality 75 -geometry {$targetX}x{$targetY} \"$filename\" $cacheFile", $output, $retVal );
	}

	if (!file_exists($cacheFile))
	{
		return false;
	}
	
	return ($webFile);
}

/**
 * check if gif is animated
 *
 * @param string file path
 *
 * @return boolean true (gif is animated)/ false (single frame gif)
 */
function isAnimGif($sFile)
{
	$output = array();
	$retval = 0;
	
	exec('identify ' . $sFile, $output, $retval);
	
	if (count($output) == 1)
	{
		return false;
	}
	
	return true;	
}

/**
 * capiImgScale: Scales (or crops) an image.
 * If scaling, the aspect ratio is maintained.
 *
 * This function chooses the best method to scale, depending on
 * the system environment and/or the parameters.
 *
 * Returns the path to the scaled temporary image.
 *
 * Note that this function does some very poor caching;
 * it calculates an md5 hash out of the image plus the
 * maximum X and Y sizes, and uses that as the file name.
 * If the file is older than 10 minutes, regenerate it.
 *
 * @param $img string The path to the image (relative to the frontend)
 * @param $maxX int The maximum size in x-direction
 * @param $maxY int The maximum size in y-direction
 * @param $crop boolean If true, the image is cropped and not scaled.
 * @param $expand boolean If true, the image is expanded (e.g. really scaled).
 *                        If false, the image will only be made smaller. 
 * @param $cacheTime int The number of minutes to cache the image  
 * @param $wantHQ boolean If true, try to force high quality mode
 *
 * @return string Path to the resulting image
 */
function capiImgScale ($img, $maxX, $maxY, $crop = false, $expand = false, $cacheTime = 10, $wantHQ = true)
{
	global $client, $db, $cfg, $cfgClient;
	
	$deleteAfter = false;

    
	$sRelativeImg = str_replace($cfgClient[$client]["upl"]["path"], "", $img);
	if (is_dbfs($sRelativeImg))
	{
		// This check should be faster than a file existance check
		$dbfs = new DBFSCollection;
    			
		$file = basename($sRelativeImg);
    			
		$dbfs->writeToFile($sRelativeImg, $cfgClient[$client]["path"]["frontend"]."cache/".$file);
    			
		$img = $cfgClient[$client]["path"]["frontend"]."cache/".$file;
    	$deleteAfter = true;
	} else if (!file_exists($img))
	{
		/* Try with upload string */
		if (file_exists($cfgClient[$client]["upl"]["path"].$img) && !is_dir($cfgClient[$client]["upl"]["path"].$img))
		{
			$img = $cfgClient[$client]["upl"]["path"].$img;
		} else
		{
    		/* No, it's neither in the upload directory nor in the dbfs. return. */
    		return false;
    	}
	}
	
	$filename = $img;
	$filetype = substr($filename, strlen($filename) -4,4);
	
	$mxdAvImgEditingPosibility= checkImageEditingPosibility();
	switch ($mxdAvImgEditingPosibility)
	{
		case '1': // gd1
			$method = 'gd1';
			if (!function_exists('imagecreatefromgif') && $filetype == '.gif') 
			{
				$method = 'failure';
			}
			break;
		case '2': //gd2
			$method = 'gd2';
			if (!function_exists('imagecreatefromgif') && $filetype == '.gif') 
			{
				$method = 'failure';
			}
			break;
		case 'im': //imagemagick
			$method = 'im';
			break;
		case '0':
			$method = 'failure';
			break;
		default:
			$method = 'failure';
			break;
	}
	
	switch ($method)
	{
		case 'gd1':
			$return = capiImgScaleLQ($img, $maxX, $maxY, $crop, $expand, $cacheTime);	
			break;
		
		case 'gd2':
			$return = capiImgScaleHQ($img, $maxX, $maxY, $crop, $expand, $cacheTime);
			break;
		
		case 'im':
			$return = capiImgScaleImageMagick($img, $maxX, $maxY, $crop, $expand, $cacheTime);
			break;
		
		case 'failure':
        	$return = str_replace($cfgClient[$client]["path"]["frontend"], $cfgClient[$client]["path"]["htmlpath"], $img);
			break;
	}
	
	if ($deleteAfter == true)
	{
		unlink($img);
	}
	
	return $return;
					
}

/**
* check possible image editing functionality
*
* return mixed information about installed image editing extensions/tools
*/
function checkImageEditingPosibility() {

	if (isImageMagickAvailable())
	{
		return 'im';
	} else
	{
		if (extension_loaded('gd'))
		{
			if (function_exists('gd_info'))
			{
				$arrGDInformations = gd_info();
			
				if (preg_match('#([0-9\.])+#', $arrGDInformations['GD Version'], $strGDVersion))
				{
					if ($strGDVersion[0] >= '2')
					{
						return '2';
					}
					return '1';
				}
				return '1';
			}
			return '1';
		}
		return '0';
	}
}

?>

Faar
Beiträge: 1497
Registriert: Sa 8. Sep 2007, 16:23
Wohnort: Brandenburg
Kontaktdaten:

Re: Bildercache Qualitätseinstellung functions.api.images.ph

Beitrag von Faar » Do 9. Jan 2014, 14:34

Es könnte sein, dass die Funktion capiimageirgendwasLQ benützt wird, also für Low Quality.
Dort gibt es irgendwo diesen Code, wonach dann das Bild ausgespuckt wird:

Code: Alles auswählen

/* Output the file */
   imagejpeg($targetImage, $cacheFile,80);
Diese 80 bedeutet quasi die Bildqualität. Es sollte für das Web 85 betragen.
Aber falls es noch ein alter Server mit alter GD-Library ist und alten JPEG-Algorythmus, dann konvertiert der eben schlecht.
Früher waren sogar jpeg 95 noch mit jpeg-Artefakten und dem berühmten Saum um Ränder herum.
Das ist heute nur noch bei Komprimierungen um die 75 so.

Die Module die die Bilder verarbeiten, sollten also diese Funktion nehmen:

Code: Alles auswählen

capiImgScaleHQ: Scales (or crops) an image in high quality.
Note: GDLib 2.x is required!
Kann aber sein, dass auf dem Server gar kein GDLib 2.x liegt oder der Pfad dazu nicht gefunden wird.
Dann gibt es immer schlechte Bilder.

Mehr zu PHP und Bilder findet man auch hier: http://www.php.net/manual/de/ref.image.php

Übrigens würde ich das System wenigstens auf 4.6.24 updaten, das wurde damals gegen Hackerangriffe abgedichtet.
Fliegt der Bauer übers Dach, ist der Wind weißgott nicht schwach.

ebengingsnoch
Beiträge: 5
Registriert: Mi 8. Jan 2014, 18:07
Kontaktdaten:

Re: Bildercache Qualitätseinstellung functions.api.images.ph

Beitrag von ebengingsnoch » Do 9. Jan 2014, 15:02

Hallo Faar,

vielen Dank für Deine Antwort und Deinen Upgrade-Tipp. Ein Upgrade trau ich mir noch nicht zu, aber ich schau mir das noch mal intensiv an.
Die Module die die Bilder verarbeiten, sollten also diese Funktion nehmen:
Code: Alles auswählen
capiImgScaleHQ: Scales (or crops) an image in high quality.
Note: GDLib 2.x is required!
Ich habe alle php Dateien (auch innerhalb des Dokuments) nach "capiImgScale" durchsucht und konnte nur die Datei im Anhang finden. Daher nehme ich an, dass nur die Datei "functions.api.images.php" Bilder verarbeitet.
Wie sage ich der Datei "functions.api.images.php", dass sie nur noch das Modul "capiImgScaleHQ:" benutzt?

Anbei habe ich die Datei "functions.api.images.php" -> welche Zeilen müssen angepasst werden und wie?
Ich habe alle möglichen Zeilen durchprobiert und den Quali-Wert auf 100 gedreht, aber die gecachten bilder waren (in kb gemessen) immer gleich groß? Die Ansicht ergo immer gleich schlecht.

Meinst Du, wenn ich laut dieser Seite:
http://www.conrepo.org/apidoc/contenido ... c8d0e5a226

Alle Funktionen auf >95 dreh, dann klappt es?

Oder: "php.info" auf meinem Server angucken und wenn die GDLib sehr alt ist, diese auf die neueste Version updaten?

Viele Grüße
Chris
Dateianhänge
functions.api.images.php.zip
(3.3 KiB) 105-mal heruntergeladen

Faar
Beiträge: 1497
Registriert: Sa 8. Sep 2007, 16:23
Wohnort: Brandenburg
Kontaktdaten:

Re: Bildercache Qualitätseinstellung functions.api.images.ph

Beitrag von Faar » Do 9. Jan 2014, 23:16

Hi,
ein Upgrade wäre das noch nicht sondern nur ein Update innerhalb der 4.6 Schiene.

Aber zum Image:
Die Datei functions.api.images.php ist lediglich eine Sammlung an Funktionen, die irgendwas mit Bildern zu tun haben. Ich habe mir die mal kurz angeschaut.
Darin befinden sich im Wesentlichen die Funktionen:
  • capiImgScaleGetMD5CacheFile()
    capiImgScaleLQ()
    capiImgScaleHQ()
    capiImgScaleImageMagick()
    capiImgScale()
    checkImageEditingPosibility()
Eigentlich ist die capiImgScale() diejenige, die vermutlich meistens aufgerufen wird, weil sie teils die anderen Funktionen darin selbst aufruft.
Diese Funktion kommt zwar mit einem Schalter für HQ Bilder daher ($wantHQ = true),

Code: Alles auswählen

capiImgScale ($img, $maxX, $maxY, $crop = false, $expand = false, $cacheTime = 10, $wantHQ = true)
doch in der Folge finde ich nirgends mehr eine Weiterverarbeitung von $wantHQ.
Stattdessen wird nach GD 1 oder GD 2 oder IM (ImageMagic) geforscht und entsprechend das Bild an eine der anderen Funktionen geschickt.
Wenn nur GD Version 1 auf dem Server installiert ist, wird die Funktion capiImgScaleLQ() benützt.
Wenn aber GD Version 2 auf dem Server installiert ist, wird die Funktion capiImgScaleHQ() benützt.
Wenn noch IM auf dem Server installiert ist, wird die Funktion capiImgScaleImageMagick() benützt.
Bei Gif-Bildern wird nichts gemacht.

Kurzum, die Bildqualität wird hier nur in der Art berücksichtigt, welche Version der GD-Library auf dem Server ist oder sogar ImageMagic.
Und im schlechtesten Fall trifft es die Funktion capiImgScaleLQ().
Dort steht dann irgendwo am Ende diese GD-Funktion: imagejpeg($targetImage, $cacheFile,80);
Und damit wird die Bildqualität auf 80 eingestellt, was für saubere Bilder definitiv zu wenig ist.

Das alleine beeinträchtigt die Bildqualität noch nicht so schlimm wie es sich bei dir anhört.
Also muss man noch wissen, wie man Bilder verarbeiten darf:
Für einen schlechtes Bildprogramm (wie das alte GD) ist es ein leichtes, ein Bild von 1000x1000 auf 500x500 herunter zu rechnen, das lässt sich leicht interpolieren.
Aber von 863x554 auf 640x480 wird das schlimm und je näher das Originalbild der Größe des Ausgangsbildes ist, desto schlimmer.
Ein gutes Bild mit schlechten Programm nur um 1 Pixel von 501 auf 500 zu machen, kann das ganze Bild total versauen!

Daher habe ich meine Bilder alle immer exakt in der Größe hochgeladen, wie sie am Ende in der Webseite erscheinen sollen.
Nur hält das diese Funktionen nicht davon ab, das Bild trotzdem zu überarbeiten und damit zu versaubeuteln.
Darum hatte ich zu Zeiten von Contenido 4.6. noch hier und da das jeweilige Programm so umgeschrieben, dass es bei 1 zu 1 Formaten das Bild in Ruhe lässt (also nicht 1:1 skaliert) und nicht durch die Funktion jagt.
Damit erzielte ich sehr gute Bildqualitäten (so wie sie mit teurem Grafikprogramm auf dem PC erzeugt wurden) auch in der Webseite.

Da Du nicht weißt, welches Programm dir die Bilder durch die Funktionen jagt (kann ein Galeriemodul sein), hast du wenig Einfluss darauf, aber immerhin das noch.
JPEG-Bilder werden umso schlechter, desto öfter man sie durch ein schlechtes Grafikprogramm jagt.
Nimmst du z.B. ein 75'er Originalbild und machst mit GD 1 ein 80'er Bild, wird das niemals besser, denn der Schaden ist bereits da (durch die 75) und wird durch die erneute Komprimierung noch vergrößert.
Also nimm dann grundsätzlich 95'er bis 99'er Bilder (die neueren Kameras machen bei Fine-Qualität meistens 98 bis 99), dann wird aus einen sehr guten Bild ein schlechtes gemacht, denn andernfalls würde aus einem halbschlechten ein sauschlechtes Bild gemacht werden. Dazu muss man wissen, dass ein Photoshop 75'er Bild immer noch gut ist, während ich schon 95'er Bilder von Kameras mit deutlichem JPEG-Saum gesehen habe. Das liegt einfach am besseren Programm.

Dein vermutliches Problem:
Kombiniere einfach mal, dass der Server nur GD 1 bietet oder das veraltete Programm functions.api.images.php es nicht besser erkennen kann und daher auf GD 1 springt.
Dann noch eine ungerade Skalierung.
Und dazu eine geringe Veränderung der Originalgröße.
Und noch zu stark komprimierte Originalbilder.
Dann hast du den Supergau.

Lösung:
Update (sicher wurde die Funktion mal überarbeitet seither, denn 2003 ist lange her)
Im Programm functions.api.images.php jeweils die 80 in 90 umschreiben (wird beim Update natürlich wieder überschrieben).
Schauen, was der Server bietet, ob er wirklich nur GD 1 hat (bei alten Servern durchaus möglich) und notfalls den Server updaten.
Bilder direkt mit FTP hochladen und direkt in die Seite einbinden, ohne Cache und Zwischenprogramm, falls möglich.
Skalierfaktoren beachten, also nicht 843 Pixel in 800 Pixel umwandeln wollen (mach das lieber mit einen PC-Grafikprogramm).
Nur gute Originalbilder mit JPEG 95 (hohe Qualität) benützen.

VG,
Frank
Fliegt der Bauer übers Dach, ist der Wind weißgott nicht schwach.

ebengingsnoch
Beiträge: 5
Registriert: Mi 8. Jan 2014, 18:07
Kontaktdaten:

Re: Bildercache Qualitätseinstellung functions.api.images.ph

Beitrag von ebengingsnoch » Mo 13. Jan 2014, 09:29

Hallo Frank,

hast Du Contenido entwickelt? : )
Vielen Dank für Deine Mühe und ausführliche Antwort.

Die Komprimierungsproblematik habe ich bereits versucht zu umgehen, trotz unkromprimerten Originalbilder und Ausgabe in exakten/geforderten Pixelmaßen des Templates => das Ergebnis ist immer furchtbar.
Ich werde jetzt die GDLib prüfen und hoffe, dass dann bald ein akzeptables Ergebnis vorliegt, wenn nicht muss ich wohl (zusätzlich) ein Update auf 4.9.x machen.

Hoffentlich hält das Forum einen Guide bereit in puncto update von 4.6.15 auf 4.9?!?!

Beste Grüße
Chris

Oldperl
Beiträge: 4055
Registriert: Do 30. Jun 2005, 22:56
Wohnort: Eltmann, Unterfranken, Bayern
Kontaktdaten:

Re: Bildercache Qualitätseinstellung functions.api.images.ph

Beitrag von Oldperl » Mo 13. Jan 2014, 13:17

Hallo Chris,
ebengingsnoch hat geschrieben:Hoffentlich hält das Forum einen Guide bereit in puncto update von 4.6.15 auf 4.9?!?!
Du solltest über ein schrittweises Upgrade nachdenken, vor Allem das sich bei jedem Versionssprung diverse Sachen im Core geändert haben.
Eine Anleitung bis zur 4.8er findest du auf meiner Seite - http://www.ortwinpinke.de/2009/05/18/co ... mandanten/
Diese kann man auch analog zum Upgrade auf die 4.9 nutzen.
Je nach Umfang der Seite ist es aber auch ein Neuaufsetzen und ein händisches Übertragen der Daten zu empfehlen, zumal viele Module nicht ad-hoc in der 4.9er laufen werden, da es dort wirklich gravierende Änderungen im Core, API und Strukturen von Contenido gibt. Hier muss man gegebenenfalls den Aufwand für beide Wege kurz überschlagen.

Gruß aus Franken

Ortwin
CONTENIDO 4.9 Entwickler-Handbuch - Publikation auf medium.com zu meinem angedachten Entwickler-Buch zu CONTENIDO 4.9
ConLite 2.0, alternatives und stabiles Update von Contenido 4.8.x
phpBO Search Advanced - das neue Suchwort-Plugin für CONTENIDO 4.9
Mein Entwickler-Blog

Gesperrt