• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Bild upload und resize

Calypto

Neues Mitglied
Hallo leute!

folgendes:

ich habe ein bild und möchte das uploaden (das bild hat zb. eine ausgangsgröße von 2545x4589 px).

jetzt möchte ich dass das bild beim upload verkleinert wird sodass es in 150x200px passt, aber das bild selbst weder breiter noch länger wird. das es die form nicht verliert. also das kein querformat plötzlich hochformat wird.

wie in facebook zb. ich lade ein bild ins fotoalbum und es passt sich dort an der rest ist schwarz, sodass es angepasst wird, oder in einer singlebörse.

ich weiss nicht wie ich es anders erklären soll. vielleicht so als würde man das bild auszoomen bis es so klein is das es da reinpasst.
 
Werbung:
Wenn der Verkleinerungsfaktor k lautet, dann gilt:

PHP:
$new_width = k * $old_width;
$new_height = k * $old_height;

Nun musst du darüber nachdenken, ob die Höhe oder die Breite weiter verkleinert werden soll. Damit ist k = max($old_width/$max_width, $old_height/$max_height).
 
also den php code könnte ich jetzt in meine programmierung implementieren und es würde funktionieren ;)?

jungs ich brauch einen code und keine hilfestellungen ;)
 
Werbung:
Dann frag in der Jobbörse nach, hier gibts nur Hilfestellung und keine feritgen Codes. Nebenbei bemerkt ist soetwas ein großes Sicherheitsrisiko, wer weiß was dir da alles an Code eingeschleust wird.
 
Wenn der Verkleinerungsfaktor k lautet, dann gilt:

PHP:
$new_width = k * $old_width;
$new_height = k * $old_height;
Nun musst du darüber nachdenken, ob die Höhe oder die Breite weiter verkleinert werden soll. Damit ist k = max($old_width/$max_width, $old_height/$max_height).

Mich würde interessieren wie das Funktionieren soll.


Also, nehmen wir an:

max_width: 150px;
max_height: 200px;

Ein Bild wird hochgeladen mit folgenden Größen:
width: 3500px;
height: 700px;


Du meinst:
PHP:
$k = max($old_width/$max_width, $old_height/$max_height);


Das heißt:
1.Param = old_width/max_width -> 3500 / 150 = 23,333.
2.Param = old_height/max_height -> 700 / 200 = 3,5



Bei max wird der größte Parameter zurückgeliefert, daher:

PHP:
$k = 23.333;


Neue Width und Height Werte:
PHP:
$new_width = $k * $old_width; //ergibt: 78166,55
$new_height = $k * $old_height; //ergibt: 15633,1

Das Ergebnis kann nicht stimmen? Oder hab ich was falsch verstanden?

Grüße
Nico
 
Stimmt, da ist mir ein Fehler unterlaufen. So sollte es stimmen:

PHP:
$k = min($max_width/$old_width, $max_height/$old_height);
 
Werbung:
PHP:
<?php
// --- get width and height of uploaded image
$sizes = getimagesize("bild.png");
$imageWidth = $sizes["0"];
$imageHeight = $sizes["1"];

// --- max größen
$maxWidth = 150;
$maxHeight = 200;

// if height or width is to big, set new width and height
if ($imageWidth > $maxWidth || $imageHeight > $maxHeight)
{
    $kfactor = max($maxWidth / $imageWidth, $maxHeight / $imageHeight);
    
    $newWidth = $kfactor * $imageWidth;
    $newHeight = $kfactor * $imageHeight;    
}
?>

Ausgangsbreite eines Bildes:
500
Ausgangshöhe eines Bildes: 200

150 / 500 = 0,3
200 / 200 = 1

1 ist der größere Parameter, daher werden imageWidth und imageHeight mit 1 multipliziert, womit sich nichts an den Ausgangswerten ändert.

Das kann also noch immer nicht stimmen, oder?
 
Werbung:
So in etwa koennte man das auch loesen wuerde ich sagen

