Zmniejszanie fotek w PHP do określonego rozmiaru

0

Witam serdecznie,
Mam problem ze zmniejszaniem zdjęć w PHP :(
Mam następujący kod:

class Image
{
        const JPG                        =        'jpg';
        const JPEG                        =        'jpeg';
        const GIF                        =        'gif';
        const PNG                        =        'png';

        private $handle;
        private $width;
        private $height;
        private $imageType;

        function __construct($fileName = '')
        {
                if ($fileName)
                {
                        $this->open($fileName);
                }
        }

        function __destruct()
        {
                if ($this->handle)
                {
                        $this->close();
                }
        }

        public function setImageType($imageType)
        {
                $this->imageType = $imageType;
                return $this;
        }

        public function getImageType()
        {
                return $this->imageType;
        }

        public function create($imageType, $width, $height)
        {
                $this->imageType = $imageType;
                $this->handle = imagecreatetruecolor($width, $height);

                $this->width = $width;
                $this->height = $height;
                return $this;
        }

        /**
         * Otwarcie obrazu
         * @param string $fileName Sciezka/nazwa pliku
         */
        public function open($fileName)
        {
                if (!file_exists($fileName))
                {
                        throw new Exception("$fileName does not exist");
                }

                $this->imageType =  strtolower(end(explode('.', $fileName)));
                list($this->width, $this->height, , ,) = @getimagesize($fileName);

                switch ($this->imageType)
                {
                        case 'jpeg':
                        case 'jpg':
                                $this->handle = @imagecreatefromjpeg($fileName);
                        break;

                        case 'gif':
                                $this->handle = @imagecreatefromgif($fileName);
                        break;

                        case 'png':
                                $this->handle = @imagecreatefrompng($fileName);
                        break;

                        default:
                                throw new Exception('Unsupported image format');
                }
        }

        public function getHandle()
        {
                return $this->handle;
        }

        /**
         * Zamyka uchwyt i konczy prace z obrazem
         */
        public function close()
        {
                @imagedestroy($this->handle);
        }

        /**
         * Zwraca szerokosc obrazu
         * @return int
         */
        public function getWidth()
        {
                return $this->width;
        }

        /**
         * Zwraca wysokosc obrazu
         * @return int
         */
        public function getHeight()
        {
                return $this->height;
        }

        /**
         * Zmiara rozmiaru obrazu do wartosci podanych w parametrach
         * @param int $width
         * @param int $height
         */
        public function resize($width, $height)
        {
                $image = @imagecreatetruecolor($width, $height);
//$this->handle = imagealphablending ($image, true);
                @imagecopyresampled($image, $this->handle, 0, 0, 0, 0, $width, $height, $this->width, $this->height);

                $this->handle = $image;
                $this->width = $width;
                $this->height = $height;
        }

        /**
         * Konwersja do systemu szestnastkowego
         * @param int $red
         * @param int $green
         * @param int $blue
         * @return string
         */
        public function rgb2hex($red, $green, $blue)
        {
                 return sprintf('#%02s%02s%02s', dechex($red), dechex($green), dechex($blue));
        }

        /**
         * Konwersja liczby szestnastkowej okreslajacej kolor, do tablicy liczb RGB
         * @param string $hex np. #ccc lub #f8f8f8
         * @return array
         */
        public function hex2rgb($hex)
        {
                if ($hex{0} == '#')
                {
                        $hex = substr($hex, 1);
                }
                if (strlen($hex) == 6)
                {
                        list($red, $green, $blue) = array(substr($hex, 0, 2), substr($hex, 2, 2), substr($hex, 4, 2));
                }
                elseif (strlen($hex) == 3)
                {
                        list($red, $green, $blue) = array($hex[0] . $hex[0], $hex[1] . $hex[1], $hex[2] . $hex[2]);
                }
                else
                {
                        return false;
                }

                return array(hexdec($red), hexdec($green), hexdec($blue));
        }

        /**
         * Metoda generuje miniature o podanych rozmiarach
         * @param int $width Szerokosc w px
         * @param int $height Wysokosc w px
         * @param strig $color Kolor tla dla miniatury
         */
        public function thumbnail($width, $height, $color = '#FFF')
        {
                // jezeli wysokosc jest MNIEJSZA niz szerokosc
                // obraz poziomy
                if ($this->height < $this->width)
                {
                        $ratio = $this->getHeight() / $this->getWidth();
                        $cHeight = $width * $ratio;

                        $this->resize($width, $cHeight);
                }
                // obraz pionowy
                else
                {
                        $ratio = $this->getWidth() / $this->getHeight();
                        $cWidth = $height * $ratio;

                        $this->resize($cWidth, $height);
                }

                list($red, $green, $blue) = $this->hex2rgb($color);
                $output = imagecreatetruecolor($width, $height);

                $color = imagecolorallocate($output, $red, $green, $blue);
                imagefill($output, 0, 0, $color);

                imagecopy($output, $this->handle, round(($width - $this->getWidth()) / 2), round(($height - $this->getHeight()) / 2), 0, 0, $this->getWidth(), $this->getHeight());

                $this->handle = $output;
        }

        /**
         * Zapis obrazu do pliku
         * @param $fileName Nazwa (sciezka) pliku
         */
        public function save($fileName)
        {
                switch ($this->imageType)
                {
                        case 'jpg':
                        case 'jpeg':
                                 @imagejpeg($this->handle, $fileName, 80);
                        break;

                        case 'gif':
                                @imagegif($this->handle, $fileName);
                        break;

                        case 'png':
                                @imagepng($this->handle, $fileName);
                        break;
                }
        }
}

$image = new Image("pliki/" . "" . $f1a);
$image->thumbnail(160, 240, '#FFFFFF');
$image->save("pliki/" . "mini222_" . $f1a); // miniatura
$image->close();

Zdjęcie źródłowe wygląda następująco:
user image

skrypt obrabia mi fotkę do czegoś takiego:
user image

a Chciałbym żeby to wyglądało następująco:
user image

Czyli całe zdjęcie, sformatowane tak ażeby się mieściło proporcjonalnie... :)

