Zmień rozmiar obrazu w PHP

96

Chcę napisać jakiś kod PHP, który automatycznie zmienia rozmiar dowolnego obrazu przesłanego przez formularz do 147x147px, ale nie mam pojęcia, jak się do tego zabrać (jestem względnie nowicjuszem w PHP).

Jak dotąd udało mi się przesłać obrazy, rozpoznano typy plików i wyczyszczono nazwy, ale chciałbym dodać funkcję zmiany rozmiaru do kodu. Na przykład mam obraz testowy, który ma 2,3 MB i wymiary 1331x1331 i chciałbym, aby kod zmniejszył jego rozmiar, co, jak sądzę, dramatycznie skompresuje również rozmiar pliku obrazu.

Do tej pory mam następujące informacje:

if ($_FILES) {
                //Put file properties into variables
                $file_name = $_FILES['profile-image']['name'];
                $file_size = $_FILES['profile-image']['size'];
                $file_tmp_name = $_FILES['profile-image']['tmp_name'];

                //Determine filetype
                switch ($_FILES['profile-image']['type']) {
                    case 'image/jpeg': $ext = "jpg"; break;
                    case 'image/png': $ext = "png"; break;
                    default: $ext = ''; break;
                }

                if ($ext) {
                    //Check filesize
                    if ($file_size < 500000) {
                        //Process file - clean up filename and move to safe location
                        $n = "$file_name";
                        $n = ereg_replace("[^A-Za-z0-9.]", "", $n);
                        $n = strtolower($n);
                        $n = "avatars/$n";
                        move_uploaded_file($file_tmp_name, $n);
                    } else {
                        $bad_message = "Please ensure your chosen file is less than 5MB.";
                    }
                } else {
                    $bad_message = "Please ensure your image is of filetype .jpg or.png.";
                }
            }
$query = "INSERT INTO users (image) VALUES ('$n')";
mysql_query($query) or die("Insert failed. " . mysql_error() . "<br />" . $query);
Alex Ryans
źródło
Czy wypróbowałeś próbki takie jak te stackoverflow.com/questions/10029838/image-resize-with-php ?
Coenie Richards
bez zmiany upload_max_filesizew php.ini, po pierwsze, czy można wgrać plik o rozmiarze większym niż upload_max_filesize?. Czy jest szansa na zmianę rozmiaru obrazu o więcej niż upload_max_filesize? bez zmiany upload_max_filesizewphp.ini
RCH

Odpowiedzi:

143

Aby pracować z obrazami, musisz używać funkcji PHP ImageMagick lub GD .

Na przykład w przypadku GD jest to tak proste, jak ...

function resize_image($file, $w, $h, $crop=FALSE) {
    list($width, $height) = getimagesize($file);
    $r = $width / $height;
    if ($crop) {
        if ($width > $height) {
            $width = ceil($width-($width*abs($r-$w/$h)));
        } else {
            $height = ceil($height-($height*abs($r-$w/$h)));
        }
        $newwidth = $w;
        $newheight = $h;
    } else {
        if ($w/$h > $r) {
            $newwidth = $h*$r;
            $newheight = $h;
        } else {
            $newheight = $w/$r;
            $newwidth = $w;
        }
    }
    $src = imagecreatefromjpeg($file);
    $dst = imagecreatetruecolor($newwidth, $newheight);
    imagecopyresampled($dst, $src, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);

    return $dst;
}

I możesz nazwać tę funkcję, w ten sposób ...

$img = resize_image(‘/path/to/some/image.jpg’, 200, 200);

Z własnego doświadczenia wynika, że ​​ponowne próbkowanie obrazu GD znacznie zmniejsza rozmiar pliku, zwłaszcza podczas ponownego próbkowania surowych obrazów z aparatu cyfrowego.