PHP:
             $max_width = 150;
             $max_height = 200;


              //bildbreite groesser als maximale breite
              if($src_width > $max_width) {
                    $convert = $max_width/$src_width;
                    $dest_width = $max_width;
                    $dest_height = ceil($src_height*$convert);
                                
                    if($dest_height > $max_height) {   //Bild weiter verkleinern, falls Hoehe $max_height uebersteigt
                                    $convert = $max_height/$dest_height;
                                    $dest_height=$max_height;
                                    $dest_width = (float)ceil($dest_width*$convert);
                    }
              } else {
                    //maximale breite wird nicht ueberschritten, aber die hoehe
                    if($src_height > $max_height) {
                      $convert = (float)$max_height/$src_height;
                      $dest_height=$max_height;
                      $dest_width= (float) ceil($src_width*$convert);
                    } else {
                        //breite und hoehe passen bereits
                        $dest_width = $src_width;
                        $dest_height = $src_height;
                    }
              }
wie du die Bildbreite und Hoehe bekommst ist klar oder?
 
Zuletzt bearbeitet:
@Commodore

Habe es 3-4 mal mit verschiedensten Zahlen überprüft und es funktioniert prima. Hast mir sehr weitergeholfen - vielen Dank.


Mit move_uploaded_file bring ich Bilder auf n Server, allerdings sollten gleich die neuen Größen für die Bilder festgelegt werden.

Welche Funktionen sind da geeignet? Wenns geht, ohne GD Bibliothek.

Grüße,
Nico
 
Ohne irgendeine Form von Imagelibrary wird das wohl kaum funktionieren. Das Verkleinern eines Bildes ist keineswegs eine triviale Aufgabe, die man einfach so über ein paar Filemanipulationen machen kann.

- Man braucht zunächst einen Algorithmus um aus den Bilddaten die tatsächlichen Werte der Pixel zu errechnen [z.B. PNG oder JPG nutzen verschiedene Kompressionsalgorithmen].
- Man braucht noch einen Algorithmus, um die Pixel ordentlich zu interpolieren. Es kann z.B. passieren, dass 8 Pixel auf 5 Pixel gestaucht werden müssen - hier muss man den Interpolationsalgorithmus clever genug wählen, um das Bild erkennbar zu lassen.
- Der erste Schritt muss umgekehrt angewendet werden.


Alleine für den ersten bzw. dritten Schritt müsstest du für jedes akzeptierte Format eine eigene Funktionen erstellen, sowas ist alles andere als trivial. Um eine Grafiklibrary wirst du wohl kaum drumherumkommen.
 
Werbung:
Gut, welche Bibliothek ist da em einfachsten zu bedienen? Gibt es Bibliotheken, die anhand des Grafikformates bereits die richtige Funktion wählen? Untersützt sollte .jpg/.jpeg, .png und .gif werden.

Grüße
Nico
 
Auf php.net is das in der Spate "GD und Image Funktionen". Kann es sein, dass für diese Funktion keine Bibliothek vorhaden sein muss? Weil GD wird nirgendwo erwähnt. Allerdings wird da unten weiter ein Problem bei der Verwendung von imagecopyresampled angeführt. So wie ich das verstanden habe, brauchen manche Grafikformate mehr Farben und diese Funktion unterstützt lediglich 255. Ich brauche wie gesagt .jpg, .png und .gif - bei welchen hätte ich denn da Probleme?

Da ich bilder nicht vergrößern, sondern lediglich verkleinern möchte und auch nur dann, wenn die Maximal Werte überschritten wurden, dürften die Bilder dann ja nicht so zum Pixeln anfangen wie dieses hier: http://www.php.net/manual/de/images/21009b70229598c6a80eef8b45bf282b-imagecopyresampled_2.jpg, oder doch?
 
Werbung:
GD ist eine Grafikbibliothek, sie ist einfach nur meist bereits installiert. Wer mal auf einem Debian-basierten System einen PHP-Server aufgesetzt hat, wird bemerken, dass es ein eigenes Paket php5-gd gibt.


Zu dem Problem mit den Farben: Wenn ich das richtig verstehe, kann das Problem umgangen werden, indem imagecreattruecolor() verwendet wird. So wie auch in dem Beispielcode:
PHP:
// […]
$image_p = imagecreatetruecolor($width, $height);
$image = imagecreatefromjpeg($filename);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
// […]

