Sabtu, 03 April 2010

Resize Image/Gambar dengan PHP

Resize Image/Gambar dengan PHP

Melakukan resize gambar sangatlah simple, apalagi menggunakan software image editing seperti ®Photoshop, tinggal beberapa klik udah jadi. Tapi bagaimana jika file gambar yang akan diedit ada diserver atau bayangkan contoh kasus seorang user mengupload gambar sedangkan anda ingin agar gambarnya tidak lebih lebar dari 100 pixel?.

Nah!, disini akan dibahas cara melakukan resize gambar langsung menggunakan PHP sehingga anda tidak perlu membuka aplikasi image editor lagi. Jika anda tidak ingin tahu hal teknisnya dan langsung ingin mencoba menggunakannya, anda dapat unduh filenya disini. Didalamnya sudah ada "sedikit" keterangan tentang cara menggunakannya. Sebenarnya sudah ada banyak software yang dibuat dengan PHP untuk beroperasi pada file gambar, dan saya tidak ingin mereinventing the wheel, tapi kalau hanya membutuhkan kemampuan untuk melakukan resize saja, kenapa harus menggunakan software yang lengkap.

Source Code

Ini dia source PHP yang digunakan, nanti akan kita bahas setelahnya.

<?php
class my_image {
    protected $image;
    
    public function __construct($image) {
        if(!is_file($image)): trigger_error('Image file does not exists', E_USER_ERROR); 
        else: $this->image = $image; endif; clearstatcache();
    }
    
    public function resize($new_width=0, $new_height=0, $new_name='') {
        if(empty($new_width) && empty($new_height)) { return false; }
        
        list($iwidth, $iheight, $type) = getimagesize($this->image);
        $rext = image_type_to_extension($type, false);
        
        if($type !== 2 && $type !== 3) { return false; }
        
        if(!empty($new_width) && empty($new_height)) {
            $mwidth = $new_width / $iwidth;
            $new_height = round($iheight * $mwidth);
        }
        
        if(empty($new_width) && !empty($new_height)) {
            $mheight = $new_height / $iheight;
            $new_width = round($iwidth * $mheight);
        }
        
        $image_p = imagecreatetruecolor($new_width, $new_height);
        $image = ($rext == 'png' ? imagecreatefrompng($this->image) : imagecreatefromjpeg($this->image));
        
        if(isset($image)) {
            imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $iwidth, $iheight);
        }
        
        if(!empty($new_name)) {
            $next = strtolower(end(explode('.', $new_name)));
            switch($next) {
                case 'jpg':
                    if($rext == 'png'): $new_name .= '.'.$rext; endif; break;
                case 'png':
                    if($rext == 'jpeg'): $new_name .= '.'.$rext; endif; break;
                default:
                    $new_name .= '.'.$rext;
            }
        } else { $new_name = $this->image; }
        
        if($rext === 'png') {
            imagepng($image_p, $new_name, 0);
        } else {
            imagejpeg($image_p, $new_name, 95);
        }
    }
}
?>

Pembahasan

Pada kode diatas, saya membuat sebuah class dengan nama my_image yang memiliki constructor yang meminta input file gambar yang akan diresize. Contoh pembuatan objek dari class ini adalah: $img = new my_image('path/imageku.jpg');. Object constructor akan mengecek apakah nama file yang anda masukkan benar sebuah file, jika file tidak ketemu akan muncul pesan error kalau file tidak ada. Jika file ditemukan, constructor akan mengeset properti image di class ini. Setelah objek dibuat, anda langsung dapat menggunakan fungsi resize dengan cara: $img->resize(10, 10, 'imut.jpg'); yang menghasilkan image baru dengan nama imut.jpg.

Method resize menggunakan tiga parameter yang semuanya bersifat optional yaitu:

  1. $new_width: Angka lebar gambar yang baru dalam pixel.
  2. $new_height: Angka tinggi gambar yang baru juga dalam pixel.
  3. $new_name: Nama file yang baru hasil dari resize.

Kita bahas kode berikutnya dalam fungsi resize()

if(empty($new_width) && empty($new_height)) { return false; }
   
list($iwidth, $iheight, $type) = getimagesize($this->image);
$rext = image_type_to_extension($type, false);
if($type !== 2 && $type !== 3) { return false; }

Kode diatas akan mengecek apakah parameter lebar dan tinggi diisi atau tidak. Jika keduanya tidak diisi maka fungsi akan mereturn FALSE. Setelah itu kita gunakan fungsi dari PHP getimagesize() yang akan menghasilkan array informasi dari file gambar yang akan kita resize (yang diset melalui constructor). Secara berurutan informasi itu adalah: lebar, tinggi, jenis gambar, string properti yang digunakan di HTML, dan terakhir adalah mime type yang dikirim oleh server untuk file gambar tersebut.

