Miniaturki obrazków w PHP (gd)

Podczas tworzenia strony www w PHP, częstym tematem jest tworzenie miniaturek. Ja niedługo będę miał projekt gdzie taką procedurę będę musiał wykonać. Oczywiście posiadam juz takie skrypty lecz nie są one w pełni niezawodne. Postanowiłem napisać klasę w PHP, którą będę mógł wykorzystac wielokrotnie, i też tutaj ją udostępniam – jeżeli masz pomysł jak ją ulepszyć, napisz.

UWAGA!

O wiele lepszy skrypt do tworzenia miniaturek napisałem w artykule miniaturki obrazków php – imagemagic (imagic) – ten tutaj proponuje zostawic w spokoju, no chyba że nie masz możliwości zainstalowania imagic :)

Założenia

Skrypt powinien otrzymywać w parametrach adres obrazka, oraz maksymalny rozmiar jaki powinien mieć obrazek wynikowy. Tworzenie jednej miniaturki powinno się odbywać tylko raz (trzeba zastosowac cache), aby później nie obciążać serwera, oraz po to aby działało to szybciej.

U mnie na localhost mialem problem z obsługą png, myślę że to kwestia softu ponieważ jakiś czas temu mi to działało :), tak więc skrypt obsługuje tylko JPG, i GIF.

Przykładowe wywołanie: image.php?url=images/auto.jpg&max=200

W skrypcie musimy ustawić trzy zmienne: katalog cache, obrazek który się wygeneruje w przypadku jakiegoś błedu (np niepoprawne rozszerzenie, czy też gdy obrazek do zmniejszenia jest niepoprawny) oraz jakość (tutaj proponuje 80, max 90)

1
2
3
$config['cache'] = 'cache_image';
$config['notExist'] = 'cache_image/_notExist.gif';
$config['quality'] = 80;

Skrypt

Pisząc skrypt ominąłem takie rzeczy jak komentarze i ne przykładałem uwagi do tego aby to wszystko ładnie wyglądało, myślę że pomimo powyższych niedociągłości procedura ta jest czytelna i przejrzysta.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
<?

class Image{

    private $max;
    private $config;
    private $image;
   
    public function generate(){
        $this -> getImageInfo();
        $this -> calculateNewSize();
        $this -> resizeImage();
        $this -> output();
    }
   
    private function output(){
        $command = 'image'.$this -> image['info']['type'].'(
            $this -> image["result"],
            $this -> image["cacheUrl"],
            $this -> config["quality"]);'
;
        eval($command);
       
        $command = 'image'.$this -> image['info']['type'].'(
            $this -> image["result"],
            "",
            $this -> config["quality"]);'
;     
        header("Content-Type: image/".$this -> image['info']['type']);
        eval($command);
        exit;
    }  
   
    private function checkCache(){
        if(file_exists($this -> image['cacheUrl'])){
           
            $fp = fopen($this -> image['cacheUrl'], 'rb');
            $type = $this -> getType($this -> image['cacheUrl']);
           
            header("Content-Type: image/".$type);
            header("Content-Length: " . filesize($this -> image['cacheUrl']));
            fpassthru($fp);
            exit;
        }
    }
   
    private function resizeImage(){
         
        $command = '$source = imagecreatefrom'.$this -> image['info']['type'].'("'.$this -> image['url'].'");';
        eval($command);
       
        $target = imagecreatetruecolor($this -> image['info']['newSize']['w'],$this -> image['info']['newSize']['h']);
        if($this -> image['info']['type'] == 'gif'){
            $trnprt_indx = imagecolortransparent($source);
            $trnprt_color = imagecolorsforindex($source, $trnprt_indx);
            $trnprt_indx = imagecolorallocate($target, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']);
            imagefill($target, 0, 0, $trnprt_indx);
            imagecolortransparent($target, $trnprt_indx);
        }
        imagecopyresampled(
            $target,
            $source,
            0,
            0,
            0,
            0,
            $this -> image['info']['newSize']['w'],
            $this -> image['info']['newSize']['h'],
            $this -> image['info']['originalSize']['w'],
            $this -> image['info']['originalSize']['h']);      
        $this -> image['result'] = $target;
    }
   
   
    private function getImageInfo(){
       
        if(!file_exists($this -> image['url']))
            $this -> image['url'] = $this -> config['notExist'];
       
       
        $this -> image['cacheUrl'] = $this -> config['cache'];
        $this -> image['cacheUrl'] .= DIRECTORY_SEPARATOR;
        $this -> image['cacheUrl'] .= $this -> max.'_';
        $this -> image['cacheUrl'] .= $this -> config['quality'].'_';
        $this -> image['cacheUrl'] .= bin2hex($this -> image['url']);
        $this -> checkCache();
        $tmp = getimagesize($this -> image['url']);
        $this -> image['info']['originalSize']['w'] = $tmp[0];
        $this -> image['info']['originalSize']['h'] = $tmp[1];
        $type = $this -> getType($this -> image['url']);

        if($type == ''){
            $this -> image['url'] = $this -> config['notExist'];
            $this -> getImageInfo();
        }else{
            $this -> image['info']['type'] = $type;
        }
    }
    private function getType($url){
        $type = '';
        switch (exif_imagetype($url)){
            case IMAGETYPE_GIF:
                $type = 'gif';
                break;
            case IMAGETYPE_JPEG:
                $type = 'jpeg';
                break;     

        }  
        return $type;
   
    }
    private function calculateNewSize(){
        $max = $this -> max;
       
        $lengthValue = max($this->image['info']['originalSize']);
        $change = round($max/$lengthValue,2);
        $this -> image['info']['newSize']['w'] = round($this -> image['info']['originalSize']['w']*$change);
        $this -> image['info']['newSize']['h'] = round($this -> image['info']['originalSize']['h']*$change);
   
    }
   

    public function __construct() {
        $this -> max = $_GET['max'];
        $this -> image = array();
        $this -> image['url'] = $_GET['url'];
       
    }
    public function config($_config){
        $this -> config = $_config;
   
    }
}

$config = array();

$config['cache'] = 'cache_image';
$config['notExist'] = 'cache_image/_notExist.gif';
$config['quality'] = 80;


$image = new Image();
$image -> config($config);
$image -> generate();

?>

 

Tagi:

Komentarze: 1 do “Miniaturki obrazków w PHP (gd)”

  1. 1 MWL

    Prosto, zwięźle i na temat. Dzięki za rozwiązanie mojego problemu :)

Napisz komentarz