Das mit den Pixeln ist so eine Sache, wie gut das verkleinerte Bild aussieht hängt vom Verkleinerungsfaktor, von der ursprünglichen Größe, vom Bild selbst etc. ab.
 
PHP:
<?php

/**
 * Helper class for resizing images (based on GD)
 *
 * @author Marc Ermshaus <http://www.ermshaus.org/>
 * @version 2011-Apr-20
 * @license GNU General Public License Version 3 (or later)
 *          <http://www.gnu.org/licenses/gpl.html>
 */
class ImageResizer
{
    /**
     *
     * @var int
     */
    protected $maxWidth = 300;

    /**
     *
     * @var int
     */
    protected $maxHeight = 300;

    /**
     *
     * @var bool
     */
    protected $enlargeSmallImages = false;

    /**
     *
     * @param resource $image
     * @return resource GD image resource
     */
    protected function resize($image)
    {
        $maxWidth  = $this->maxWidth;
        $maxHeight = $this->maxHeight;

        $width  = imagesx($image);
        $height = imagesy($image);

        // If both dimensions of the image are below specified maxima and no
        // enlargement of small images is wanted, there is nothing to do
        if ($this->enlargeSmallImages === false
                && $width < $maxWidth && $height < $maxHeight
        ) {
            return $image;
        }

        $ratioX = $width / $maxWidth;
        $ratioY = $height / $maxHeight;

        $newWidth  = 0;
        $newHeight = 0;

        if ($ratioX > $ratioY) {
            $newWidth = $maxWidth;
            $newHeight = (int) round(imagesy($image) / $ratioX);
            if ($newHeight > $maxHeight) {
                $newHeight = $maxHeight;
            }
        } else {
            $newHeight = $maxHeight;
            $newWidth  = (int) round(imagesx($image) / $ratioY);
            if ($newWidth > $maxWidth) {
                $newWidth = $maxWidth;
            }
        }

        $newImage = imagecreatetruecolor($newWidth, $newHeight);

        imagecopyresampled($newImage, $image, 0, 0, 0, 0,
                $newWidth, $newHeight, $width, $height);

        imagedestroy($image);

        return $newImage;
    }

    /**
     *
     * @param string $path
     * @return resource GD image resource
     */
    public function resizeFromPath($path)
    {
        return $this->resize(imagecreatefromstring(file_get_contents($path)));
    }

    /**
     *
     * @param resource $image
     * @return resource GD image resource
     */
    public function resizeFromGd($image)
    {
        return $this->resize($image);
    }

    /**
     *
     * @param string $imageData
     * @return resource GD image resource
     */
    public function resizeFromString($imageData)
    {
        return $this->resize(imagecreatefromstring($imageData));
    }

    /**
     *
     * @return int
     */
    public function getMaxWidth()
    {
        return $this->maxWidth;
    }

    /**
     *
     * @param int $maxWidth
     */
    public function setMaxWidth($maxWidth)
    {        
        if (!is_int($maxWidth) || $maxWidth < 1) {
            throw new InvalidArgumentException(
                    'maxWidth must be an (int) greater than 0');
        }

        $this->maxWidth = $maxWidth;
    }

    /**
     *
     * @return int
     */
    public function getMaxHeight()
    {
        return $this->maxHeight;
    }

    /**
     *
     * @param int $maxHeight
     */
    public function setMaxHeight($maxHeight)
    {
        if (!is_int($maxHeight) || $maxHeight < 1) {
            throw new InvalidArgumentException(
                    'maxHeight must be an (int) greater than 0');
        }

        $this->maxHeight = $maxHeight;
    }

    /**
     *
     * @return bool
     */
    public function getEnlargeSmallImages()
    {
        return $this->enlargeSmallImages;
    }

    /**
     *
     * @param bool $enlargeSmallImages
     */
    public function setEnlargeSmallImages($enlargeSmallImages)
    {
        if (!is_bool($enlargeSmallImages)) {
            throw new InvalidArgumentException(
                    'enlargeSmallImages must be a (bool)');
        }

        $this->enlargeSmallImages = $enlargeSmallImages;
    }
}

Beispiel:

