GD kullanarak PHP'de resimlerle çalışma. PHP php gd örnekleriyle dinamik görüntü oluşturma

  • 20.06.2020

Tanıtım:

PHP'nin yetenekleri HTML "I oluşturmakla sınırlı değildir. PHP, gif, png, jpg, wbmp ve xpm dahil olmak üzere çeşitli biçimlerdeki görüntüleri oluşturmak ve işlemek için kullanılabilir. Çalışmak için GD grafik kitaplığı ile derlenmiş PHP'ye ihtiyacınız var.GD ve PHP, hangi görüntü formatlarıyla çalışacağınıza bağlı olarak diğer kitaplıklara da bağlı olabilir.

EXIF uzantısı ile JPEG ve TIFF görüntülerinin başlıklarında saklanan bilgileri işleyebileceksiniz. Bununla dijital kameralar tarafından oluşturulan meta etiketlere erişebilirsiniz. EXIF uzantısının çalışması için GD kitaplığı gerekli değildir.

Kütüphaneyi kurma ve yapılandırma hakkında resmi belgelerde okuyabilirsiniz. Büyük olasılıkla, buna ihtiyacınız olmayacak çünkü her şey uzun süredir kurulu.

neyle uğraşıyoruz

PHP'deki görüntü işleme fonksiyonlarını iki kategoriye ayıracağım. Dosyalarla çalışanlar ve bellekteki bir görüntüyle çalışanlar (kaynak).

Bu işlevlerin birçoğu vardır ve hepsi önemlidir. Her birini tarif etmeyeceğim, bunu resmi belgelerle yapmamak benim için daha iyi. Ama bunlara örneklerle bakabileceğiz ve şimdi yapacağız.

İşlenen görüntünün kaydedilmesi, aşağıdakiler kullanılarak gerçekleştirilir:
Açıklamada imagegif yazıyor - Görüntüyü tarayıcıya veya dosyaya çıkar. Bunun nasıl çalıştığını kabaca anlamak için bir editöre ve bir resme ihtiyacımız var. Resmi editörle açıyoruz ve bir sürü anlaşılmaz sembol görüyoruz.
Harika, bu bizim resmimiz. Bu fonksiyon hafızamızdaki pikselleri şöyle bir kayda dönüştürür. Tüm bunları bir dosyaya yazmak için imagegif'te 2 parametre belirtiyoruz: hafızadaki imajımıza bir işaretçi ve dosyanın adı.
imagegif ($im, "image.gif");

Tarayıcı bize bir resim gösterdiğinde, esasen sunucudan aynı karalamaları ister ve bunları ekranda bir görüntüye dönüştürür.
Bu, bu karalamaları sadece bir dosyaya kaydedemeyeceğimiz, aynı zamanda hemen tarayıcıya gönderebileceğimiz anlamına gelir. Onu aynı imagegif yapar, ancak bu sefer ikinci parametre olmadan.
resimgif ($ im)

Ama bir tane var ama. Tarayıcıya, düz metin olarak değil, resim olarak işlenmesi gerektiğini söylemeniz gerekir. Burada "php'nin çalıştığı yer" bölümünde tartışılan başlıkları size hatırlatmama izin verin.
Başlığı göndermek için başlık işlevini kullanırız.
başlığın içeriği (belge türü: resim gif) olacaktır.
şuna benziyor: başlık ("İçerik türü: resim / gif");

Ve son olarak, burada tanıştığın son şey
$ img değişkenini silmez, ancak değişkenin işaret ettiği belleği temizler. Yüksek çözünürlüklü görüntülerle, örneğin birkaç paralel görüntüyle ve aynı anda izin verilen boş belleğin ötesine geçme konusunda sabırsızsanız, kullanışlı olacaktır.

Çalışma zamanında komut dosyasına ayrılan tüm belleğin, çalışması tamamlandıktan sonra otomatik olarak serbest bırakıldığını hatırlatmama izin verin.

Hepsi bu, teorik temele hakim olduk.


Tipik hatalar:

Önemli hata: Tanımsız işleve çağrı ...
Bu, GD kitaplığının kurulu olmadığı veya her şeyin çok daha basit olduğu anlamına gelir - işlev adına bir hata yazdınız. GD'nin kurulumu belgelerde açıklanmıştır. Denver'da varsayılan olarak, ubuntu'da sudo apt-get install php5-gd komutunu kullanabilir ve sunucuyu yeniden başlatabilirsiniz.

Uyarı: imagecreatefrom .. (a.png) akışı açamadı: İzin reddedildi
burada da her şey basit. Resmimize sağ tıklayın ve herkes için okuma izinlerini ayarlayın.

Resim yerine kaynak kimliği # görüntülenir.
= (Tarayıcıya çıktının ikinci parametre olmadan imagegif () gibi özel işlevler kullanılarak gerçekleştirildiğini zaten söylemiştim. Ve bir yerde echo $ img var ve ekranda hafızanın içeriği değil, sadece bir mesaj görüntüleniyor. bunun bir işaretçi olduğunu.

Uyarı: ... (): sağlanan argüman geçerli bir Resim kaynağı değil
Bir işaretçi bekleniyordu, ancak ona ilettiğiniz şey bir dize veya başka bir şey. Ayrıca, bir işaretçiyi geçtiğinizden eminseniz, ancak yine de bu hatayı alıyorsanız, itaat etmeyi bırakın. Yanılıyorsun ve her şeyi iki kez kontrol etsen iyi olur. Çok fazla sinir kurtaracak =)