Generalnie mam różnego rodzaju fotki i chciałbym żeby miniaturka tak operowała tymi białymi paskami ażeby zawsze całe fotki były widoczne...

Macie pomysł co mam źle w moim skrypcie?

North

0

tak działa ta biblioteka. szukaj innej, takiej, która pozwala Ci wybrać metodę skalowania. phpclasses.org i powodzenia ;)

0

nooo właśnie ta działa prawie idealnie ;)
gdyby nie te mały szkopuły....

0

Nie zgodzę się z tym. Kiedyś się bawiłem w GD w zmniejszanie i z tego co pamiętam jest to możliwe. Robisz tak, że zmniejszasz proporcjonalnie oba wymiary i wklejasz mniejszy obrazek w większy. Jeżeli by się nie dało to niby jak np.: na Allegro robiliby kilka ikonek na jednym obrazku?

Jak dobrze wszystko policzysz to da się zrobić, chyba że chcesz to robić z automatu... (jedna gotowa funkcja).

0

jak chcesz mieć proporcjonalne zmniejszanie to i wysokość i szerokość musi być przemnożona przez to samo ratio
czyli tam gdzie masz:

 $this->resize(..., ...);

(w dwóch miejscach)
napisz:

 $this->resize($width * $ratio, $height * $ratio);

// jak chcesz białe paski to już więcej roboty i trzeba dopisać kod - po prostu poszukaj innej biblioteki, jak radzi dzek bo nikomu się tu nie będzie chciało tego robić za Ciebię

0

omg, Zi00mal, logiczne, że się da przy pomocy GD ;| po prostu ta biblioteka nazwana tu Image nie posiada takiej opcji. Ale oczywiście można ją rozbudować/poprawić, aczkolwiek mi się nie chce, bo nie lubię tego przeliczania wszystkiego, raz sobie zrobiłem wygodną bibliotekę pod to i kosztowało mnie to trochę wizualizacji co i jak i używam teraz (niestety nie mogę upublicznić, a chciałbym, bo jak ja szukałem to nie znalazłem nic wygodnego w obsłudze).

0

Myślałem, że stwierdziłeś że się nie da. Ale to prawda wymaga to trochę czasu i przeliczeń.

1 użytkowników online, w tym zalogowanych: 0, gości: 1