PHP:
$ir = new ImageResizer();
$ir->setMaxWidth(200);
$ir->setMaxHeight(200);
$ir->setEnlargeSmallImages(false);

$resizedImage = $ir->resizeFromPath('./demo.jpg');

header('content-type: image/jpeg');
imagejpeg($resizedImage);
 
Hallo Zusammen,

Ich suche ungern fertige scripte sondern 'bastle' die existenten PHP-Funktionen lieber zusammen bis das Script tut was es soll.

Zumal das veröffentlichen von Scripten ja eher Rar und verschrien ist.
@Mermshaus: Aber deine classe werd ich wohl so übernehmen wollen :D
Besonders da es Typ unabhängig ist.

Dennoch würde ich gern mal mein gebasteltes begutachten lassen da ich nen echt komischen Fehler hab.

Es werden zwar alle Grafiken resized, jedoch wird nicht jede Grafik auf den Server geladen. Unabhängig ob JPG, GIF, PNG. Mir scheint das kleine Grafiken (w:50px etc) Probleme bereiten. Ein 100%iges Fehlerschema kann ich jedoch nicht erkennen.

Nun mal zum (kleinen) Code:

PHP:
$timestamp = time();
  $datum = date("Y-m-d",$timestamp);
  $uhrzeit = date("H-i-s",$timestamp);
 
  if(isset($_FILES['userlogo']['tmp_name']))
  {
   $dateityp = GetImageSize($_FILES['userlogo']['tmp_name']);
   if($dateityp[2]==1 OR $dateityp[2]==2 OR $dateityp[2]==3)
   {
    if($dateityp[2] == 1) $type="gif";
    if($dateityp[2] == 2) $type="jpg";
    if($dateityp[2] == 3) $type="png";
 
    $file        = $_FILES['userlogo']['tmp_name']; 
    switch ($dateityp[2])
    {
     case 1:
      $type="gif";
      $src_img     = imagecreatefromgif($file); 
      break;
     case 2:
      $type="jpg";
      $src_img     = imagecreatefromjpeg($file); 
      break;
     case 3:
      $type="png";
      $src_img     = imagecreatefrompng($file); 
      break;
    }
 
    $imgwidth  = $dateityp[0];
    $imgheight = $dateityp[1];
    //Namen kreieren
    $userlogonameoriginal=$_FILES['userlogo']['name'];
    $_FILES['userlogo']['name']=$_SESSION['userid']."_".$datum."_".$uhrzeit.".".$type;
    $imgname = $_FILES['userlogo']['name'];
    $target = $imgname;
    $imgsize = $_FILES['userlogo']['size'];
    if ( $imgwidth > 333 )
    { 
     $max_width   = "333"; 
     $picsize     = getimagesize($file); 
     $src_width   = $picsize[0]; 
     $src_height  = $picsize[1]; 
     if($src_width > $max_width) 
     { 
      $convert = ($max_width/$src_width); 
      $dest_width = $max_width; 
      $dest_height = ceil($src_height*$convert); 
     } 
     else 
     { 
      $dest_width = $src_width; 
      $dest_height = $src_height; 
     } 
 
     $dst_img = imagecreatetruecolor($dest_width,$dest_height); 
     imagecopyresampled($dst_img, $src_img, 0, 0, 0, 0, $dest_width, $dest_height, $src_width, $src_height); 
     switch ($dateityp[2])
     {
      case 1:
       $quality     = "9"; 
       imagegif($dst_img, "pics/upload/$target"); //, $quality);
       break;
      case 2:
       $quality     = "90"; 
       imagejpeg($dst_img, "pics/upload/$target", $quality);
       break;
      case 3:
       $quality     = "9"; 
       imagepng($dst_img, "pics/upload/$target", $quality); 
       break;
     }
 
     $imgwidth  = $dest_width;
     $imgheight = $dest_height;
    }
 
    //if($imgsize <  512400)
    //{
     //if(move_uploaded_file($imgname, "pics/upload/$target"))
     //{
      move_uploaded_file($imgname, "pics/upload/$target");
     //}
      echo "<br><br><br><p align=\"center\">Das Bild wurde Erfolgreich hochgeladen<br><br><img src=\"pics/upload/".$imgname."\"></p><br><br>";
 
     /*else
     {
      echo "<br><br><br><p align=\"center\">Das Bild konnte nicht Erfolgreich hochgeladen werden.<br><br></p><br><br>";
      die();
     }*/
     //BILD in DB eintragen


Was auch komisch ist,
PHP:
if(move_uploaded_file($imgname, "pics/upload/$target"))
hat mir immer FALSE geliefert, das Bild jedoch auf den FDP als auch 'localhost' geladen.
 
Werbung:
Jetzt hab ich gemerkt das ich jedes Bild ja theoretisch 2x hochlade oO

PHP:
imagegif($dst_img, "pics/upload/$target"); //Wenn nicht in $variable wird das GIF unter "pics/upload/$target" gespeichert

und

PHP:
if(move_uploaded_file($imgname, "pics/upload/$target"))

Jetzt habe ich letzteres auskommentiert jedoch hat sich nichts an meiner Situation geändert. mal wird die file gespeichert, mal wird sie nicht.
 
Ich finde es faszinierend das jedesmal wenn ich in diesem Forum Poste ich meine Fehler finde :D
PHP:
  $timestamp = time();
  $datum = date("Y-m-d",$timestamp);
  $uhrzeit = date("H-i-s",$timestamp);
  $file = $_FILES['userlogo']['tmp_name']; 
  if(isset($file))
  {
   $picsize = getimagesize($file); 
   if($picsize[2]==1 OR $picsize[2]==2 OR $picsize[2]==3)
   {
    $upl=0; 
    
    switch ($picsize[2])
    {
     case 1:
      $type="gif";
      $src_img = imagecreatefromgif($file); 
      break;
     case 2:
      $type="jpg";
      $src_img = imagecreatefromjpeg($file); 
      break;
     case 3:
      $type="png";
      $src_img = imagecreatefrompng($file); 
      break;
    }
    //Namen kreieren
    $userlogonameoriginal=$_FILES['userlogo']['name'];          //Für DB benötigt
    $_FILES['userlogo']['name']=$_SESSION['userid']."_".$datum."_".$uhrzeit.".".$type;
    $imgname = $_FILES['userlogo']['name'];
    $imgsize = $_FILES['userlogo']['size'];
    $max_width   = "333"; 
    $src_width   = $picsize[0]; 
    $src_height  = $picsize[1]; 
    if($src_width > $max_width) 
    { 
     $convert = ($max_width/$src_width); 
     $dest_width = $max_width; 
     $dest_height = ceil($src_height*$convert); 
    } 
    else 
    { 
     $dest_width = $src_width; 
     $dest_height = $src_height; 
    } 
    $dst_img = imagecreatetruecolor($dest_width,$dest_height); 
    imagecopyresampled($dst_img, $src_img, 0, 0, 0, 0, $dest_width, $dest_height, $src_width, $src_height); 
    switch ($picsize[2])
    {
     case 1:
      $quality     = "9"; 
      if(imagegif($dst_img, "pics/upload/$imgname")) //, $quality);
      {
       echo "<br><br><br><p align=\"center\">Das Bild wurde Erfolgreich hochgeladen<br><br><img src=\"pics/upload/".$imgname."\"></p><br><br>";
       $upl=1;
      }
      else $upl=0;
      break;
     case 2:
      $quality     = "90"; 
      if(imagejpeg($dst_img, "pics/upload/$imgname", $quality))
      {
       echo "<br><br><br><p align=\"center\">Das Bild wurde Erfolgreich hochgeladen<br><br><img src=\"pics/upload/".$imgname."\"></p><br><br>";
       $upl=1;
      }
      else $upl=0;
     case 3:
      $quality     = "9"; 
      if(imagepng($dst_img, "pics/upload/$imgname", $quality))
      {
       echo "<br><br><br><p align=\"center\">Das Bild wurde Erfolgreich hochgeladen<br><br><img src=\"pics/upload/".$imgname."\"></p><br><br>";
       $upl=1;
      }
      else $upl=0;

Ein Problem habe ich jedoch: Bilder mit Alphachannel wird der Alphachannel schwarz. Kann ich das irgendwie auf weiß ändern? Google ist da grade nicht mein Freund.
 
Zurück
Oben