Ian Atkin
źródło
1
Czy przechowujesz obrazy jako BLOBs? Zalecałbym przechowywanie obrazów w systemie plików i wstawianie odniesień do bazy danych. Polecam również przeczytanie pełnej dokumentacji GD (lub ImageMagick), aby zobaczyć, jakie inne opcje są dostępne.
Ian Atkin
20
Uwaga, to rozwiązanie działa tylko w przypadku plików JPEG. Możesz zamienić imagecreatefromjpeg na dowolne z następujących: imagecreatefromgd, imagecreatefromgif, imagecreatefrompng, imagecreatefromstring, imagecreatefromwbmp, imagecreatefromxbm, imagecreate fromxpm, aby poradzić sobie z różnymi typami obrazów.
Chris Hanson
2
@GordonFreeman Dzięki za świetny fragment kodu, ale jest tam jedna usterka, dodaj abs(), podobnie jak ceil($width-($width*abs($r-$w/$h)))i to samo do części dotyczącej wysokości. Jest to potrzebne w niektórych przypadkach.
Arman P.
1
Zmiana domyślnej wartości przycięcia na true i zmiana rozmiaru obrazu na http://wallpapercave.com/wp/wc1701171.jpg400x128 (baner) spowodowała utworzenie czarnego obrazu; Nie mogę jednak zrozumieć, dlaczego to robi.
FoxInFlame
5
Aby zapisać obraz o zmienionym rozmiarze w systemie plików, dodaj imagejpeg($dst, $file);po imagecopyresampled($dst,...wierszu. Zmień, $filejeśli nie chcesz nadpisywać oryginału.
wkille
23

Ten zasób (zepsuty link) również jest wart rozważenia - bardzo uporządkowany kod, który używa GD. Jednak zmodyfikowałem ich końcowy fragment kodu, aby utworzyć tę funkcję, która spełnia wymagania PO ...

function store_uploaded_image($html_element_name, $new_img_width, $new_img_height) {
    
    $target_dir = "your-uploaded-images-folder/";
    $target_file = $target_dir . basename($_FILES[$html_element_name]["name"]);
    
    $image = new SimpleImage();
    $image->load($_FILES[$html_element_name]['tmp_name']);
    $image->resize($new_img_width, $new_img_height);
    $image->save($target_file);
    return $target_file; //return name of saved file in case you want to store it in you database or show confirmation message to user
    
}

Będziesz także musiał dołączyć ten plik PHP ...

<?php
 
/*
* File: SimpleImage.php
* Author: Simon Jarvis
* Copyright: 2006 Simon Jarvis
* Date: 08/11/06
* Link: http://www.white-hat-web-design.co.uk/blog/resizing-images-with-php/
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details:
* http://www.gnu.org/licenses/gpl.html
*
*/
 
class SimpleImage {
 
   var $image;
   var $image_type;
 
   function load($filename) {
 
      $image_info = getimagesize($filename);
      $this->image_type = $image_info[2];
      if( $this->image_type == IMAGETYPE_JPEG ) {
 
         $this->image = imagecreatefromjpeg($filename);
      } elseif( $this->image_type == IMAGETYPE_GIF ) {
 
         $this->image = imagecreatefromgif($filename);
      } elseif( $this->image_type == IMAGETYPE_PNG ) {
 
         $this->image = imagecreatefrompng($filename);
      }
   }
   function save($filename, $image_type=IMAGETYPE_JPEG, $compression=75, $permissions=null) {
 
      if( $image_type == IMAGETYPE_JPEG ) {
         imagejpeg($this->image,$filename,$compression);
      } elseif( $image_type == IMAGETYPE_GIF ) {
 
         imagegif($this->image,$filename);
      } elseif( $image_type == IMAGETYPE_PNG ) {
 
         imagepng($this->image,$filename);
      }
      if( $permissions != null) {
 
         chmod($filename,$permissions);
      }
   }
   function output($image_type=IMAGETYPE_JPEG) {
 
      if( $image_type == IMAGETYPE_JPEG ) {
         imagejpeg($this->image);
      } elseif( $image_type == IMAGETYPE_GIF ) {
 
         imagegif($this->image);
      } elseif( $image_type == IMAGETYPE_PNG ) {
 
         imagepng($this->image);
      }
   }
   function getWidth() {
 
      return imagesx($this->image);
   }
   function getHeight() {
 
      return imagesy($this->image);
   }
   function resizeToHeight($height) {
 
      $ratio = $height / $this->getHeight();
      $width = $this->getWidth() * $ratio;
      $this->resize($width,$height);
   }
 
   function resizeToWidth($width) {
      $ratio = $width / $this->getWidth();
      $height = $this->getheight() * $ratio;
      $this->resize($width,$height);
   }
 
   function scale($scale) {
      $width = $this->getWidth() * $scale/100;
      $height = $this->getheight() * $scale/100;
      $this->resize($width,$height);
   }
 
   function resize($width,$height) {
      $new_image = imagecreatetruecolor($width, $height);
      imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
      $this->image = $new_image;
   }      
 
}
?>
zakaz geoinżynierii
źródło
1
Twoja próbka jest najlepsza. działa bezpośrednio w ramach Zend bez tworzenia komedii, dramatów, wyrywania włosów. kciuki w górę
Myślę, że cały kod, którego potrzebujesz, powinien znajdować się w mojej odpowiedzi, ale może to również pomóc: gist.github.com/arrowmedia/7863973 .
zakaz geoinżynierii
20

Proste użycie funkcji PHP ( skala obrazów ):

Składnia:

imagescale ( $image , $new_width , $new_height )

Przykład:

Krok: 1 Przeczytaj plik

$image_name =  'path_of_Image/Name_of_Image.jpg|png';      

Krok: 2: Załaduj plik obrazu

 $image = imagecreatefromjpeg($image_name); // For JPEG
//or
 $image = imagecreatefrompng($image_name);   // For PNG

Krok: 3: Nasz ratownik wchodzi w „_” | Skaluj obraz

   $imgResized = imagescale($image , 500, 400); // width=500 and height = 400
//  $imgResized is our final product

Uwaga: skala obrazów będzie działać dla (PHP 5> = 5.5.0, PHP 7)

Źródło: Kliknij, aby przeczytać więcej

M Abdullah
źródło
Najlepsze rozwiązanie dla PHP 5.6.3>
Pattycake Jr
12

Jeśli nie zależy Ci na współczynniku proporcji (tzn. Chcesz wymusić na obrazie określony wymiar), oto uproszczona odpowiedź

// for jpg 
function resize_imagejpg($file, $w, $h) {
   list($width, $height) = getimagesize($file);
   $src = imagecreatefromjpeg($file);
   $dst = imagecreatetruecolor($w, $h);
   imagecopyresampled($dst, $src, 0, 0, 0, 0, $w, $h, $width, $height);
   return $dst;
}

 // for png
function resize_imagepng($file, $w, $h) {
   list($width, $height) = getimagesize($file);
   $src = imagecreatefrompng($file);
   $dst = imagecreatetruecolor($w, $h);
   imagecopyresampled($dst, $src, 0, 0, 0, 0, $w, $h, $width, $height);
   return $dst;
}

// for gif
function resize_imagegif($file, $w, $h) {
   list($width, $height) = getimagesize($file);
   $src = imagecreatefromgif($file);
   $dst = imagecreatetruecolor($w, $h);
   imagecopyresampled($dst, $src, 0, 0, 0, 0, $w, $h, $width, $height);
   return $dst;
}

Teraz zajmijmy się częścią przesyłania. Najpierw prześlij plik do wybranego katalogu. Następnie wywołana jedną z powyższych funkcji w oparciu o typ pliku (jpg, png lub gif) i podaj bezwzględną ścieżkę do przesłanego pliku, jak poniżej:

 // jpg  change the dimension 750, 450 to your desired values
 $img = resize_imagejpg('path/image.jpg', 750, 450);

Wartość zwracana $imgjest obiektem zasobu. Możemy zapisać w nowej lokalizacji lub zastąpić oryginał jak poniżej:

 // again for jpg
 imagejpeg($img, 'path/newimage.jpg');

Mam nadzieję, że to komuś pomoże. Sprawdź te linki, aby uzyskać więcej informacji na temat zmiany rozmiaru Imagick :: resizeImage i imagejpeg ()

Tunde Michael
źródło
bez zmiany upload_max_filesizew php.ini, po pierwsze nie można przesłać pliku o rozmiarze większym niż upload_max_filesize. Czy jest jakaś szansa, aby zmienić rozmiar obrazu o rozmiarze ponad upload_max_filesizebez zmiany upload_max_filesizewphp.ini
RCH
6

Mam nadzieję, że to zadziała dla Ciebie.

/**
         * Image re-size
         * @param int $width
         * @param int $height
         */
        function ImageResize($width, $height, $img_name)
        {
                /* Get original file size */
                list($w, $h) = getimagesize($_FILES['logo_image']['tmp_name']);


                /*$ratio = $w / $h;
                $size = $width;

                $width = $height = min($size, max($w, $h));

                if ($ratio < 1) {
                    $width = $height * $ratio;
                } else {
                    $height = $width / $ratio;
                }*/

                /* Calculate new image size */
                $ratio = max($width/$w, $height/$h);
                $h = ceil($height / $ratio);
                $x = ($w - $width / $ratio) / 2;
                $w = ceil($width / $ratio);
                /* set new file name */
                $path = $img_name;


                /* Save image */
                if($_FILES['logo_image']['type']=='image/jpeg')
                {
                    /* Get binary data from image */
                    $imgString = file_get_contents($_FILES['logo_image']['tmp_name']);
                    /* create image from string */
                    $image = imagecreatefromstring($imgString);
                    $tmp = imagecreatetruecolor($width, $height);
                    imagecopyresampled($tmp, $image, 0, 0, $x, 0, $width, $height, $w, $h);
                    imagejpeg($tmp, $path, 100);
                }
                else if($_FILES['logo_image']['type']=='image/png')
                {
                    $image = imagecreatefrompng($_FILES['logo_image']['tmp_name']);
                    $tmp = imagecreatetruecolor($width,$height);
                    imagealphablending($tmp, false);
                    imagesavealpha($tmp, true);
                    imagecopyresampled($tmp, $image,0,0,$x,0,$width,$height,$w, $h);
                    imagepng($tmp, $path, 0);
                }
                else if($_FILES['logo_image']['type']=='image/gif')
                {
                    $image = imagecreatefromgif($_FILES['logo_image']['tmp_name']);

                    $tmp = imagecreatetruecolor($width,$height);
                    $transparent = imagecolorallocatealpha($tmp, 0, 0, 0, 127);
                    imagefill($tmp, 0, 0, $transparent);
                    imagealphablending($tmp, true); 

                    imagecopyresampled($tmp, $image,0,0,0,0,$width,$height,$w, $h);
                    imagegif($tmp, $path);
                }
                else
                {
                    return false;
                }

                return true;
                imagedestroy($image);
                imagedestroy($tmp);
        }
Er.gaurav soni
źródło
6

Stworzyłem łatwą w użyciu bibliotekę do zmiany rozmiaru obrazu. Można go znaleźć tutaj na Github .

Przykład korzystania z biblioteki:

// Include PHP Image Magician library
require_once('php_image_magician.php');

// Open JPG image
$magicianObj = new imageLib('racecar.jpg');

// Resize to best fit then crop (check out the other options)
$magicianObj -> resizeImage(100, 200, 'crop');

// Save resized image as a PNG (or jpg, bmp, etc)
$magicianObj -> saveImage('racecar_small.png');

Inne funkcje, jeśli ich potrzebujesz, to:

  • Szybka i łatwa zmiana rozmiaru - Zmień rozmiar na poziomy, pionowy lub automatyczny
  • Łatwa uprawa
  • Dodaj tekst
  • Regulacja jakości
  • Znak wodny
  • Cienie i refleksy
  • Wsparcie przejrzystości
  • Przeczytaj metadane EXIF
  • Krawędzie, Zaokrąglone rogi, Obrót
  • Filtry i efekty
  • Wyostrzanie obrazu
  • Konwersja typu obrazu
  • Obsługa BMP
Jarrod
źródło
1
To uratowało mi dzień. Jest jednak mała uwaga, którą skierowałem do kogoś, kto szukał przez 3 dni, tak jak ja, i miał stracić nadzieję na znalezienie rozwiązania do zmiany rozmiaru. Jeśli w przyszłości zobaczysz niezdefiniowane powiadomienia o indeksie, po prostu zobacz ten link: github.com/Oberto/php-image-magician/pull/16/commits I zastosuj zmiany w plikach. Będzie działać w 100% bez żadnych problemów.
Hema_Elmasry
2
Hej, @Hema_Elmasry. FYI, właśnie włączyłem te zmiany do głównego :)
Jarrod
Ok, przepraszam, nie zauważyłem. Ale mam pytanie. Kiedy zmieniam rozmiar na mniejszą rozdzielczość bez zmiany jakości, jakość wyświetlanego obrazu jest znacznie niższa. Czy zdarzyło Ci się coś podobnego? Ponieważ nadal nie znalazłem rozwiązania.
Hema_Elmasry
6