Jenis gambar berisi angka sedangkan saya butuh string ekstensionnya, karena itu saya gunakan fungsi image_type_to_extension() (PHP 5+) dengan parameter kedua diisi FALSE agar string yang dihasilkan tidak didahului karakter dot/titik. Baris berikutnya, karena fungsi resize hanya mendukung jenis gambar JPEG/JPG dan PNG saja, maka fungsi akan mereturn FALSE jika jenis gambarnya selain keduanya.

if(!empty($new_width) && empty($new_height)) {
    $mwidth = $new_width / $iwidth;
    $new_height = round($iheight * $mwidth);
}
        
if(empty($new_width) && !empty($new_height)) {
    $mheight = $new_height / $iheight;
    $new_width = round($iwidth * $mheight);
}
        
$image_p = imagecreatetruecolor($new_width, $new_height);
$image = ($rext == 'png' ? imagecreatefrompng($this->image) : imagecreatefromjpeg($this->image));
        
if(isset($image)) {
    imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $iwidth, $iheight);
}

Beberapa baris awal pada kode diatas akan menghitung kira-kira lebar dan tinggi dari gambar yang baru. Jika lebar diset sedangkan tinggi tidak diset maka fungsi akan menghitung tinggi baru berdasarkan perbandingan lebar gambar asli dengan lebar gambar yang baru, begitu pula sebaliknya. Selanjutnya kita membuat resource gambar menggunakan fungsi imagecreatetruecolor() yang berisi parameter lebar dan tinggi gambar yang kita inginkan.

Karena kita mendukung dua jenis gambar maka kita menggunakan dua fungsi yaitu: imagecreatefrompng() dan imagecreatefromjpeg yang ditentukan berdasarkan isi variabel $rext. Kedua fungsi tadi berfungsi membuat gambar yang berasal dari sebuah URL ataupun nama sebuah file.

Setelah itu kita menggunakan fungsi imagecopyresampled() yang memiliki fungsi hampir sama dengan imagecopyresized() tapi dengan kualitas yang lebih baik. Fungsi imagecopyresampled memiliki 10 parameter yaitu:

  1. Resource gambar file tujuan.
  2. Resource gambar file asal.
  3. Titik koordinat x file tujuan.
  4. Titik koordinat y file tujuan.
  5. Titik koordinat x file asal.
  6. Titik koordinat y file asal.
  7. Lebar file gambar tujuan.
  8. Tinggi file gambar tujuan.
  9. Lebar file gambar asal.
  10. Tinggi file gambar asal.

Dari parameter-parameter diatas kita bisa membayangkan bahwa kita akan dapat melakukan "crop" pada suatu gambar, tapi saat ini tidak akan dibahas.

if(!empty($new_name)) {
    $next = strtolower(end(explode('.', $new_name)));
    switch($next) {
        case 'jpg':
            if($rext == 'png'): $new_name .= '.'.$rext; endif; break;
        case 'png':
            if($rext == 'jpeg'): $new_name .= '.'.$rext; endif; break;
        default:
            $new_name .= '.'.$rext;
    }
} else { $new_name = $this->image; }
        
if($rext === 'png') {
    imagepng($image_p, $new_name, 0);
} else {
    imagejpeg($image_p, $new_name, 95);
}

Hampir selesai :). Baris berikutnya adalah memeriksa apakah nama baru diset atau tidak. Jika iya, akan dicek apakah memiliki ekstension yang sama dengan target. Jika berbeda akan ditambahkan ekstension secara otomatis. Jika nama baru tidak diset maka fungsi akan melakukan overwrite pada file gambar yang lama. Setelah nama selesai dicek selanjutnya kita gunakan dua fungsi untuk menyimpan file gambar JPEG/JPG dan PNG dari resource yang telah kita buat yaitu dengan fungsi imagepng dan imagejpeg. Angka 0 dan 95 adalah kualitas dari gambar yang dihasilkan. Untuk PNG menggunakan range 1-10 sedangkan JPEG menggunakan range 1-100 (defaultnya 75). Kualitas gambar juga akan mempengaruhi ukuran dari gambar yang akan kita buat.

Penggunaan Class

Cara menggunakan class diatas adalah pertama anda harus membuat instance lebih dahulu dengan perintah new yang berisi string path ke file gambar yang akan diedit. Contoh:

$gambar = 'path/image.jpg';
$img = new my_image($gambar);


Selanjutnya tinggal panggil resize method dengan cara berikut:

$lebar_baru = 10;
$tinggi_baru = 10;
$nama_gambar_baru = 'path/imagekecil.jpg';
$img->resize($lebar_baru, $tinggi_baru, $nama_gambar_baru);


Selesai. Jika anda ingin mengunduh file yang saya buat, anda dapat melakukannya disini. Thanks. Oh iya, tambahkan handle resize untuk jenis file GIF jika anda berkenan :).