�PNG ��� IHDR���������h6��PIDAT (����JA��Mv�M4��
Evet, nedense görüntünün ikili kodu görüntüleniyor ve tarayıcı bundan bir görüntü çıkarmayı düşünmedi, ancak normal metin olarak işledi. Öğreticiyi tekrar gözden geçirin ve görüntüyü tarayıcıya gönderdiğimiz kısmı arayın.


Malzemeye hakim olmak için birkaç görev

Programlama adımlarını tekrar hatırlatayım
1. Sorunun ifadesi
2. Gerekli işlemlerin belirlenmesi
3. Her işlem için uygun fonksiyonların seçimi ()
4. Zinciri kurmak
5. İlk noktaya dönüş ile hata ayıklama

Unutmayın - şimdi deneyim kazanmıyorsunuz, ancak onu kazanmayı öğreniyorsunuz. Ödevleri tamamladığınızda bunu düşünün.
Bunları yerine getirdiysen ama kendin için yeni bir şey öğrenmediysen, ya onları kötü yaptın ya da hiç yerine getirmedin. Farklı bir senaryoda buraya kadar okumanız pek olası değildir.

Görevler

1. Üst Baskı
Resime birkaç kelime eklemek eminim sizin için zor olmayacaktır. Bu nedenle, bir grafik imza çizmeye çalışalım. Boyayı açıp imzamızı atıyoruz. Olmuş? İyi.
Şimdi Google'dan Pamela Anderson'ın iki fotoğrafını kaydedip onlara imzamızı ekliyoruz.
(İpucu: Görüntünün Alpha gibi bir parametreye sahip olduğunu bilmek muhtemelen yararlıdır - bu şeffaflık anlamına gelir. Ctrl + F'nin fonksiyonlar listesinde gözünüze çarpacağına eminim, ancak bu hiç gerekli değildir.)

2. Captcha
Karmaşık olanı yapmayacağız, basit olanı yapacağız. Her seferinde rastgele 4 basamak görüntülenir.
Amaç ne? Bunun için özel bir yazı tipi kullanacağız -. Ve resmimiz siyah metinli beyaz olduktan sonra bile, ona negatif bir filtre uygulayacağız ve ekranda tam tersi, siyah bir arka plan ve beyaz renkle görünmesini sağlayacağız ve her iki resim de ekranda görüntüleniyor. (Ve hepsi bir komut dosyasında)

3. php logosu
Bu görev daha basit ve daha özgün - php logosunu çizin.

Bu soruların cevaplarını burada bulabilirsiniz:

<<< Назад İçerik İleri >>>
Daha fazla sorunuz varsa veya net olmayan bir şey varsa - hoş geldiniz

DvizhKod projesinin sevgili katılımcıları! Bugün başka bir ilginç konu sizi bekliyor. Hepimiz sosyal ağlara yeni avatarlar yüklemeye alışkınız. Ancak doğru boyuta nasıl ölçeklenirler? Sunucuda neler oluyor? Bu ve bunun gibi pek çok sorunun cevabı kesi altında sizleri bekliyor.

Evet, eğer birisi bilmiyorsa, o zaman İnternet terminolojisinde "kes" (İngilizce cut - cut'tan) haberleri kısa (genel listede) ve tam sunum olarak ayıran bir yerdir.

Birçok kişi Cogear (Cogear, http://cogear.ru) adlı kendi site yönetim sistemimi geliştirdiğimi biliyor. Hikaye karmaşık ve uzun ama inatla hedefe doğru ilerliyorum.

Resimlerle çalışmanın temel yönlerine bir göz atalım.

PHP'nin yerleşik bir GD kitaplığı vardır. İşte belgeleri:

http://php.net/manual/ru/book.image.php

Bu sayfada çok sayıda çok farklı işlev bulacaksınız. Ama paniğe kapılmayın. Çok spesifik olanlarla ilgileniyoruz.

Gördüğünüz gibi, resimlerle çalışma hala prosedürler (fonksiyonlar) şeklinde oluyor, bu yüzden nesne yönelimli kabuğu kendiniz yazmanız gerekiyor.

Bir görüntüyle çalışmanın en basit örneği:

Yerel bir makinede denemek.

Dosya oluştur resim.php(Deneyler için yerel bir alanım var test.yerel).

1.jpg resmini test.local site klasörünün kök dizinine yerleştirin:

Tarayıcıda http://test.local/image.php diyoruz (sizin durumunuzda başka bir adres).

2.jpg resmini klasörde bulun:

Gördüğünüz gibi oranlar korunmadı. Çünkü onları saymadık.

Yeniden hesaplamanın gerçekleşmesi için komut dosyamızı düzeltelim:

$ ratio_orig) ($ genişlik = $ yükseklik * $ rate_orig;) else ($ yükseklik = $ genişlik / $ rate_orig;) // görüntüyü yeniden ölçeklendirme ile tuvale dosyadan yeniden örneklenmiş ($ image_p, $ image, 0, 0) , 0 , 0, $ genişlik, $ yükseklik, $ genişlik_orjin, $ height_orig); // imagejpeg çıktısı ($ image_p, "2.jpg", 100);

Sonucu görelim:

Yüksekliği saydığımız için, son görüntünün bir kısmı siyah çıktı (oluşturulan tuvalin orijinal rengi).

Resimle başka ne yapabilirsiniz? Kırpın, döndürün, üst üste katlayın, üzerine boyayın.

Görsellerle çalışmak için dersime ilgi duyacağınıza eminim. Dişli (modül) "Görüntüler" için bir sürücü olduğu için sistem dışında çalışmaz.

Ama içinde çok ilginç şeyler bulacaksınız:

* @copyright Copyright (c) 2012, Dmitry Belyaev * @license http://cogear.ru/license.html * @link http://cogear.ru * / class Image_Driver_GD, Image_Driver_Abstract'ı genişletir (/ ** * Bir resim oluşturur * / public function create () (switch ($ this-> info-> type) (case IMAGETYPE_JPEG: case IMAGETYPE_JPEG2000: $ this-> source = imagecreatefromjpeg ($ this-> info-> file); break; case IMAGETYPE_PNG: $ this - > kaynak = imagecreatefrompng ($ this-> info-> file); imagecolortransparent ($ this-> source, imagecolorallocate ($ this-> source, 0, 0, 0)); imagealphableding ($ this-> kaynak, YANLIŞ) ; imagesavealpha ($ this-> source, TRUE); break; case IMAGETYPE_GIF: $ this-> source = imagecreatefromgif ($ this-> info-> file); imagecolortransparent ($ this-> source, imagecolorallocate ($ this-> source) , 0, 0, 0)); imagealphablending ($ this-> source, FALSE); imagesavealpha ($ this-> source, TRUE); break; case IMAGETYPE_ICO: $ this-> source = imagecreatefromwbmp ($ this-> info- > dosya); break;)) / ** * Resmi yok eder * / public function destroy() (imagedestroy ($ this-> source); is_resource ($ this-> hedef) && imagedestroy ($ this-> target); ) / ** * Hedef resim oluşturur * * @param karışık $ genişlik * @param karışık $ yükseklik * / public function createTarget ($ genişlik, $ yükseklik) ($ bu-> hedef = imagecreatetruecolor ($ genişlik, $ yükseklik); if ($ this-> info-> type == IMAGETYPE_PNG VEYA IMAGETYPE_GIF == $ this-> info-> type) (imagecolortransparent ($ this-> target, imagecolorallocate ($ this-> target, 0, 0, 0)); imagealphableending ($ this-> target, FALSE); imagesavealpha ($ this-> target, TRUE);) return $ this-> target;) / ** * Resmi ölçeklendir * * @param int | string $ genişlik Genişlik * @ param int | string $ yükseklik Yükseklik * @param string $ fit Ölçekleme türü genişlik, yükseklik, sığdır * @param int | string $ ölçek Hangi görüntülerin herhangi bir, yukarı, aşağı ölçekleneceği * @return nesnesi Görüntü * / genel işlev yeniden boyutlandırma ($ genişlik , $ yükseklik, $ uygun = "genişlik", $ ölçek = "herhangi bir") ($ source_width = $ this-> smartSize ($ genişlik, "width"); $ source_height = $ this-> smartSize ($ yükseklik, "yükseklik) " ); // Ölçekleme türü anahtarını ($ uygun) kontrol edin (// genişlikte iplik geçiriyoruz, sonra yüksekliği istenen orantılara getiriyoruz durum "width": $ width = $ source_width; $ yükseklik = yuvarlak (($ kaynak_genişlik * $ bu-> bilgi-> yükseklik) / $ bu-> bilgi-> genişlik); kırmak; // Yüksekliği ayarlıyorsanız, genişliği istenen orantılara getirin case "height": $ genişlik = yuvarlak (($ bu-> bilgi-> genişlik * $ kaynak_yükseklik) / $ bu-> bilgi-> yükseklik); $ yükseklik = $ kaynak_yükseklik; kırmak; case "crop": if ($ bu-> bilgi-> genişlik> $ bu-> bilgi-> yükseklik) ($ genişlik = yuvarlak (($ bu-> bilgi-> genişlik * $ kaynak_yükseklik) / $ bu-> bilgi -> yükseklik); $ yükseklik = $ kaynak_yükseklik;) else ($ genişlik = $ kaynak_genişlik; $ yükseklik = yuvarlak (($ bu-> bilgi-> yükseklik * $ kaynak_genişlik) / $ bu-> bilgi-> genişlik);) kırmak; // Varsayılan olarak, sadece varsayılanı uzat: case "fit":) // Ölçeklemenin yapılıp yapılmayacağını kontrol edin geçiş ($ ölçeği) (// Resim belirtilen boyutlardan daha büyükse, "yukarı" durumunda hiçbir şey olmaz: if ($ genişlik< $this->bilgi-> genişlik && $ yükseklik< $this-> info-> yükseklik) ($ this;) break; // Resim belirtilen boyutlardan daha küçükse, "down" durumunda hiçbir şey olmaz: if ($ width> $ this-> info-> width && $ height> $ this-> info-> height) (dönüş $ bu;) ara; case "any": default: // Hiçbir şey yapmayın. Philonym) $ this-> target = $ this-> createTarget ($ genişlik, $ yükseklik); if (imagecopyreampled ($ this-> target, $ this-> source, 0, 0, 0, 0, $ width, $ height, $ this-> info-> width, $ this-> info-> height)) ( $ bu-> kaynak = $ bu-> hedef; $ bu-> bilgi-> genişlik = $ genişlik; $ bu-> bilgi-> yükseklik = $ yükseklik; if ("kırpma" == $ uygun) (buna dön -> kırp ("merkez", "merkez", $ kaynak_genişliği, $ kaynak_yükseklik);)) şunu döndür $ this; ) / ** * Resmi kırpar * * @param mixed $ x Kırpma koordinatı x * @param mix $ y Kırpma koordinatı y * @param mix $ genişlik Kırpma genişliği * @param mix $ yüksekliği Kırpma yüksekliği * @dönüş nesnesi Görüntü * / genel işlev kırpma ($ x, $ y, $ genişlik, $ yükseklik) ($ x = $ this-> smartSize ($ x, "width") - $ genişlik / 2; $ y = $ this-> smartSize ($ y , "yükseklik") - $ yükseklik / 2; $ genişlik = $ bu-> smartSize ($ genişlik, "genişlik"); $ yükseklik = $ bu-> smartSize ($ yükseklik, "yükseklik"); $ bu-> hedef = $ this-> createTarget ($ genişlik, $ yükseklik); if (imagecopyreampled ($ this-> target, $ this-> source, 0, 0, $ x, $y, $ width, $ height, $ width, $ yükseklik)) ($ bu-> kaynak = $ bu-> hedef; $ bu-> bilgi-> genişlik = $ genişlik; $ bu-> bilgi-> yükseklik = $ yükseklik;) dönüş $ bu;) / ** * Görüntüleri birleştirir * / genel işlev birleştirme (Görüntü $ görüntü, $ x, $ y, $ yüzde = 100) ($ x = $ this-> smartSize ($ x, "width"); $ y = $ this-> smartSize ( $ y, "height"); if (imagecopymerge ($ this-> source, $ image-> getSource (), $ x, $ y, 0, 0 , $ görüntü-> nesne () -> görüntü-> genişlik, $ görüntü-> nesne () -> görüntü-> yükseklik, yüzde $)) () bu $ döndür; ) / ** * Resmi kaydeder * / public function save ($ file = NULL, $ options = array()) ($ this-> target VEYA $ this-> target = $ this-> source; if (strpos ($) file , ".") VEYA $ file = $ this-> info-> file) ($ ext = pathinfo ($ file, PATHINFO_EXTENSION); $ ext = strtolower ($ ext);) else ($ ext = strtolower ($ dosya ); $ file = NULL;) switch ($ ext) (case "jpg": case "jpeg": $ options VEYA $ options = 90; imagejpeg ($ this-> target, $ file, $ options); break; case " gif ": imagecolortransparent ($ this-> target, imagecolorallocatealpha ($ this-> target, 0, 0, 0, 127)); imagealphablending ($ this-> target, YANLIŞ); imagesavealpha ($ this-> hedef, DOĞRU ) ; imagegif ($ this-> target, $ file); break; case "png": imagealphablending ($ this-> target, FALSE); imagesavealpha ($ this-> target, TRUE); if (is_numeric ($ seçenekleri) ) ($ kalite = $ seçenekler; $ filtreler = PNG_NO_FILTER;) başka ($ kalite = isset ($ seçenekler ["kalite"])? $ seçenekler ["kalite"]: 9; $ filtreler = isset ($ seçenekler ["filtreler"])? $ seçenekler ["filtreler"]: PNG_NO_FILTER; ) imagepng ($ bu-> hedef, $ dosya, $ kalite, $ filtreler); kırmak; ) $ this-> yok et (); ) / ** * Çıktı resmi * / genel işlev çıktısı ($ biçimi, $ seçenekleri) ($ bu-> kaydet ($ biçimi, $ seçenekleri);))

Sistemde nasıl çalışır? Bu kadar kod ne için?

Görmek:

$ resim = yeni Resim ("1.jpg"); $ resim-> yeniden boyutlandır (200.200, "genişlik") -> kırp (200.200) -> kaydet ("2, jpg);

Anlıyor musun? Gerekli tüm formatlarla otomatik olarak çalışır. Gerekirse işlevsellik genişletilebilir.

Sizin için ev ödevi, yerel makinede yukarıda belirtilenleri (sınıfıma kadar) yapıyor olacak. İstenirse ve parametrelerle deneme zamanı.

9 yıl önce

Selamlar,
degrade bir görüntü oluşturmak için bir işlev yaptım.

tanım:
gradyan (int resim_genişliği, int resim_yüksekliği,
int start_red, int start_green, int start_blue,
int end_red, int end_green, int end_blue,
bool dikey)

işlev:
işlev gradyanı ($ image_width, $ image_height, $ c1_r, $ c1_g, $ c1_b, $ c2_r, $ c2_g, $ c2_b, $ dikey = yanlış)
{
// ilk: cast tipini yazalım;
$ image_width = (tam sayı) $ image_width;
$ image_height = (tamsayı) $ image_height;
$ c1_r = (tam sayı) $ c1_r;
$ c1_g = (tam sayı) $ c1_g;
$ c1_b = (tam sayı) $ c1_b;
$ c2_r = (tam sayı) $ c2_r;
$ c2_g = (tam sayı) $ c2_g;
$ c2_b = (tam sayı) $ c2_b;
$ dikey = (bool) $ dikey;

// bir görüntü oluştur
$ resim = imagecreatetruecolor ($image_width, $image_height);

// degradeyi yap
için ($ ben = 0; $ ben< $image_height ; $i ++)
{
$ color_r = kat ($ i * ($ c2_r - $ c1_r) / $ image_height) + $ c1_r;
$ color_g = kat ($ i * ($ c2_g - $ c1_g) / $ image_height) + $ c1_g;
$ color_b = kat ($ i * ($ c2_b - $ c1_b) / $ image_height) + $ c1_b;

$ color = ImageColorAllocate ($ resim, $ color_r, $ color_g, $ color_b);
görüntü çizgisi ($ görüntü, 0, $ ben, $ görüntü_genişliği, $ ben, $ renk);
}

# Tüm rakamları ve resmi yazdırır ve hafızayı boşaltır
başlık ("İçerik türü: resim / png");

if ($ dikey) ($ görüntü = görüntü döndürme ($ görüntü, 90, 0);)
ImagePNG ($ görüntü);
imagedestroy ($ görüntü);
}
?>

7 yıl önce

Komut dosyanızın bir yerde çıktı arabelleğe alma işlevlerini kullanması durumunda, imagepng () gibi bir işleve sahip bir görüntü çıktısı almadan önce ilk olarak (ob_clear () ile) arabelleği temizlemeniz gerekir.

Ve ob_end_flush() - işlevini kullanarak bir görüntünün çıktısını aldıktan sonra hiçbir arabellek gönderilmeyeceğinden emin olmalısınız.

Ayrıca, bir arabellek daha önce bir yerde temizlenip temizlenmediğini kontrol etmelisiniz. Bu, headers_sent () - işlevi kullanılarak yapılabilir.

İşte tam çözüm:

if (headers_sent ()) (
ölmek ( "Başlıklar senaryomun içinde bir yere gönderildi");
}

Ob_clean(); // Tamponu temizler

Başlık ("İçerik türü: resim / png");
imagepng ($ img, NULL, 0, NULL);

Ob_end_flush(); // Şimdi başlığı ve resmi gönderiyoruz ve bundan sonra sayfa yürütmenin sonuna kadar (olası kapatma işlevleri ve __destruct () - yöntemleri dahil) hiçbir şeyin gönderilmeyeceğinden emin oluyoruz
?>

10 yıl önce

Biliyor musun, belki söylemeye gerek yok ama buraya bir not bırakayım dedim. Görüntüleri yeniden boyutlandırmak için kod geliştirirken GD kullanmamak en iyisidir. Mevcut GD metodolojilerini kullanırken, bir görüntüden içerik okuyor ve onu manipüle ediyorsunuz. O içeriği yepyeni bir dosyaya yazarak EXIF ​​​​verilerini kaybedersiniz.

EXIF verilerini saklamak istediğiniz amaçlar için, PECL Imagick uzantısını derlemeniz ve kullanmanız önerilir. Doğrudan yerleşik harika yeniden boyutlandırma yöntemlerine sahiptir ve EXIF ​​verileri korunur.

10 yıl önce

Çıktıyı bir dosya veya tarayıcı aracılığıyla proxy olmadan GD'den bir metin dizesine göndermek istiyordum.

Ben bir çözüm buldum.

Bu kod, ob_start () ve ob_end () işlevleri arasındaki çıktıyı ob_get_contents () içine arabelleğe alır.

Aşağıdaki örneğe bakın

// Bu örnek için bir test kaynağı görüntüsü oluşturun
$ im = imagecreatetruecolor (300, 50);
$ text_color = imagecolorallocate ($ im, 233, 14, 91);
imagestring ($ im, 1, 5, 5, "Basit Bir Metin Dizisi", $ text_color);

// arabelleğe almayı başlat
ob_start();
// çıktı jpeg (veya seçilen herhangi bir başka) format ve kalite
imagejpeg ($ im, NULL, 85);
// çıktıyı dizgeye yakala
$ içerik = ob_get_contents();
// yakalamayı sonlandır
ob_end_clean();

// düzenli ol; hafızayı boşalt
imagedestroy ($ im);

// son olarak (örnek için) diziyi bir dosyaya yazıyoruz
$ fh = fopen ("./temp/img.jpg", "a +");
fwrite ($ fh, $ içindekiler);
fclose ($ fh);
?>

Bu yazıda, üçüncü taraf bileşenlere ve çerçevelere başvurmadan PHP kullanarak sunucuya görüntü yükleme mekanizmasını ayrıntılı olarak analiz edeceğiz. Görüntüleri yalnızca kullanıcının yerel makinesinden değil, aynı zamanda bir bağlantı aracılığıyla uzak dosyalardan da güvenli bir şekilde nasıl indireceğimizi öğreneceğiz. Kodu daha hızlı okuyabilmeniz ve bir yöntemden diğerine atlamamanız için tüm kod örneklerini prosedürel bir tarzda yazacağım. Kılavuzun telif hakkı tamamen saklıdır ve herhangi bir akademik sunum iddiasında bulunmaz..

§1. Genel İlkeler

Sunucuya bir görüntü yükleme sırasının tamamı aşağıdaki gibi görüntülenebilir: php.ini ayarıdosyayı algüvenlik kontrolüveri doğrulamaDiske kaydet... Bir kullanıcının bilgisayarından veya bir URL'den bir resim indirme işlemi, bir resim elde etme ve kaydetme yöntemi dışında farklı değildir. Sunucuya bir resim yüklemek için genel şema aşağıdaki gibidir:

Görüntüyü URL ile doğrulamak için, cURL onu daha sonraki işlemler için bir değişkene indireceğinden getimagesizefromstring() işlevini kullanacağız.

Görüntüleri sunucuya yüklediğimiz için, belirli parametrelerini kontrol etmek iyi olur: Genişlik, yükseklik, bir çeşit resimler, boyut bayt cinsinden dosya. Bu, uygulamanızın mantığına bağlıdır, ancak netlik adına, bu eğitimde yukarıda açıklanan tüm parametreleri kontrol edeceğiz.

§2. Güvenlik düzenlemeleri

Görüntüleri indirmenin güvenliği, yabancı kodun sunucuya girmesini ve onu yürütmesini engellemekten geçer. Pratikte, PHP uygulamalarında en savunmasız nokta görüntüleri yüklemektir: kabuk komut dosyaları isabet, ikili dosyalara kötü amaçlı kod yazma, EXIF verilerinin değiştirilmesi... Çoğu bilgisayar korsanlığı yönteminden kaçınmak için aşağıdaki kurallara uymanız gerekir:

a Olumsuz $ _FILES'den gelen verilere güven;
B Olumsuz getimagesize () işlevinden görüntünün MIME türünü kontrol edin;
yüklenen dosyada yeni bir ad ve uzantı oluşturun;
d resimler içeren klasörde PHP komut dosyalarının yürütülmesini yasaklayın;
NS Olumsuz gereksinim ve içerme yoluyla özel verileri ekleyin;
Yani, $ _FILES için is_uploaded_file() ve move_uploaded_file() kullanın.

"Güvenlik Kuralları"nı tamamlayacak bir şeyiniz varsa, bu kılavuzdaki yorumlarda güvenlikle ilgili makalelere veya bağlantılara yorumlarınızı bırakın, ben de bunları bu paragrafta yayınlayacağım.

§3. Php.ini yapılandırması

PHP, herhangi bir dosyanın yükleme işlemine belirli yapılandırma değerleri eklemenize olanak tanır. Bunu yapmak için php.ini dosyasındaki blokları bulmanız gerekir “ Kaynak Sınırları», « Veri işleme" ve " Dosya Yüklemeleri”Ardından aşağıdaki değerleri gerektiği gibi düzenleyin:

; Saniye cinsinden maksimum komut dosyası yürütme süresi max_execution_time = 60 ; Bir komut dosyası tarafından maksimum bellek tüketimi memory_limit = 64M ; POST yöntemiyle gönderilen izin verilen maksimum veri boyutu post_max_size = 5 milyon ; Dosya yükleme izni file_uploads = Açık ; İndirme sırasında dosyaların saklandığı klasör upload_tmp_dir = ana sayfa / kullanıcı / geçici ; Maksimum yükleme dosyası boyutu upload_max_filesize = 5 milyon ; İzin verilen maksimum eşzamanlı yüklenen dosya sayısı max_file_uploads = 10

Belirtilen değerlere göre, kullanıcı bir seferde ondan fazla dosya indiremez ve her dosya 5 MB'ı geçmemelidir. Bloktan parametreler " Kaynak Sınırları»Uzak bir dosya yüklemek için daha fazla gereklidir, çünkü cURL yardımıyla içeriği bir değişkene indireceğiz ve ihtiyacımız olan kriterlere göre kontrol edeceğiz ve bu ek zaman ve bellek gerektirir.

php.ini yapılandırma dosyası her zaman geliştirilmekte olan web uygulamasının iş mantığına göre yapılandırılmalıdır. Örneğin, 5 MB'a kadar on dosyadan fazlasını yüklemeyi planlıyoruz, bu da ~ 50 MB belleğe ihtiyacımız olduğu anlamına geliyor. Ayrıca max_execution_time'da yeterli bir script yürütme süresi ayarlamak ve kullanıcıları hatalarla korkutmamak için yerel makineden ve referans olarak bir dosyanın maksimum indirme süresini bilmemiz gerekir.

§4. Formdan resim yükleme

Şimdi sunucuya birkaç dosya yüklemeyi düşünmeyeceğiz, ancak yalnızca bir dosya örneğinde yüklemenin çok mekaniklerini analiz edeceğiz. Bu nedenle, bir kullanıcının bilgisayarından bir resim yüklemek için, bir HTML formu kullanarak POST yöntemini kullanarak bir PHP komut dosyasına bir dosya göndermeniz ve verileri kodlamak için bir yöntem belirtmeniz gerekir. enctype = "çok parçalı / form verisi"(bu durumda, veriler kodlanmaz ve bu değer yalnızca ikili dosyaları göndermek için kullanılır). Aşağıdaki form ile çalışacağız:

Dosya seçim kutusu için adını kullanıyoruz isim = "yükle" HTML formumuzda, ancak herhangi bir şey olabilir. Dosyayı PHP betiği file-handler.php dosyasına gönderdikten sonra, süper küresel değişken kullanılarak engellenebilir $ _FILES ["yükle"] dizide dosya hakkında bilgi içeren aynı ada sahip:

Dizi ( => resim.jpg // orijinal dosya adı => resim / jpeg // MIME dosya türü => ana sayfa \ kullanıcı \ temp \ phpD07E.tmp // ikili dosya => 0 // hata kodu => 17170 // bayt cinsinden dosya boyutu)

Tüm veriler değil $ _FILES Güvenebilirsiniz: Bir dosyanın MIME türü ve boyutu, HTTP yanıtından oluşturuldukları için sahte olabilir ve arkasında tamamen farklı bir dosya gizlenebileceği için dosya adındaki uzantıya güvenilmemelidir. . Yine de, daha sonra dosyamızın doğru yüklenip yüklenmediğini ve hiç yüklenip yüklenmediğini kontrol etmemiz gerekiyor. Bunu yapmak için, içindeki hataları kontrol etmeniz gerekir. $ _FILES ["yükleme"] ["hata"] ve dosyanın işlevi kullanılarak POST yöntemi kullanılarak yüklendiğinden emin olun. is_uploaded_file()... Bir şey plana göre gitmezse, hatayı ekranda gösteririz.

// Kolaylık sağlamak için değişkenlerin üzerine yaz$ filePath = $ _FILES ["yükleme"] ["tmp_name"]; $ errorCode = $ _FILES ["yükleme"] ["hata"]; // Hataları kontrol et if ($ errorCode! == UPLOAD_ERR_OK ||! is_uploaded_file ($ filePath)) ( // Hata adlarına sahip dizi$ errorMessages = [UPLOAD_ERR_INI_SIZE => "PHP yapılandırmasında dosya boyutu upload_max_filesize değerini aştı.", UPLOAD_ERR_FORM_SIZE => "Yüklenen dosyanın boyutu HTML biçimindeki MAX_FILE_SIZE değerini aştı.", UPLOAD_ERR_PARTIAL => "İndirme dosyası yalnızca kısmen alındı.", UPLOAD_ERR_NO_FILE => "Dosya yüklenmedi.", UPLOAD_ERR_NO_TMP_DIR => "Temp klasörü eksik.", UPLOAD_ERR_CANT_WRITE => "Dosya diske yazılamadı.", UPLOAD_ERR_EXTENSION => "PHP uzantısı dosya indirmeyi durdurdu.", ]; // Bilinmeyen bir hata ayarla$ bilinmeyenMesaj = "Dosya yüklenirken bilinmeyen bir hata oluştu."; // Dizide hata kodu yoksa hata bilinmiyor diyelim$ outputMessage = isset ($ errorMessages [$ errorCode])? $ errorMessages [$ errorCode]: $ bilinmeyenMesaj; // Hatanın adını göster die ($ çıktıMesajı); )

Bir saldırganın görüntüye gömülü kötü amaçlı kodu indirmesini önlemek için işleve güvenilemez getimagesize () bu da MIME türünü döndürür. İşlev, ilk argümanın geçerli bir görüntü dosyasına bağlantı olmasını bekler.... Bir resmin gerçek MIME türünü FileInfo uzantısı aracılığıyla belirleyebilirsiniz. Aşağıdaki kod, anahtar kelimenin varlığını kontrol edecektir. resim yüklediğimiz dosyanın türünde ve görünmüyorsa hata verecektir:

// Bir FileInfo kaynağı oluşturun$ fi = finfo_open (FILEINFO_MIME_TYPE); // MIME türünü al $ mime = (string) finfo_file ($ fi, $ filePath); );

Bu aşamada zaten MIME tip kontrolünden geçmiş tüm görselleri sunucumuza yükleyebiliyoruz ancak belirli özelliklere göre görsel yüklemek için bu görselleri fonksiyonu kullanarak doğrulamamız gerekiyor. getimagesize (), ki biz ikili dosyanın kendisini besleyeceğiz $ _FILES ["yükle"] ["tmp_name"]... Sonuç olarak, maksimum 7 elemanlı bir dizi elde edeceğiz:

Dizi (=> 1280 // genişlik => 768 // yükseklik => 2 // tür => genişlik = "1280" yükseklik = "768" // HTML için nitelikler => 8 // renk derinliği => 3 // renk modeli => resim / jpeg // MIME türü)

Görüntüyü daha fazla doğrulamak ve üzerinde çalışmak için yalnızca 3 değeri bilmemiz gerekir: Genişlik, yükseklik ve boyut dosya (boyutu hesaplamak için işlevi kullanın) Dosya boyutu () geçici bir klasörden ikili dosya için).

// Fonksiyonun sonucunu bir değişkene yaz$ resim = getimagesize ($ filePath); $ limitBytes = 1024 * 1024 * 5; $ limitGenişlik = 1280; $ limitYükseklik = 768; // Gerekli parametreleri kontrol edin if (filesize ($ filePath)> $ limitBytes) ölür ( "Resim boyutu 5 MB'ı geçmemelidir."); if ($ image> $ limitHeight) die(); if ($ image> $ limitWidth) die();

Tüm kontrollerden sonra indirilebilir dosyamızı resimli bir klasöre güvenle taşıyabiliriz. Bunu bir işlev aracılığıyla yapmak daha iyidir move_uploaded_file () bu güvenli modda çalışır. Dosyayı taşımadan önce unutmamalısınız görüntü türünden rastgele ad ve uzantı oluştur dosyamız için. İşte böyle görünüyor:

// MD5 karma değerine dayalı olarak yeni bir dosya adı oluşturun$ isim = md5_file ($ dosyayolu); // .jpeg'i .jpg'ye küçült// Resmi yeni bir ad ve uzantıyla / pics klasörüne taşıyın if (! move_uploaded_file ($ filePath, __DIR__. "/ resimler /". $ ad. $ biçimi)) (die ( "Görüntü diske yazılırken bir hata oluştu."); }

Bu, görüntünün indirilmesini tamamlar. Daha uygun dosya yükleme için, bir sarmalayıcı olan Symfony HttpFoundation paketinden UploadedFile sınıfını kullanabilirsiniz. $ _FILES ve ayrıca dosyayı aracılığıyla kaydeder move_uploaded_file ().

§5. Bir bağlantıdan resim yükleme

Bir bağlantıdan görüntü yüklemek için uzak kaynaklarla çalışan bir cURL kitaplığına ihtiyacımız var. Bunun yardımıyla içeriği bir değişkene indireceğiz. Bir yandan, bu amaçlar için uygun görünebilir file_get_contents (), ancak aslında, indirilen veri miktarını kontrol edemeyiz ve normalde meydana gelen tüm hataları işleyemeyiz. cURL'nin verileri doğru bir şekilde indirmesi için şunlara ihtiyacımız var: takip etmesine izin ver yönlendirmeler, kontrolü etkinleştir sertifika, belirtmek maksimum süre cURL çalışması (indirilen veri miktarı ve kaynakla ortalama çalışma hızı nedeniyle oluşur). Bir dosyanın bir değişkene doğru şekilde nasıl indirileceği, gerekli parametrelerle aşağıda gösterilmiştir:

// Bağlantıyı bir şekilde alın$ url = "https://site.ru/picture.jpg"; // Bağlantı url'sindeki HTTP'yi kontrol edin if (! preg_match ("/ ^ https?: / i", $ url) && filter_var ($ url, FILTER_VALIDATE_URL)) (öl ( "Uzak dosyaya geçerli bir bağlantı belirtin."); } // cURL'yi bağlantımızla çalıştırın$ ch = curl_init ($ url); // cURL için ayarları belirtin curl_setopt_array ($ ch, [ // cURL için maksimum çalışma süresini belirtin CURLOPT_TIMEOUT => 60, // Yönlendirmeleri takip etmeye izin ver CURLOPT_FOLLOWLOCATION => 1, // Sonucun bir değişkene yazılmasına izin verelim CURLOPT_RETURNTRANSFER => 1, // Veri yükleme göstergesini aç CURLOPT_NOPROGRESS => 0, // Tampon boyutunu 1 KB olarak ayarla CURLOPT_BUFFERSIZE => 1024, // İndirilen verileri saymak için bir fonksiyon yazın // Daha Fazlası: http://stackoverflow.com/a/17642638 CURLOPT_PROGRESSFUNCTION => fonksiyon ($ ch, $ dwnldSize, $ dwnld, $ upldSize, $ upld) ( // 5 MB'den fazla indirildiğinde cURL iptal edilecek if ($ dwnld> 1024 * 1024 * 5) (dönüş - 1;)), // Sertifika doğrulamasını aç (varsayılan olarak) CURLOPT_SSL_VERIFYPEER => 1, // Sertifikanın adını ve belirtilen ana bilgisayarla eşleşmesini kontrol edin (varsayılan olarak) CURLOPT_SSL_VERIFYHOST => 2, // Doğrulama sertifikasını belirtin // İndir: https://curl.haxx.se/docs/caextract.html CURLOPT_CAINFO => __DIR__. "/cacert.pem",]); $ ham = curl_exec ($ ch); // Verileri bir değişkene yükle$ bilgi = curl_getinfo ($ ch); // İşlem hakkında bilgi alın$ hata = curl_errno ($ ch); // Son hatanın kodunu yaz // cURL oturumunu sonlandır curl_close ($ ch);

Her şey yolunda giderse ve cURL 60 saniye içinde biterse, bağlantının içeriği bir değişkene indirilecektir. $ ham... Ek olarak, fonksiyon curl_getinfo() uzak kaynaklarla çalışmayı analiz etmek için ek bilgi alabileceğimiz, yapılan istekle ilgili bilgileri döndürür:

Dizi ( => resim / jpeg // Content-Type'tan MIME-type => 200 // son HTTP kodu => 0 // yönlendirme sayısı => 0.656 // cURL'nin toplam çalışma süresi => 0.188 // ana bilgisayara bağlanma zamanı => 4504 // alınan verinin gerçek boyutu => 4504 // Content-Length'den veri boyutu /* ... */ )

Ardından, herhangi bir hata olup olmadığını kontrol etmemiz gerekiyor. curl_errno () ve kaynağın 200'e eşit bir HTTP kodu döndürdüğünden emin olun, aksi takdirde bu URL'de hiçbir şey bulunamadığını söyleyeceğiz. Tüm kontrollerden sonra, değişken $ ham transfer getimagesizefromstring() ve bir formdan resim yükleme durumunda olduğu gibi yerleşik şemaya göre çalışıyoruz.

Content_type, http_code, download_content_length değerleri alınan HTTP başlıklarına göre oluşturulduğundan, curl_getinfo'ya () %100 güvenemeyeceğimizden, verileri alma anında dosya boyutunu doğruladığımızı lütfen unutmayın. Tüm dosyayı indirmek ve ardından bayt sayısını kontrol etmek çok fazla zaman ve bellek alacaktır. Bu nedenle, alınan verilerin boyutunu CURLOPT_PROGRESSFUNCTION seçeneğini kullanarak kontrol ettik: cURL limitimizden daha fazla veri alır almaz çalışmayı durduracak ve bir CURLE_ABORTED_BY_CALLBACK hatası verecektir.

// cURL hatalarını ve dosya kullanılabilirliğini kontrol edin if ($ error === CURLE_OPERATION_TIMEDOUT) ölür ( "Bekleme sınırı aşıldı."); if ($ error === CURLE_ABORTED_BY_CALLBACK) ölür ( "Boyut 5 MB'ı geçmemelidir."); if ($ info ["http_code"]! == 200) die ( "Dosya mevcut değil."); // Bir FileInfo kaynağı oluşturun$ fi = finfo_open (FILEINFO_MIME_TYPE); // $ raw içeriğini kullanarak MIME türünü alın$ mime = (string) finfo_buffer ($ fi, $ ham); // FileInfo kaynağını kapatın finfo_close ($ fi); // Görsel anahtar kelimesini kontrol edin (resim / jpeg, resim / png, vb.) if (strpos ($ mime, "image") === false) die ( "Yalnızca resimler yüklenebilir."); // Görüntü verilerini içeriğinden alın$ resim = getimagesizefromstring ($ ham); // Resimler için limitleri ayarla$ limitGenişlik = 1280; $ limitYükseklik = 768; // Gerekli parametreleri kontrol edin if ($ image> $ limitHeight) ölür ( "Görüntü yüksekliği 768 pikseli geçmemelidir."); if ($ image> $ limitWidth) ölür ( "Görüntü genişliği 1280 noktayı geçmemelidir."); // Resmin MD5 karmasından yeni bir ad üret$ isim = md5 ($ ham); // Görüntü türüne göre dosya uzantısı oluştur$ extension = image_type_to_extension ($ görüntü); // .jpeg'i .jpg'ye küçült$ biçimi = str_replace ("jpeg", "jpg", $ uzantı); // Resmi yeni bir ad ve uzantıyla / pics klasörüne kaydedin if (! file_put_contents (__DIR__. "/ resimler /". $ ad. $ biçimi, $ ham)) (die ( "Görüntü diske kaydedilirken bir hata oluştu."); }

Görüntüyü diske kaydetmek için kullanabilirsiniz. file_put_contents () içeriği bir dosyaya yazacak. İşlev aracılığıyla yeni bir dosya adı oluşturacağız md5 (), ve uzantıyı şuradan yapacağız image_type_to_extension ()... Artık bağlantıdan herhangi bir resmi indirebiliriz.

§6. Çoklu Dosya Seçimini Yapılandırma

Bu bölümde, kullanıcının yerel makinesinden ve uzak bağlantılardan aynı anda birkaç görüntünün nasıl indirileceğini analiz edeceğiz. Bağlantıları göndermek için kullanıyoruz $ _POST ve etiketi kullanarak tüm verileri ona iletin metin alanı... Formdan dosya yüklemek için çalışmaya devam edeceğiz. $ _FILES... Yeni HTML formumuz eskisinden biraz farklı olacak.

Dosya seçimi alan adının sonunda isim = "yükle" küme parantezleri ve bir öznitelik eklendi çoklu bu, tarayıcının birden fazla dosya seçmesine izin verir. php.ini'de herhangi bir hata yoksa tüm dosyalar tekrar geçici klasöre yüklenecektir. onları araya sokabilirsin $ _FILES, ancak bu sefer süper küresel, bir dizideki verileri işlemek için garip bir yapıya sahip olacak. Bu görev, diziyle yapılan küçük değişikliklerle çözülür:

// $ _FILES yapısını değiştir foreach ($ _FILES ["upload"] as $ key => $ value) (foreach ($ değeri olarak $ k => $ v) ($ _FILES ["upload"] [$ k] [$ key] = $ v; ) // Eski anahtarları sil unset ($ _FILES ["yükleme"] [$ anahtar]); ) // Tüm resimleri sırayla yükle foreach ($ _FILES ["upload"] as $ k => $ v) ( // Bir seferde bir dosya yükle$ _FILES ["yükleme"] [$ k] ["tmp_name"]; $ _FILES ["yükleme"] [$ k] ["hata"]; )

URL'ye göre birkaç resim indirmek için bağlantılarımızı ileteceğiz metin alanı adı ile isim = "yükle", bir boşlukla veya yeni bir satırda ayrılabilecekleri yer. İşlev preg_split tüm verileri ayrıştıracak $ _POST ["yükle"] ve döngü içinde dolaşmanız ve her geçerli URL'yi işleyiciye göndermeniz gereken bir dizi oluşturacaktır.

$ data = preg_split ("/ \ s + /", $ _POST ["yükleme"], - 1, PREG_SPLIT_NO_EMPTY); foreach ($ veri olarak $ url) ( // Resmi URL'ye göre doğrulayın ve yükleyin }

Görüntüler olmadan internet oldukça sıkıcı olacak. Bununla birlikte, web siteniz için yüzlerce veya binlerce görselin bakımı ve yönetimi baş ağrısına neden olabilir. Site tasarımınız değiştikçe, tüm resimlerinizi değiştirmeniz gerekebilir - örneğin, tüm resimlerinizi gri tonlamaya dönüştürün veya orijinal boyutlarının %50'sine yeniden boyutlandırın. Ayrıca farklı görüntüleri sıkıştırabilir veya kırpabilirsiniz. Bunu manuel olarak yapmak zaman alıcıdır ve hataya açıktır, ancak biraz programlama bilgisi ile otomatikleştirilebilir.

Bu dersimizde PHP'deki GD (Graphic Draw) kütüphanesini öğreneceğiz. Bu kitaplığın görüntüleri yeniden boyutlandırma, kırpma, döndürme veya filtreleme yoluyla işlemek için nasıl kullanılabileceğini göreceksiniz.

GD nedir?

PHP, ziyaretçilerinize HTML mesajları göndermekten çok daha fazlasını yapabilir. Örneğin, görüntüleri manipüle etme yeteneğine sahiptir. Sadece bu değil, aynı zamanda sıfırdan kendi resimlerinizi oluşturabilir ve ardından bunları kaydedebilir veya kullanıcılara sunabilirsiniz.

PHP, Graphic Draw'un kısaltması olan GD kitaplığını kullanarak neredeyse tüm temel görüntü işleme ihtiyaçlarınızı karşılayabilir.

Kurulum

Windows kullanıyorsanız, dosyayı ekleyebilirsiniz. php_gd2.dll uzantısı olarak php.ini... XAMPP gibi bir şey kullanıyorsanız, dosyayı bulacaksınız. php_gd2.dll katalogda xampp\php\ext... Ayrıca phpinfo() işlevini kullanarak GD'nin sisteminizde kurulu olup olmadığını kontrol edebilirsiniz; ... Sonuca bakarsanız, aşağıdakine benzer bir şey bulacaksınız.

Kurulum hakkında daha fazla bilgi edinmek için Gereksinimler ve Kurulumlar sayfasını da ziyaret edebilirsiniz.

PHP GD ile Görüntü Oluşturma

PHP ile imajları manipüle etmenin ilk adımı onları imaj kaynağı olarak belleğe yüklemektir. Bu, farklı formatlar için farklı işlevler kullanılarak elde edilebilir. Bu işlevlerin tümü birbirine çok benzer adlara sahiptir, bu nedenle hatırlamaları kolaydır.

Yeni bir görüntü oluşturma

Değiştirmek istediğiniz görüntünün orijinal kaynağına sahip değilseniz, imagecreatetruecolor () işlevi kullanışlıdır. İki tamsayı parametresi alır: genişlik ve yükseklik. Her şey plana göre giderse görüntü varlığını döndürür. Döndürülen görüntü kaynağı, temel olarak verilen genişlik ve yüksekliğe sahip siyah bir görüntüdür.

Bir resim dosyası yükleme

Halihazırda bir yerde depolanmış görüntülerle çalışmayı planlıyorsanız, imagecreatefromjpeg(), imagecreatefrompng() ve imagecreatefromgif() gibi işlevleri kullanmak kullanışlı olacaktır. Yüklenen görüntü dosyasındaki tüm verilerle bir görüntü kaynağı oluşturacaklar. Bu işlevler, URL veya dosya yolu gibi yüklenecek görüntünün konumunu belirten tek bir parametre alır.

Bir dizeden görüntü oluşturma

GD kitaplığı ayrıca PHP'deki imagecreatefromstring() işlevini kullanarak bir dizeden görüntüler oluşturmanıza olanak tanır. imagecreatefromstring()'den önce verilen dize için base64_decode() kullanmanız gerekeceğini unutmayın. İşlev, görüntü türünün JPG, PNG, GIF veya desteklenen başka bir biçim olup olmadığını otomatik olarak algılayabilir.

Bir görüntüyü döndürme, ölçekleme, kırpma ve çevirme

Bir görüntü varlığı üzerinde gerçekleştirebileceğiniz bazı yaygın işlemler döndürme, ölçekleme, kırpma ve çevirmedir.

döndürme

Komut dosyasına önceden yüklemiş olduğunuz bir görüntüyü imagerotate () işlevini kullanarak döndürebilirsiniz. Görüntünün merkezini dönme merkezi olarak kullanarak görüntüyü belirli bir açıda döndürür. Açı, kayan nokta değeri olarak temsil edilir ve PHP, onu dönüş açısı değeri olarak kabul eder. Bazen döndürülen görüntü, orijinal sürüme kıyasla farklı boyutlara sahip olabilir. Bu, döndükten sonra biraz açık alan elde edeceğiniz anlamına gelir. imagerotate () işlevinin üçüncü parametresi, döndürmeden sonra boş alanın arka plan rengini ayarlamak için kullanılabilir.

ölçekleme

GD kütüphanesini kullanarak bir görüntüyü ölçeklendirmek çok kolaydır. Görüntü kaynağının yanı sıra genişlik ve yüksekliği de imagescale () işlevine iletmeniz yeterlidir. Yüksekliği düşürürseniz, GD, en-boy oranını korurken görüntüyü belirtilen genişliğe ölçeklendirir. Ayrıca görüntü ölçekleme modunu da belirleyebilirsiniz. IMG_NEAREST_NEIGHBOUR, IMG_BILINEAR_FIXED, IMG_BICUBIC, vb. olarak ayarlanabilir. Hatırlanması gereken en önemli şey, bu işlevin, orijinal olanı değiştirmek yerine, ölçeklenen görüntünün yeni bir kaynağını döndürmesidir.

Budama

GD'deki imagecrop() işleviyle herhangi bir görüntü kaynağını kırpabilirsiniz. İlk parametre görüntünün orijinal kaynağıdır ve ikinci parametre, kırpma kutusunun konumunun boyutunu belirleyen x, y, genişlik ve yükseklik tuşlarına sahip bir ilişkisel dizidir.

Yukarıdaki kelebek resmi aşağıdaki kod kullanılarak kırpılmıştır:

$ im_php = imagecreatefromjpeg ("yol / görüntü / görüntü"); $ boyut = min (imagesx ($ im_php), imagesy ($ im_php)); $ im_php = imagecrop ($ im_php, ["x" => $ boyut * 0.4, "y" => 0, "genişlik" => $ boyut, "yükseklik" => $ boyut]); $ im_php = görüntü ölçeği ($ im_php, 300);

Temel olarak, en küçük kenarın uzunluğunu $ size değişkeninde saklarız. Bu değişken daha sonra kırpma dikdörtgenimizin kenarlığını tanımlamak için kullanılır. Son olarak, görüntü yalnızca 300 piksel genişliğinde ve uzunluğunda olacak şekilde küçültülür. Bu bize kare bir görüntü verir.

Resimleri çevir

Görüntüler, imageflip () işlevi kullanılarak yatay, dikey veya her iki yönde çevrilebilir. İlk parametre olarak çevirmek istediğiniz görüntü kaynağını ve ikinci parametre olarak çevirme modunu alır. Çevirme modu IMG_FLIP_HORIZONTAL, IMG_FLIP_VERTICAL veya IMG_FLIP_BOTH olarak ayarlanabilir.

Yukarıdaki resimde sol üstteki resim orijinaldir. Sağ üstteki resim IMG_FLIP_HORIZONTAL kullanılarak, sol alttaki resim IMG_FLIP_VERTICAL kullanılarak ve sağ alttaki resim IMG_FLIP_BOTH kullanılarak oluşturuldu. ( Pixabay'den kuzgun görüntü.)

Bir görüntüye filtre uygulama

GD ayrıca, önceki görüntülerden işlevler kullanılarak yüklenen farklı görüntü kaynaklarına filtre uygulayabilen çok kullanışlı bir görüntü filtresi () işlevine sahiptir. Bu fonksiyon, uygulanan filtreye bağlı olarak farklı parametreler alabilir.

İlk olarak, uygulamak istediğiniz filtrenin adını ve görüntü varlığını belirtin. Bunu, belgelerde belirtilen önceden tanımlanmış 12 filtre türünden birine ayarlayabilirsiniz.

  • IMG_FILTER_NEGATE: görüntüdeki renkleri tersine çevirir (negatif olarak değişir)
  • IMG_FILTER_GRAYSCALE: görüntüden rengi kaldırır
  • IMG_FILTER_BRIGHTNESS: görüntüyü daha parlak veya daha koyu yapar
  • IMG_FILTER_CONTRAST: Resmin kontrastını artırır
  • IMG_FILTER_COLORIZE: görüntüyü seçilen renge boyar
  • IMG_FILTER_EDGEDETECT: Resmin kenarlarını vurgular
  • IMG_FILTER_EMBOSS: Kenar algılamaya benzer, ancak her kenara yükseltilmiş bir görünüm verir
  • IMG_FILTER_GAUSSIAN_BLUR: Gauss yöntemini kullanarak görüntüyü bulanıklaştırır
  • IMG_FILTER_SELECTIVE_BLUR: Seçici yöntemi kullanarak görüntüyü bulanıklaştırır
  • IMG_FILTER_MEAN_REMOVAL: stilize edilmiş bir görüntü yaratmanın etkisi
  • IMG_FILTER_SMOOTH: Resmin pürüzlü kenarlarını düzeltir
  • IMG_FILTER_PIXELATE: resmi pikselli hale getirir

NEGATE, GRAYSCALE, EDGE_DETECT ve EMBOSS gibi bazı filtreler ek verilere ihtiyaç duymaz. BRIGHTNESS, CONTRAST ve SMOOTH gibi diğer filtreler, son görüntüdeki parlaklık, kontrast veya pürüzsüzlük miktarını belirleyen ek bir parametre alabilir. PIXELATE parametresi, iki ek parametre belirlemenizi sağlar: blok boyutu ve pikselleştirme modu. Son olarak, COLORIZE filtresi kırmızı, yeşil ve mavi bileşenlerin yanı sıra alfa kanalı için değerleri tanımlayan dört parametre alır.

Sol üst köşedeki resim orijinaldir. Sağ üstteki resim RENKLENDİRME filtresi kullanılarak, sol alttaki resim GRAYSCALE filtresi kullanılarak ve sağ alttaki resim PARLAKLIK filtresi kullanılarak oluşturulmuştur. (Bu kelebek resmi Pixabay'de bulundu.)

Resimlerle çalışmak için diğer kullanışlı işlevler

Ayrıca zaman zaman faydalı olabilecek diğer bazı genel GD işlevlerinin de farkında olmalısınız.

Görüntü boyutlarını alma

imagesx () ve imagesy () işlevlerini kullanarak bir görüntü kaynağının genişliğini ve yüksekliğini belirleyebilirsiniz.

getimagesize () adlı başka bir işlev, bir görüntünün türüyle birlikte genişliğini ve yüksekliğini almak için de kullanılabilir. Bu işlev, genişlik, yükseklik ve en boy oranını tanımlayan öğeler içeren bir dizi döndürür. Dizinin ilk iki öğesi genişlik ve yüksekliği tanımlar ve üçüncü öğe dosya biçimini tanımlayan bir sabit içerir: IMAGETYPE_PNG, IMAGETYPE_GIF, vb. öğelerinden biri.

Bir görüntüyü kaydetme

Görüntüde gerekli tüm değişiklikleri yaptıktan sonra, büyük olasılıkla onu tarayıcıya çıkarmak veya bir dosya olarak kaydetmek isteyeceksiniz. Zaten imagejepg (), imagepng () veya imagegif () gibi GD'nin çıktı işlevlerinden birini kullanmanız gerekecek. Görüntü kaynağınızı bu çıktı işlevlerinden birine ileteceksiniz ve görüntüyü bir dosyaya kaydetmek istiyorsanız dosya adını da vereceksiniz. Çıktı görüntüsünün kalitesini, görüntünün türüne bağlı olarak isteğe bağlı bir üçüncü parametreyle de kontrol edebilirsiniz.

Bir dizindeki tüm görüntüleri yeniden boyutlandırma

Bir şeyler yapmak için öğrendiklerimizi uygulamaya koyalım. Bu bölümde, belirli bir dizindeki tüm JPEG görüntülerini 640 piksel genişliğinde yeniden boyutlandıracağız. Yükseklik, orijinal görüntünün boyutlarına göre otomatik olarak hesaplanacaktır.

Değiştirilen görüntüleri adlı yeni bir klasöre kaydedeceğiz. Yeniden boyutlandırıldı... Bu durumda tüm orijinal görüntüler aynı boyutlara sahiptir, ancak kod, farklı boyut ve orantılara sahip görüntülerle doğru şekilde çalışacaktır.

$ dizin = "Doğa /"; $ görüntüler = glob ($ dizini. "*. jpg"); foreach ($ resim olarak $ resim) ($ im_php = imagecreatefromjpeg ($ resim); $ im_php = resim ölçeği ($ im_php, 640); $ new_height = imagesy ($ im_php); $ new_name = str_replace ("- 1920x1080", "- 640x ". $ New_height, basename ($ image)); imagejpeg ($ im_php, $ directory." Yeniden boyutlandırılmış /".$ new_name);)

Yukarıdaki kodda, uzantılı tüm görüntüleri bulmak için glob () işlevini kullanarak başlayacağız. .jpg adlı bir dizinde Doğa... Görüntü dosyaları bir dizide depolanır ve bunları birer birer yineleriz.

Değiştirmek istediğimiz tüm resimler JPEG olduğundan, bunları komut dosyasına yüklemek için imagecreatefromjpeg() işlevini kullanırız. Görüntü ölçeği () işlevi daha sonra görüntüyü belirli bir genişliğe yeniden boyutlandırmak için kullanılır - bizim durumumuzda 640 piksel. Yükseklik otomatik hesaplansın diye sabit bir yükseklik belirtmedik.

Orijinal görüntü dosyalarının her biri eklenmiş -1920x1080 boyutlarını belirtmek için dosya adlarına. Orijinal dosya adında str_replace () kullanıyoruz ve değiştiriyoruz -1920X1080 yeni görüntü boyutuna

Son olarak, değiştirilen görselleri adlı bir klasöre kaydediyoruz. yeniden boyutlandır yeni dosya adlarıyla. Kaydedilen görüntü dosyasının kalitesini ayarlamak için imagejpeg () işlevine üçüncü bir parametre de iletebilirsiniz. Üçüncü parametre atlanırsa, görüntüler varsayılan kalite 75 ile kaydedilir.

Katalogdaki her görüntüye gri tonlama ve kontrast filtreleri uygulama

Bu sefer dizinimizde bulunan her bir görsele iki farklı filtre uygulayacağız ve dosya isminde herhangi bir değişiklik yapmadan nihai sonucu farklı bir dizine kaydedeceğiz. Kodun içine girelim ve daha sonra her bir fonksiyonun ne yaptığını açıklayacağım.

$ dizin = "Doğa /"; $ görüntüler = glob ($ dizini. "*. jpg"); foreach ($ resim olarak $ resim) ($ im_php = imagecreatefromjpeg ($ resim); resim filtresi ($ im_php, IMG_FILTER_GRAYSCALE); resim filtresi ($ im_php, IMG_FILTER_CONTRAST, -25); $ yeni_adı = temel ad ($ resim $); resimjpg , $ dizin. "Gri Tonlamalı /".$ yeni_adı);)

Gördüğünüz gibi dizinden resimler yüklüyoruz. Doğaönceki örnekte olduğu gibi. Ancak bu sefer yüklenen görüntü kaynağına filtre uygulamak için imagefilter() işlevini kullanacağız.

imagefilter() öğesinin orijinal görüntüyü değiştirdiğini ve işlemin başarısına veya başarısızlığına bağlı olarak DOĞRU veya YANLIŞ döndürdüğünü unutmayın. Bu, önceki bölümde kullandığımız ve ölçeklenmiş bir görüntü kaynağı döndüren imagescale () işlevinden farklıdır.

Unutulmaması gereken bir diğer önemli nokta ise kontrast filtresinin -100 ile 100 arasında değerler almasıdır. Negatif değerler daha fazla kontrast, pozitif değerler ise daha az kontrast anlamına gelir. Bu, bazı insanların beklediğinin tam tersi! 0 değeri görüntüyü değiştirmeden bırakır.

Öte yandan, parlaklık filtresinin minimum ve maksimum aralığı -255 ve 255'tir. Bu durumda negatif bir değer minimum parlaklığı, pozitif bir değer ise maksimum parlaklığı ifade eder.

basename() işlevini kullanarak dosya yolundan dosya adını alırız ve ardından imagejpeg() işlevini kullanarak görüntüyü kaydederiz.

Son düşünceler

Bu öğreticinin amacı, sizi PHP GD kitaplığıyla tanıştırmak ve hayatınızı kolaylaştırmak için tüm özelliklerini nasıl kullanacağınızı öğrenmekti. Eğitimin sonundaki örnekleri, kendi görüntüleme komut dosyalarınızı yazmak için bir kılavuz olarak kullanabilirsiniz. Örneğin, bir görüntüyü yalnızca, imagesx () işlevini kullanarak genişliğini belirleyerek belirtilen bir sınırdan büyükse yeniden boyutlandırabilirsiniz.

Bu özelliklerin tümü, görüntülerle çalışmanızı kolaylaştırmak için birçok olanak sunar ve sonuçta size çok zaman kazandıracaktır. Bu eğitimle ilgili herhangi bir sorunuz varsa, lütfen yorumlarda bana bildirin.