( WAŻNE : w przypadku zmiany rozmiaru animacji (animowany webp lub gif) wynik będzie nieanimowany, ale zmieniony rozmiar obrazu z pierwszej klatki! (Oryginalna animacja pozostaje nienaruszona ...)

Stworzyłem to do mojego projektu php 7.2 (przykład imagebmp sure (PHP 7> = 7.2.0): php / manual / function.imagebmp ) o techfry.com/php-tutorial , z GD2 (więc nic z biblioteki innej firmy) i bardzo podobny do odpowiedzi Nico Bistolfi, ale działa z wszystkimi pięcioma podstawowymi typami MIME obrazu ( png, jpeg, webp, bmp i gif ), tworząc nowy plik o zmienionym rozmiarze , bez modyfikowania oryginalnego, a wszystkie rzeczy w jednej funkcji i gotowy do użycia (skopiuj i wklej do swojego projektu). (Możesz ustawić rozszerzenie nowego pliku za pomocą piątego parametru lub po prostu go zostawić, jeśli chcesz zachować oryginalny):

function createResizedImage(
    string $imagePath = '',
    string $newPath = '',
    int $newWidth = 0,
    int $newHeight = 0,
    string $outExt = 'DEFAULT'
) : ?string
{
    if (!$newPath or !file_exists ($imagePath)) {
        return null;
    }

    $types = [IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_GIF, IMAGETYPE_BMP, IMAGETYPE_WEBP];
    $type = exif_imagetype ($imagePath);

    if (!in_array ($type, $types)) {
        return null;
    }

    list ($width, $height) = getimagesize ($imagePath);

    $outBool = in_array ($outExt, ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp']);

    switch ($type) {
        case IMAGETYPE_JPEG:
            $image = imagecreatefromjpeg ($imagePath);
            if (!$outBool) $outExt = 'jpg';
            break;
        case IMAGETYPE_PNG:
            $image = imagecreatefrompng ($imagePath);
            if (!$outBool) $outExt = 'png';
            break;
        case IMAGETYPE_GIF:
            $image = imagecreatefromgif ($imagePath);
            if (!$outBool) $outExt = 'gif';
            break;
        case IMAGETYPE_BMP:
            $image = imagecreatefrombmp ($imagePath);
            if (!$outBool) $outExt = 'bmp';
            break;
        case IMAGETYPE_WEBP:
            $image = imagecreatefromwebp ($imagePath);
            if (!$outBool) $outExt = 'webp';
    }

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

    //TRANSPARENT BACKGROUND
    $color = imagecolorallocatealpha ($newImage, 0, 0, 0, 127); //fill transparent back
    imagefill ($newImage, 0, 0, $color);
    imagesavealpha ($newImage, true);

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

    // Rotate image on iOS
    if(function_exists('exif_read_data') && $exif = exif_read_data($imagePath, 'IFD0'))
    {
        if(isset($exif['Orientation']) && isset($exif['Make']) && !empty($exif['Orientation']) && preg_match('/(apple|ios|iphone)/i', $exif['Make'])) {
            switch($exif['Orientation']) {
                case 8:
                    if ($width > $height) $newImage = imagerotate($newImage,90,0);
                    break;
                case 3:
                    $newImage = imagerotate($newImage,180,0);
                    break;
                case 6:
                    $newImage = imagerotate($newImage,-90,0);
                    break;
            }
        }
    }

    switch (true) {
        case in_array ($outExt, ['jpg', 'jpeg']): $success = imagejpeg ($newImage, $newPath);
            break;
        case $outExt === 'png': $success = imagepng ($newImage, $newPath);
            break;
        case $outExt === 'gif': $success = imagegif ($newImage, $newPath);
            break;
        case  $outExt === 'bmp': $success = imagebmp ($newImage, $newPath);
            break;
        case  $outExt === 'webp': $success = imagewebp ($newImage, $newPath);
    }

    if (!$success) {
        return null;
    }

    return $newPath;
}
danigore
źródło
Jesteś wspaniały! To proste i czyste rozwiązanie. Miałem problem z modułem Imagick i rozwiązałem problemy z tą prostą klasą. Dzięki!
Ivijan Stefan Stipić
Świetnie, jeśli chcesz, mogę później dodać kolejną aktualizację, poprawię to trochę.
Ivijan Stefan Stipić
pewnie! Nadal nie mam czasu na zbudowanie części zmiany rozmiaru animacji ...
danigore
@danigore, jak zmienić rozmiar surowych obrazów ( .cr2, .dng, .nefi podobnych)? GD2 nie ma żadnego wsparcia i po wielu zmaganiach udało mi się skonfigurować ImageMagick. Ale kończy się niepowodzeniem z błędem przekroczenia limitu czasu połączenia podczas odczytu pliku. I nie ma też dziennika błędów ...
Krishna Chebrolu
1
@danigore Dodaję do twojej funkcji automatyczne obracanie obrazu, aby naprawić problemy Apple.
Ivijan Stefan Stipić
2

Oto rozszerzona wersja odpowiedzi, której udzielił @Ian Atkin. Okazało się, że działa bardzo dobrze. W przypadku większych zdjęć to znaczy :). Jeśli nie będziesz ostrożny, możesz powiększyć mniejsze obrazy. Zmiany: - Obsługuje pliki jpg, jpeg, png, gif, bmp - Zachowuje przezroczystość dla plików .png i .gif - Podwójnie sprawdza, czy rozmiar oryginału nie jest już mniejszy - Zastępuje obraz podany bezpośrednio (tego potrzebowałem)

Więc oto jest. Domyślnymi wartościami funkcji są „złota zasada”

function resize_image($file, $w = 1200, $h = 741, $crop = false)
   {
       try {
           $ext = pathinfo(storage_path() . $file, PATHINFO_EXTENSION);
           list($width, $height) = getimagesize($file);
           // if the image is smaller we dont resize
           if ($w > $width && $h > $height) {
               return true;
           }
           $r = $width / $height;
           if ($crop) {
               if ($width > $height) {
                   $width = ceil($width - ($width * abs($r - $w / $h)));
               } else {
                   $height = ceil($height - ($height * abs($r - $w / $h)));
               }
               $newwidth = $w;
               $newheight = $h;
           } else {
               if ($w / $h > $r) {
                   $newwidth = $h * $r;
                   $newheight = $h;
               } else {
                   $newheight = $w / $r;
                   $newwidth = $w;
               }
           }
           $dst = imagecreatetruecolor($newwidth, $newheight);

           switch ($ext) {
               case 'jpg':
               case 'jpeg':
                   $src = imagecreatefromjpeg($file);
                   break;
               case 'png':
                   $src = imagecreatefrompng($file);
                   imagecolortransparent($dst, imagecolorallocatealpha($dst, 0, 0, 0, 127));
                   imagealphablending($dst, false);
                   imagesavealpha($dst, true);
                   break;
               case 'gif':
                   $src = imagecreatefromgif($file);
                   imagecolortransparent($dst, imagecolorallocatealpha($dst, 0, 0, 0, 127));
                   imagealphablending($dst, false);
                   imagesavealpha($dst, true);
                   break;
               case 'bmp':
                   $src = imagecreatefrombmp($file);
                   break;
               default:
                   throw new Exception('Unsupported image extension found: ' . $ext);
                   break;
           }
           $result = imagecopyresampled($dst, $src, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
           switch ($ext) {
               case 'bmp':
                   imagewbmp($dst, $file);
                   break;
               case 'gif':
                   imagegif($dst, $file);
                   break;
               case 'jpg':
               case 'jpeg':
                   imagejpeg($dst, $file);
                   break;
               case 'png':
                   imagepng($dst, $file);
                   break;
           }
           return true;
       } catch (Exception $err) {
           // LOG THE ERROR HERE 
           return false;
       }
   }
Daniel Doinov
źródło
Świetna funkcja @DanielDoinov - dzięki za opublikowanie - szybkie pytanie: czy jest sposób, aby przekazać tylko szerokość i pozwolić funkcji na względne dostosowanie wysokości na podstawie oryginalnego obrazu? Innymi słowy, jeśli oryginał ma wymiary 400x200, czy możemy powiedzieć funkcji, dla której chcemy, aby nowa szerokość wynosiła 200, i pozwolić funkcji obliczyć, że wysokość powinna wynosić 100?
marcnyc
Jeśli chodzi o twoje wyrażenie warunkowe, nie sądzę, aby miało sens wykonywanie techniki zmiany rozmiaru, jeśli $w === $width && $h === $height. Pomyśl o tym. Powinien być >=i >=porównania. @Daniel
mickmackusa
1

Ciasto ZF:

<?php

class FkuController extends Zend_Controller_Action {

  var $image;
  var $image_type;

  public function store_uploaded_image($html_element_name, $new_img_width, $new_img_height) {

    $target_dir = APPLICATION_PATH  . "/../public/1/";
    $target_file = $target_dir . basename($_FILES[$html_element_name]["name"]);

    //$image = new SimpleImage();
    $this->load($_FILES[$html_element_name]['tmp_name']);
    $this->resize($new_img_width, $new_img_height);
    $this->save($target_file);
    return $target_file; 
    //return name of saved file in case you want to store it in you database or show confirmation message to user



  public function load($filename) {

      $image_info = getimagesize($filename);
      $this->image_type = $image_info[2];
      if( $this->image_type == IMAGETYPE_JPEG ) {

         $this->image = imagecreatefromjpeg($filename);
      } elseif( $this->image_type == IMAGETYPE_GIF ) {

         $this->image = imagecreatefromgif($filename);
      } elseif( $this->image_type == IMAGETYPE_PNG ) {

         $this->image = imagecreatefrompng($filename);
      }
   }
  public function save($filename, $image_type=IMAGETYPE_JPEG, $compression=75, $permissions=null) {

      if( $image_type == IMAGETYPE_JPEG ) {
         imagejpeg($this->image,$filename,$compression);
      } elseif( $image_type == IMAGETYPE_GIF ) {

         imagegif($this->image,$filename);
      } elseif( $image_type == IMAGETYPE_PNG ) {

         imagepng($this->image,$filename);
      }
      if( $permissions != null) {

         chmod($filename,$permissions);
      }
   }
  public function output($image_type=IMAGETYPE_JPEG) {

      if( $image_type == IMAGETYPE_JPEG ) {
         imagejpeg($this->image);
      } elseif( $image_type == IMAGETYPE_GIF ) {

         imagegif($this->image);
      } elseif( $image_type == IMAGETYPE_PNG ) {

         imagepng($this->image);
      }
   }
  public function getWidth() {

      return imagesx($this->image);
   }
  public function getHeight() {

      return imagesy($this->image);
   }
  public function resizeToHeight($height) {

      $ratio = $height / $this->getHeight();
      $width = $this->getWidth() * $ratio;
      $this->resize($width,$height);
   }

  public function resizeToWidth($width) {
      $ratio = $width / $this->getWidth();
      $height = $this->getheight() * $ratio;
      $this->resize($width,$height);
   }

  public function scale($scale) {
      $width = $this->getWidth() * $scale/100;
      $height = $this->getheight() * $scale/100;
      $this->resize($width,$height);
   }

  public function resize($width,$height) {
      $new_image = imagecreatetruecolor($width, $height);
      imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
      $this->image = $new_image;
   }

  public function savepicAction() {
    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);

    $this->_helper->layout()->disableLayout();
    $this->_helper->viewRenderer->setNoRender();
    $this->_response->setHeader('Access-Control-Allow-Origin', '*');

    $this->db = Application_Model_Db::db_load();        
    $ouser = $_POST['ousername'];


      $fdata = 'empty';
      if (isset($_FILES['picture']) && $_FILES['picture']['size'] > 0) {
        $file_size = $_FILES['picture']['size'];
        $tmpName  = $_FILES['picture']['tmp_name'];  

        //Determine filetype
        switch ($_FILES['picture']['type']) {
            case 'image/jpeg': $ext = "jpg"; break;
            case 'image/png': $ext = "png"; break;
            case 'image/jpg': $ext = "jpg"; break;
            case 'image/bmp': $ext = "bmp"; break;
            case 'image/gif': $ext = "gif"; break;
            default: $ext = ''; break;
        }

        if($ext) {
          //if($file_size<400000) {  
            $img = $this->store_uploaded_image('picture', 90,82);
            //$fp      = fopen($tmpName, 'r');
            $fp = fopen($img, 'r');
            $fdata = fread($fp, filesize($tmpName));        
            $fdata = base64_encode($fdata);
            fclose($fp);

          //}
        }

      }

      if($fdata=='empty'){

      }
      else {
        $this->db->update('users', 
          array(
            'picture' => $fdata,             
          ), 
          array('username=?' => $ouser ));        
      }



  }  

źródło
1

Znalazłem matematyczny sposób na wykonanie tej pracy

Repozytorium Github - https://github.com/gayanSandamal/easy-php-image-resizer

Przykład na żywo - https://plugins.nayague.com/easy-php-image-resizer/

<?php
//path for the image
$source_url = '2018-04-01-1522613288.PNG';

//separate the file name and the extention
$source_url_parts = pathinfo($source_url);
$filename = $source_url_parts['filename'];
$extension = $source_url_parts['extension'];

//define the quality from 1 to 100
$quality = 10;

//detect the width and the height of original image
list($width, $height) = getimagesize($source_url);
$width;
$height;

//define any width that you want as the output. mine is 200px.
$after_width = 200;

//resize only when the original image is larger than expected with.
//this helps you to avoid from unwanted resizing.
if ($width > $after_width) {

    //get the reduced width
    $reduced_width = ($width - $after_width);
    //now convert the reduced width to a percentage and round it to 2 decimal places
    $reduced_radio = round(($reduced_width / $width) * 100, 2);

    //ALL GOOD! let's reduce the same percentage from the height and round it to 2 decimal places
    $reduced_height = round(($height / 100) * $reduced_radio, 2);
    //reduce the calculated height from the original height
    $after_height = $height - $reduced_height;

    //Now detect the file extension
    //if the file extension is 'jpg', 'jpeg', 'JPG' or 'JPEG'
    if ($extension == 'jpg' || $extension == 'jpeg' || $extension == 'JPG' || $extension == 'JPEG') {
        //then return the image as a jpeg image for the next step
        $img = imagecreatefromjpeg($source_url);
    } elseif ($extension == 'png' || $extension == 'PNG') {
        //then return the image as a png image for the next step
        $img = imagecreatefrompng($source_url);
    } else {
        //show an error message if the file extension is not available
        echo 'image extension is not supporting';
    }

    //HERE YOU GO :)
    //Let's do the resize thing
    //imagescale([returned image], [width of the resized image], [height of the resized image], [quality of the resized image]);
    $imgResized = imagescale($img, $after_width, $after_height, $quality);

    //now save the resized image with a suffix called "-resized" and with its extension. 
    imagejpeg($imgResized, $filename . '-resized.'.$extension);

    //Finally frees any memory associated with image
    //**NOTE THAT THIS WONT DELETE THE IMAGE
    imagedestroy($img);
    imagedestroy($imgResized);
}
?>
Gayan Sandamal
źródło
0

Możesz spróbować biblioteki PHP TinyPNG. Korzystając z tej biblioteki, obraz jest automatycznie optymalizowany podczas procesu zmiany rozmiaru. Wszystko, czego potrzebujesz, aby zainstalować bibliotekę i uzyskać klucz API ze strony https://tinypng.com/developers . Aby zainstalować bibliotekę, uruchom poniższe polecenie.

composer require tinify/tinify

Następnie twój kod jest następujący.

require_once("vendor/autoload.php");

\Tinify\setKey("YOUR_API_KEY");

$source = \Tinify\fromFile("large.jpg"); //image to be resize
$resized = $source->resize(array(
    "method" => "fit",
    "width" => 150,
    "height" => 100
));
$resized->toFile("thumbnail.jpg"); //resized image

Napisałem bloga na ten sam temat http://artisansweb.net/resize-image-php-using-tinypng

Sajid Sayyad
źródło
0

Sugerowałbym łatwy sposób:

function resize($file, $width, $height) {
    switch(pathinfo($file)['extension']) {
        case "png": return imagepng(imagescale(imagecreatefrompng($file), $width, $height), $file);
        case "gif": return imagegif(imagescale(imagecreatefromgif($file), $width, $height), $file);
        default : return imagejpeg(imagescale(imagecreatefromjpeg($file), $width, $height), $file);
    }
}
Amir Fo
źródło
0
private function getTempImage($url, $tempName){
  $tempPath = 'tempFilePath' . $tempName . '.png';
  $source_image = imagecreatefrompng($url); // check type depending on your necessities.
  $source_imagex = imagesx($source_image);
  $source_imagey = imagesy($source_image);
  $dest_imagex = 861; // My default value
  $dest_imagey = 96;  // My default value

  $dest_image = imagecreatetruecolor($dest_imagex, $dest_imagey);

  imagecopyresampled($dest_image, $source_image, 0, 0, 0, 0, $dest_imagex, $dest_imagey, $source_imagex, $source_imagey);

  imagejpeg($dest_image, $tempPath, 100);

  return $tempPath;

}

Jest to dostosowane rozwiązanie oparte na tym wspaniałym wyjaśnieniu. Ten facet wyjaśnił krok po kroku. Mam nadzieję, że wszystkim się to spodoba.

Emiliano Barboza
źródło