• 0
linux web man

الدرس الثاني عشر : التعامل مع الصور في لغة php

سؤال

السلام عليكم و رحمة الله وبركاته .
هذا الدرس من سلسلة الدروس التالية لتعلم لغة php .
درس عن التعامل مع الصور من خلال php .
ان المواقع الالكترونية اكثر من مجرد نص فهناك الصور التي تظهر في شعار الموقع الأيقونات ... الخ , وعدد من هذه الصور ثابتة واخرى يتم انشائها ديناميكيا ً . سنتعرف من خلال هذا الدرس عن كيفية انشاء وتعديل الصور واجراء العمليات المختلفة عليها (التحويل بين انواع الصور المختلفة , انشاء صور مصغرة , وضع العلامات المائية على الصور ...الخ) ; حيث تستخدم php المكتبة GD المفتوحة المصدر للقيام بتلك العمليات وهذه المكتبة تأتي بشكل افتراضي مع php وتوفر عدد لا بأس به من الدوال للتعامل مع الصور.
تتألف الصورة من مستطيل يحوي عددا ً من النقاط , وتسمى هذه النقاط بالبكسل pixel . ولكل نقطة لون معين , ويكون هذا اللون بشكل عام مُحدد بثلاث مكونات : اللون الأحمر , اللون الأخضر و اللون الأزرق و وتتراوح قيمهم بين 0 - 255 . وبعض صيغ الصور (كصيغة GIF) توفر عددا ً محدودا ً من الألوان في الصورة , بينما البعض الآخر يُوفر ما يُسمى الألوان الحقيقية ( 256 ^ 3 أو 16777216) .
يتم اعتبار مبدأ الأحداثيات عند التعامل مع الصور هو الزاوية العليا اليسرى و تتزايد قيمة العرض عند الإنتقال الى اليمين , وقيمة الطول عند الانتقال الى الأسفل كما في الصورة التالية :
post-268329-0-22890900-1363429613.jpg
انشاء الصور :
يتم انشاء مقبص للصورة اما بتحميل ملف الصورة المحفوظ في القرص الصلب الى الذاكرة او بانشاء صورة جديدة وذلك باستخدام الدوال التالية:
imagecreatetruecolor, imagecreatefromstring, imagecreatefromjpeg, imagecreatefrompng, imagecreatefromgif ..etc

الدوال imagecreatefromjpeg , imagecreatefrompng , imagecreatefromgif :
تعمل هذه الدوال الثلاث بنفس الآلية تقريبا حيث تقوم بانشاء مقبض للصورة عن طريق تحميل (load) الصورة من القرص , الشكل العام لاستعاء هذه الدوال هو :

$image = imagecreatefrompng('image.png');$image = imagecreatefromjpeg('image.jpg');$image = imagecreatefromgif('image.gif');

حيث تقبل هذه الدوال الثلاث وسيطا ًوحيدا ً هو مسار الصورة.

دالة imagecreatetruecolor :
تقوم بانشاء مقبض لصورة جديدة بالابعاد المُمررة اليها كوسائط , الشكل العام :

$image = imagecreatetruecolor($width, $height);

حيث الوسيط الاول هو عرض الصورة مقدرا بالبكسل والثاني هو ارتفاعها .
اخراج الصور :
ويتم ذلك باخراجها (output) إلى المتصفح مباشرة أو بحفظها بملف مستقل وذلك باستخدام الدوال imagepng, imagejpeg, imagegif حيث تعمل بنفس الالية مع اختلاف نوع الملف المُعاد

imagepng($image, $filename, $quality);imagegif($image, $filename, $quality);imagejpeg($image, $filename, $quality);

حيث الوسيط الأول هو مقبض الصورة والوسيط الثاني اسم الملف والثالث هو نسبة مئوية تُحدد جودة الصورة , الوسيطين الثاني والثالث اختياريين وفي حال لم يتم تحديد اسم الملف سيتم طباعة الصورة مباشرة الى المتصفح :

<?php$image = imagecreatetruecolor(200, 200);#save image file to deskimagepng($image, 'image.png');imagedestroy($image);?>


في المثال السابق سيتم حفظ صورة فارغة الى القرص باسم 'image.png' اما اذا اردنا اظهارها الى المتصفح فيجب علينا استخدام الدالة header و تحديد MIME type المُناسب لكل نوع من أنواع الصور لاخبار المتصفح ان البيانات المرسلة من الصفحة هي صورة :

 

<?php$image = imagecreatetruecolor(200, 200);#you canuse image/jpeg and image/gif for jpg and gif imagesheader('Content-Type: image/png');imagepng($image);imagedestroy($image);?>

- لكي تستطيع تحديد جودة الصورة بدون حفظ الصورة الى ملف فيمكن اسناد القيمة null لاسم الملف .
انشاء صورة من نص : تستخدم الدالة imagecreatefromstring لانشاء مقبض لصورة جاهزة دون الحاجة الى وجود ملف لها حيث يمكن ان تكون بيانات الصورة مخزنة ضمن قاعدة بيانات او باستخدام دالة base64_encode مثال :

 

<?php$base_64_data = '/9j/4AAQSkZJRgABAQEASABIAAD/2wBDADIiJSwlHzIsKSw4NTI7S31RS0VFS5ltc1p9tZ++u7Kfr6zI4f/zyNT/16yv+v/9////////wfD/////////////2wBDATU4OEtCS5NRUZP/zq/O////////////////////////////////////////////////////////////////////wAARCAAwADEDASIAAhEBAxEB/8QAGQAAAwEBAQAAAAAAAAAAAAAAAAMEAgUB/8QAJxAAAgIBAwMDBQEAAAAAAAAAAAECAxEEEjEhQVETMmEFIkJxgZH/xAAYAQEBAQEBAAAAAAAAAAAAAAADAgABBP/EABwRAAMBAAMBAQAAAAAAAAAAAAABAhESITEDQf/aAAwDAQACEQMRAD8A6gALnLLwjjeHUtCVqTwurMO/H4mJrdNbfcjx124z9r+CNp+FpT+k71Nm7duf6OlB7oJ+UQOKb6xw/kr09m+OHyjTXeHbXWoaAAIES6qbU1HtgXVJ5b7FdlUbPcsiNuyThxjgG0/RZpZg6mOI57tjCb11T7uAetqS6Zz4ElrCeLfhnW4goyXL6C9HY3fjyhN97unl9EuEN+nwbtc+yWCcTeiueMdnQAAEPOAu2vevDXDGAb0xzNTXYp9U2vKEfx/4dlxT5PPTj4J4jT9WlhHTXBVrMU2+clOnjGMGorCyZnQ3JuMmsja4KEMEzLT7IqtRoAAQg//Z';$image = imagecreatefromstring(base64_decode($base_64_data));header('Content-Type: image/png');imagepng($image);imagedestroy($image);?>


سيعرض المُتصفح صورة شبيهة بالصورة التالية :
post-268329-0-72567400-1363429415.txt
وقد تكون هذه الدالة مُفيدة عندما لا نعلم ما هو نوع الصورة المُراد إنشاء مقبض لها , كما يلي :

 

<?php//This can be image.png image.gif or any supported image format$image = imagecreatefromstring(file_get_contents('image.jpg'));?>

تعريف الألوان في الصور :
ويتم ذلك باستخدام الدالة imagecolorallocate بالشكل التالي :

$color = imagecolorallocate($image, $red, $green, $blue);

حيث تقبل هذه الدالة اربعة وسائط اجبارية هي على التوالي و بالترتيب : مقبض الصورة المراد تعريف اللون لها الثاني قيمة اللون الاحمر , قيمة اللون الاخضر , ومن ثم قيمة اللون الازرق وتتراوح قيم آخر ثلاث وسائط بين 0 - 255 .

دالة imagecolorallocaltealpha :
تعمل هذه الدالة كما تعمل الدالة السابقة باستثناء وجود وسيط جديد هو قيمة الشفافية alpha الذي تتراوح قيمته بين 0 -127

$color = imagecolorallocatealpha($image, $red, $green, $blue, $alpha);

حيث القيمة 127 تمثل لون شفاف تماما والقيمة 0 تعني انعدام الشفافية.

دالة imagecolorat :
تستخدم هذه الدالة لارجاع لون بكسل محدد باحداثياته من صورة مُحددة بمقبضها , ويكون شكلها العام كالتالي :

$color = imagecolorat($image, $x, $y);

لكن هذه الدالة تعيد قيمة RGB كرقم, ولاستخلاص قيم الالوان نستخدم الطريقة التالية :

<?php$image = imagecreatefromjpeg('image.jpg');$color1 = imagecolorat($image, 10, 10);$red1 = ($color1 >> 16) & 0xff;$green1 = ($color1 >> 8) & 0xff;$blue1 = $color1 & 0xff;echo "The first pixel color is : red = $red1 , green = $green1 , blue = $blue1<br>";$color2 = imagecolorat($image, 50, 50);$red2 = ($color2 >> 26) & 0xff;$green2 = ($color2 >> 8) & 0xff;$blue2 = $color2 & 0xff;echo "The second pixel color is : red = $red2 , green = $green2 , blue = $blue2";imagedestroy($image);?>


او باستخدام دالة imagecolorsforindex التي تعيد مصفوفة تحوي قيم الالوان بالشكل التالي :

<?php$image = imagecreatefromjpeg('image.jpg');$color1 = imagecolorat($image, 10, 10);$colors1 = imagecolorsforindex($image, $color1);//print_r($colors1) outputs ://Array ( [red] => 255 [green] => 255 [blue] => 255 [alpha] => 0 )echo "The first pixel color is : red = ".$colors1['red']." , green = ".$colors1['green']." , blue = ".$colors1['blue']."<br>";$color2 = imagecolorat($image, 50, 50);$colors2 = imagecolorsforindex($image, $color2);echo "The second pixel color is : red = ".$colors2['red']." , green = ".$colors2['green']." , blue = ".$colors2['blue']."<br>";imagedestroy($image);?>

حيث الوسيط الاول المرر لها هو مقبض الصورة والوسيط الثاني هو قيمة اللون والشكل العام لاستدعائها هو :

imagecolorsforindex($image,  $rgb);

هدم مقبض الصورة :
يتم هدم الصورة لتحرير الذاكرة المستخدمة من قبلها وذلك عن طريق دالة imagedestroy حيث تقبل وسيطا ً وحيدا ً هو مقبض الصورة :

imagedestroy($image);

تحديد أبعاد الصور :
وذلك باستخدام الدالتين imagesx, imagesy حيث تعيد هاتين الدالتين قيم العرض والطول للصورة وتقبلان وسيطا ً وحيدا ً هو مقبض الصورة :

<?php$image = imagecreatefromjpeg('image.jpg');$x = imagesx($image);$y = imagesy($image);echo "image width is $x and its height is $y";imagedestroy($image);?>

الدالة imagefill :
تقوم هذه الدالة بتلوين منطقة محددة بلون واحد اي كما تقوم اداة التعبئة في برامج الرسم :

<?php$image = imagecreatetruecolor(200, 200);$bg_color = imagecolorallocate($image, 0, 255, 0);imagefill($image, 0, 0, $bg_color);header('Content-Type: image/png');imagepng($image);imagedestroy($image);?>

حيث تقبل اربعة وسائط ,شكلها العام هو :

imagefill($image, $x, $y, $color);

الدالة imagefilledrectangle : تقوم هذه الدالة بملئ مستطيل بلون محدد :

imagefilledrectangle($image, $x1, $y1, $x2, $y2, $color);

حيث $x1, $y1 عي احداثيات الزاوية اليسرى العليا و $x2, $y2 هي احداثيات الزاوية اليمنى السفلى .
تدوير الصورة : يوجد في مكتبة GD دالة باسم imagerotate تقوم بتدوير الصورة حول مركزها , شكلها العام :

imagerotate($image,  $angle,  $bg_color);

حيث الزاوية بالدرجات و $bg_color هو اللون الذي سيتم وضعه مكان الفراغ نتيجة التدوير .
مثال :

<?php$image = imagecreatetruecolor(200, 200);imagefill($image, 0, 0, 0xffffff);$color = imagecolorallocate($image, 0, 255, 0);imagefilledrectangle($image, 50, 50, 149, 149, $color);$image = imagerotate($image, 45, 0xffffff);header('Content-Type: image/png');imagepng($image);imagedestroy($image);?>

لاحظ كيف ازدادت ابعاد الصورة تلقائيا ً .
الدالة imagesetpixel :
مفعول هذه الدالة مثل اسمها حيث تقوم بتحديد لون بكسل معين باحداثياته $x, $y تبدو هذه الدالة بلا فائدة لكن في الحقيقة هي من اهم الدوال في مكتبة GD حيث تستخدم في كثير من التطبيقات المتقدمة على الصور كما سنرى في قسم التطبيقات العملية.

imagesetpixel($image, $x, $y, $color);

رسم مستقيمات :
يتم رسم المستقيمات بواسطة الدالة imageline التي تقوم برسم مستقيم بين نقطتين محددتين الشكل العام لها هو :

imageline($image, $x1, $y1, $x2, $y2, $color);

حيث $x1 , $y1 هي احداثيات نقطة البداية و $x2 , $y2 هي احداثيات نقطة النهاية :

<?php$image = imagecreatetruecolor(200, 200);$bg_color = imagecolorallocate($image, 0, 255, 0);imagefill($image, 0, 0, $bg_color);$color = imagecolorallocatealpha($image, 255, 0, 0, 75);imageline($image, 0, 100, 199, 100, $color);imageline($image, 0, 0, 199, 199, $color);header('Content-Type: image/png');imagepng($image);imagedestroy($image);?>


تحديد سمك خط الرسم :
وذلك بواسطة الدالة imagesetthickness التي تقبل وسيطين الاول هو مقبض الصورة و الثاني هو سمك الخط مقدرا ً بالبكسل

imagesetthickness($image, $thickness);

عدل المثال السابق كي يصبح كالتالي :

<?php$image = imagecreatetruecolor(200, 200);$bg_color = imagecolorallocate($image, 0, 255, 0);imagefill($image, 0, 0, $bg_color);$color = imagecolorallocatealpha($image, 255, 0, 0, 75);imagesetthickness($image, 5);imageline($image, 0, 100, 199, 100, $color);imageline($image, 0, 0, 199, 199, $color);header('Content-Type: image/png');imagepng($image);imagedestroy($image);?>

كتابة نص على صورة :
ويوجد طريقتين : الاولى بواسطة الدالة imagestring والتي تستخدم الخطوط المدمجة مع مكتبة GD والثانية عن طريق دالة imagettftext التي تستخدم خطوط ttf او true-type fonts المتوفرة بكثرة (يوجد عدد من المواقع توفر خطوط مجانية بصيغة ttf ) .

دالة imagestring : الشكل العام لهذه الدالة :

imagestring($image, $font, $x, $y, $string, $color);

حيث الوسيط font يمثل حجم الخط و ياخذ قيمة عددية تتراوح بين 1- 5 , المثال التالبي يظهر الفروق بين قياسات الخط المُختلفة :

<?php$image = imagecreatetruecolor(200, 100);$bg_color = imagecolorallocate($image, 255, 255, 255);imagefill($image, 0, 0, $bg_color);$color = imagecolorallocatealpha($image, 0, 0, 0, 75);for($i = 1 ;$i <= 5; $i++){    imagestring($image, $i, 60, 15 *$i, 'Arab Team', $color);}header('Content-Type: image/png');imagepng($image);imagedestroy($image);?>

وسكون لديك نتيجة شبيهة بالصورة التالية :
post-268329-0-71107600-1363429576.txt
دالة imagettftext : تقوم هذه الدالة بطباعة نص باستخدام خطوط ttf بأي مقاس خط وبأي زاوية ,الشكل العام هو :

imagettftext($image, $size, $angle, $x, $y, $color, $fontfile, $text);

حيث الزاوية يمكن ان تكون موجبة او سالبة (القيمة الموجبة تؤدي الى الدوران عكس عقارب الساعة و القيمة السالبة تؤدي الى الدوران مع عقارب الساعة) و $fontfile هو مسار الخط المستخدم , جرب المثال التالي لكن مع وضع اي خط ttf في نفس المجلد وليكن اسم الخط font.ttf :

<?php$image = imagecreatetruecolor(200, 200);$bg_color = imagecolorallocate($image, 255, 255, 255);imagefill($image, 0, 0, $bg_color);$color = imagecolorallocatealpha($image, 0, 0, 0, 75);imagettftext($image, 25, 0, 25, 110, $color, 'font.ttf', 'Arab Team');header('Content-Type: image/png');imagepng($image);imagedestroy($image);?>


دالة imagettfbbox : تقوم هذه الدالة باعادة مصفوفة تحوي احداثيات نص باستخدام خط معين :

imagettfbbox($size, $angle, $fontfile, $text);

جرب المثال التالي لازالة الغموض :

<?php$font_spc = imagettfbbox(25, 0, 'font.ttf', 'Arab Team');print_r($font_spc);//Array ( [0] => -1 [1] => -1 [2] => 155 [3] => -1 [4] => 155 [5] => -25 [6] => -1 [7] => -25 )?>

لاحظ ان هذه الدالة تعيد مصفوفة مكونة من ثمانية عناصر كالتالي :
العنصر 0 يعيد قيمة x للزاوية اليسرى السفلى
العنصر 1 يعيد قيمة y للزاوية اليسرى السفلى
العنصر 2 يعيد قيمة x للزاوية اليمنى السفلى
العنصر 3 يعيد قيمة y للزاوية اليمنى السفلى
والعنصران 4 ,5 يعيدان قيمة x,y للزاوية اليمنى العليا و العنصران 6 ,7 للزاوية اليسرى العليا
تفيد هذه الدالة بحساب ابعاد اي نص مكتوب باي خط لاستخدامها في محاذاة النص (توسيط مثلا)
تختلف النتائج في المثال السابق باستخدام خطوط مختلفة .

نسخ صورة الى صورة :
دالة imagecopy :

imagecopy($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h);

تقوم هذه الدالة بنسخ جزء من صورة الى صورة اخرى حيث تقبل الوسائط التالية :
الوسيط $dst_im هو الصورة التي سيتم النسخ اليها (الصورة الهدف)
الوسيط $src_im الصورة التي سيتم النسخ منها
الوسائط $dst_x, $dst_y, $src_x, $src_y هي احداثيات بداية النسخ و اللصق
الوسيطين $src_w, $src_h هم عرض و طول الجزء المنسوخ

دالة imagecopyresized : تقوم هذه الدالة بنسخ جزء من صورة ولصقه في صورة اخرى مع تغيير ابعاده

imagecopyresized($dst_image, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);

حيث دلالات الوسائط كما في الدالة السابقة .

تطبيق التاثيرات على الصور :
تأتي الدالة imagefilter حاملة ً العديد من التأثيرات أو ما يُسمى "الفلاتر" التي يُمكن تطبيقها على الصور برمجيا ً, وتأخذ هذه الدالة عدد متغير من الوسائط بحسب التأثير المُمرر إليها , و لكن كما هو مُعتاد يكون الوسيط الأول هو مقبض الصورة والثاني هو الثابت الخاص بالفلتر المُستخدم و باقي الوسائط هي وسائط تختلف حسب التأثير المُستخدم . شكل الدالة العام :

imagefilter($image, $filtertype, $arg1, $arg2, $arg3);

- تغيير الإضاءة في الصور :
عند تمرير الثابت IMG_FILTER_BRIGHTNESS الى الدالة imagefilter يمكن تغيير الاضاءة في الصور وعند استخدام هذا التأثير يجب تمرير وسيط آخر هو قيمة الإضاءة التي تتراوح قيمتها بين -255 الى 255 حيث القيمة 255 تُمثل إضاءة كاملة (اللون الأبيض) أما القيمة -255 فتمثل اللون الاسود و القيمة 0 تُبقي الإضاءة على حالها .

<?php$image = imagecreatefromjpeg('image.jpg');imagefilter($image, IMG_FILTER_BRIGHTNESS, 100);header('Content-Type: image/png');imagejpeg($image);?>

post-268329-0-46726900-1363429555_thumb.
- تطبيق تأثير الضبابية blur :
وذلك عند استخدام الثابت IMG_FILTER_GAUSSIAN_BLUR أو IMG_FILTER_SELECTIVE_BLUR ولا داعي لاستخدام أي وسيط اضافي .
قائمة الفلاتر طويلة جدا ً وتأخذ وقت طويل للشرح فيمكنك الاطلاع عليها على موقع php الرسمي .

التطبيقات العملية :
سنستخدم شعار الفريق العربي للبرمجة لتطبيق الاكواد عليه .
التطبيق الاول تغيير صيغة صورة :
هذا التطبيق من ابسط التطبيقات المفيدة التي يمكن الاستفادة من مكتبة GD فيها ويكون بالطريقة التالية : في البداية ننشئ مقبض للصورة ولنفرض ان صيغتها jpg ثم نتسخدم الدالة imagepng لكتابتها الى ملف :

<?php$image = imagecreatefromjpeg('image.jpg');imagpng($image, 'image.png');imagedestroy($image);?>

قلب الصورة fliping image :
لا توفر مكتبة GD دالة لقلب الصورة راسيا ً او افقيا ً لكن يمكن بسهولة عمل دالة للقيام بتلك المهمة , مثلا لقلب الصورة راسيا ً نجعل كل y هي -y مع بقاء x ثابتة كما في المثال التالي :

<?php$image = imagecreatefromjpeg('image.jpg');header('Content-Type: image/png');$filped_image = imagefilphorizontal($image);imagepng($filped_image);imagedestroy($image);imagedestroy($filped_image);function imagefilphorizontal($image){    $tmp_image = imagecreatetruecolor(imagesx($image), imagesy($image));    for($x = 0, $w = imagesx($image); $x < $w; $x++)    {        for($y = 0 , $h = imagesy($image); $y < $h; $y++)        {            //to get each pixel            $color = imagecolorat($image, $x, $y);            imagesetpixel($tmp_image, $x, imagesy($image)-$y, $color);        }    }        return $tmp_image;    }?>


المثال السابق يعطي نتيجة مشابه للصورة التالية :
post-268329-0-50948000-1363429428_thumb.
حيث قمنا بانشاء صورة مؤقتة و تمكنا باستخدام حلقات for من الوصول الى جميع بكسلات الصورة الاصلية ووضع محل كل y قيمة تساوي ارتفاع الصورة - y
ولانشاء دالة تقوم بقلب الصورة افقيا نقوم باستبدال كل x ب "imagesx -x ":

<?php$image = imagecreatefromjpeg('image.jpg');header('Content-Type: image/png');$filped_image = imagefilpvertical($image);imagepng($filped_image);imagedestroy($image);imagedestroy($filped_image);function imagefilpvertical($image){    $tmp_image = imagecreatetruecolor(imagesx($image), imagesy($image));    for($x = 0, $w = imagesx($image); $x < $w; $x++)    {        for($y = 0, $h = imagesy($image); $y < $h; $y++)        {            //to get each pixel             $color = imagecolorat($image, $x, $y);            imagesetpixel($tmp_image, imagesx($image)-$x, $y, $color);        }    }        return $tmp_image;    }?>

المثال السابق يعطي نتيجة مشابه للصورة التالية :
post-268329-0-52157000-1363429450_thumb.

انشاء صور المصغرات :
عند عرض الصور في صفحة ويب لا يجب ان يكون حجمها كبيرا , لانها تتطلب وقتا طويلا لكي تتحمل من الانترنت , وخصوصا ً عند عرض عدد كبير من الصور في الصفحة الواحدة.
يمكن انشاء صور المصغرات عن طريق اعادة تحجيم الصورة باستخدام احدى الدالتين : imagecopyresized و imagecopyresampled

<?phpfunction resize($image, $new_name, $width, $height){    $tmp_image = imagecreatetruecolor($width, $height);    imagecopyresampled($tmp_image, $image, 0, 0, 0, 0, $width, $height, imagesx($image), imagesy($image));    imagejpeg($tmp_image, $new_name);    imagedestroy($image);}//To call This function ://resize(imagecreatefromjpeg('image.jpg'), 'new_image.jpg', 320, 240);?>

هذه الدالة البسيطة تقوم بتصغير صورة الى مقاس مُحدد بالوسيطين $width و $height . لكن مثلا ً عندما يكون لدينا صورة بقياس 1600 x 768 ونريد اعادة تحجيمها لتُصبح على سبيل المثال 320 x 240 فإن الصورة سوف تخضع لعميلة تشوه كما في الصورة التالية
post-268329-0-54628500-1363429459.jpg
و يمكن استخدام نسبة مئوية كوسيط للدالة السابقة بدلا ً من تحديد الابعاد :

<?phpfunction resize($image, $new_name, $percent){    $tmp_image = imagecreatetruecolor(imagesx($image) * $percent / 100, imagesy($image) * $percent / 100);    imagecopyresampled($tmp_image, $image, 0, 0, 0, 0, imagesx($image) * $percent / 100, imagesy($image) * $percent / 100, imagesx($image), imagesy($image));    imagejpeg($tmp_image, $new_name);    imagedestroy($image);}//To call This function ://resize(imagecreatefromjpeg('image.jpg'), 'new_image.jpg', 70);?>


المشكلة في الطريقة السابقة هي ان الصور الناتجة يمكن ان تختلف ابعادها بإختلاف ابعاد الصور الاصلية , فمثلا ً عند تصغير شعار الفريق العربي وجعله 70 بالمئة من قيمته الاصلية فينتج صورة مماثلة للصورة التالية :
post-268329-0-16384800-1363429466.jpg
أما لو جعلنا كلا البعدين (الطول و العرض) يصغران بنفس النسبة نحصل على صور متساوية في الحجم تقريبا و غير مشوهة :

<?phpfunction resize($image, $new_name, $width, $height){    $tmp_image = imagecreatetruecolor($width, $height);    imagefill($tmp_image, 0, 0, 0xFFFFFF);    $radio = imagesx($image) > imagesy($image) ?  imagesx($image) / $width :  imagesy($image) / $height ;    if(imagesx($image) > imagesy($image))    {        $height = imagesy($image) / $radio;    }    elseif(imagesy($image) > imagesx($image))    {        $width = imagesx($image) / $radio;    }    imagecopyresampled($tmp_image, $image, 0, 0, 0, 0, $width, $height, $width * $radio, $height * $radio);    imagejpeg($tmp_image, $new_name);    imagedestroy($image);}//To call This function ://resize(imagecreatefromjpeg('image.jpg'), 'new_image.jpg', 320, 240);?>

الدالة السابقة تُولد صورة شبيهة بالصورة التالية :
post-268329-0-50989400-1363429474.jpg
عمل ظل للنصوص :
هذا التأثير من اسهل التأثيرات المُتعلقة بالصور , حيث يمكن ببساطة انشاء لونين احدهما اسود يُكتب فيه النص و الآخر فضي للظل :

<?php$image = imagecreatetruecolor(200, 200);$bg_color = imagecolorallocate($image, 255, 255, 255);imagefill($image, 0, 0, $bg_color);$text_color = imagecolorallocate($image, 0, 0, 0);$shadow_color = imagecolorallocatealpha($image, 128, 128, 128, 60);imagettftext($image, 25, 0, 27, 111, $shadow_color, 'font.ttf', 'Arab Team');imagettftext($image, 25, 0, 25, 110, $text_color, 'font.ttf', 'Arab Team');header('Content-Type: image/png');imagepng($image);imagedestroy($image);?>

الفكرة الأساسية هي اعادة كتابة نفس الجملة لكن بلون و إحداثيات مختلفة .
post-268329-0-32723500-1363429501.png
* هل يمكن تطبيق تأثير معقد نسبيا على الصور باستخدام GD و php ؟
نعم بكل سهولة , لنأخذ مثالا بسيطا ً اذا اردت ان تقوم بتأثير الانعكاس كما في الصورة التالية :
post-268329-0-50301400-1363429542_thumb.
لنبدأ سويا بالتفكير كيف يمكن تطبيق هذا التأثير برمجيا ً :
1 - اول ما نلاحظة ان طول (height) الصورة الناتجة هو ضعف الصورة الاصلية
2 - ان الانعكاس مقلوب راسيا ً .
3 - يوجد تدرج للشفافية .
لنبدأ بكتابة الكود :

<?php$image = imagecreatetruecolor(200,50);imagefill($image,0, 0, 0xffffff);imagettftext($image, 25, 0, 25, 45, 0x000000, 'font.ttf', 'Arab Team');header('Content-Type: image/png');imagepng(mirroreffect($image));function mirroreffect($image){    $tmp_image = maketransparent(flip($image));    $result_image = imagecreatetruecolor(imagesx($image), imagesy($image) * 2);    imagecopymerge($result_image, $tmp_image, 0, imagesy($image) - 1, 0, 0, imagesx($image), imagesy($image), 100);    imagecopymerge($result_image, $image, 0, 0, 0, 0, imagesx($image), imagesy($image), 100);    return $result_image;}function flip($image){    $tmp_image = imagecreatetruecolor(imagesx($image), imagesy($image));    imagefill($tmp_image,0, 0, 0xffffff);    for($x = 0, $w = imagesx($image); $x < $w; $x++)    {        for($y = 0, $h = imagesy($image); $y < $h; $y++)        {            $color = imagecolorat($image, $x, $y);            imagesetpixel($tmp_image, $x, imagesy($image) - $y, $color);        }    }    return $tmp_image;}function maketransparent($image){    $tmp_image = imagecreatetruecolor(imagesx($image), imagesy($image));    imagefill($tmp_image, 0, 0, 0xffffff);    $falpha =(127 - 10) / imagesy($image);        for($y = 0, $h = imagesy($image); $y < $h; $y++)    {        $alpha = $falpha * $y;                        for($x = 0, $w = imagesx($image); $x < $w; $x++)        {                        $color = imagecolorat($image, $x, $y);            $colors = imagecolorsforindex($image, $color);            $new_color = imagecolorallocatealpha($image, $colors['red'], $colors['green'], $colors['blue'], $alpha + 10);            imagesetpixel($tmp_image, $x, $y, $new_color);                    }            }        return $tmp_image;}?>

شرح الكود: كما لاحظت لقد استخدمت ثلاث دالات دالة لقلب الصورة راسيا كما في المثال السابق والدالة الثانية هي دالة maketransparent التي تقوم بجعل الوان الصورة متدرج بالشفافية ثم دالة mirroreffect التي تقوم بعمل الدالة الرئيسية حيث تقوم بنسخ الصورتين الاصلية و المقلوية المتدرجة الشفافية الى صورة جديدة طولها يساوي ضعف طول الصورة الاصلية .
لكن المشكلة الاساسية هي مقدار استهلاك البرنامج لموارد السيرفر حيث يقوم كل مرة بالمرور على جميع بكسلات الصورة ثم يقوم باجراء العمليات عليها ناهيك عن انشاءه لعدد من مقابض الصور . والحل ؟؟
يمكن دمج الدالات السابقة بدالة واحدة كالتالي :

<?php$image = imagecreatefromjpeg('image.jpg');header('Content-Type: image/png');imagepng(mirroreffect($image));function mirroreffect($image){    $width = imagesx($image);    $height = imagesy($image);    $tmp_image = imagecreatetruecolor($width, $height);    imagefill($tmp_image, 0, 0, 0xffffff);    $falpha =(127 - 40)/ $height;        for($y = 0; $y < $height; $y++)    {        $alpha = $falpha * ($height - $y);        for($x = 0; $x < $width; $x++)        {                        $color = imagecolorat($image, $x, $y);            $colors = imagecolorsforindex($image, $color);            $new_color = imagecolorallocatealpha($image, $colors['red'], $colors['green'], $colors['blue'], $alpha + 40);            imagesetpixel($tmp_image, $x, $height - $y, $new_color);        }    }    $result_image = imagecreatetruecolor($width, ($height * 2) - 1);    imagecopymerge($result_image, $tmp_image, 0, $height - 1, 0, 0, $width, $height, 100);    imagecopymerge($result_image, $image, 0, 0, 0, 0, $width, $height, 100);    return $result_image;}?>

وفرنا الكثير من الوقت و الاسطر .
- يوجد هناك مشكلة في الكتابة باللغة العربية على الصور باستخدام دوال GD , حيث تظهر الحرف مُقطعة وبترتيب معكوس , لكن يُمكن حل هذه المشكلة إما باستخدام مكتبة php واللغة العربية , أو باستخدام الدالة البسيطة التي قُمتُ بكتابتها في موضوع الكتابة باللغة العربية على الصور .

 

 

الدرس السابق | الإنتقال للموضوع الأساسي

تم تعديل بواسطه Abd Allatif
6

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

11 إجابة على هذا السؤال .

  • 0

بارك الله فيك اخي

في ميزان حسناتك بإذن الله

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

موضوع ممتاااااااااااااااااااااااااااااز

انا سجلت بهذا المنتدى خص نص علشان اشكر صاحب الموضوع 

جزاك الله خير

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

:)  :) عمل جميل :)  :) 


لدي سوال حول كيفية عمل قالب للصور (مجموعة صور فب اطار واحد)


بلغة php فقط


0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

لدي سوال حول كيفية عمل قالب للصور (مجموعة صور فب اطار واحد)

بلغة php فقط

 

أرجو توضيح سؤالك وفتح موضوع جديد للمشكلة لتنظيم المنتدى.

رائع جداًً بارك الله فيك 

تُشكر على مرورك :)

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

درس رائع, بارك الله بك أخي عبد

ولكن ماذا لو طرح السؤال التالي:

ما الفائدة من استخدام هذه الدوال؟ الا استطيع التعامل مع الصور مباشرة باستخدام html؟

حتى بالنسبة للتأثيرات, جميعها قابلة للتوليد من خلال css فما هو المميز هنا وما هو المكان الذي سأكون مجبراً فيه على التعامل مع هذه الدوال؟

 

قلو أخذنا هذا المثال من الدرس:

<?php$base_64_data = '/9j/4AAQSkZJRgABAQEASABIAAD/2wBDADIiJSwlHzIsKSw4NTI7S31RS0VFS5ltc1p9tZ++u7Kfr6zI4f/zyNT/16yv+v/9////////wfD/////////////2wBDATU4OEtCS5NRUZP/zq/O////////////////////////////////////////////////////////////////////wAARCAAwADEDASIAAhEBAxEB/8QAGQAAAwEBAQAAAAAAAAAAAAAAAAMEAgUB/8QAJxAAAgIBAwMDBQEAAAAAAAAAAAECAxEEEjEhQVETMmEFIkJxgZH/xAAYAQEBAQEBAAAAAAAAAAAAAAADAgABBP/EABwRAAMBAAMBAQAAAAAAAAAAAAABAhESITEDQf/aAAwDAQACEQMRAD8A6gALnLLwjjeHUtCVqTwurMO/H4mJrdNbfcjx124z9r+CNp+FpT+k71Nm7duf6OlB7oJ+UQOKb6xw/kr09m+OHyjTXeHbXWoaAAIES6qbU1HtgXVJ5b7FdlUbPcsiNuyThxjgG0/RZpZg6mOI57tjCb11T7uAetqS6Zz4ElrCeLfhnW4goyXL6C9HY3fjyhN97unl9EuEN+nwbtc+yWCcTeiueMdnQAAEPOAu2vevDXDGAb0xzNTXYp9U2vKEfx/4dlxT5PPTj4J4jT9WlhHTXBVrMU2+clOnjGMGorCyZnQ3JuMmsja4KEMEzLT7IqtRoAAQg//Z';$image = imagecreatefromstring(base64_decode($base_64_data));header('Content-Type: image/png');imagepng($image);imagedestroy($image);?>

ما هو وجه الاختلاف بينه وبين هذه الطريقة؟

<img src="data:image/png;base64,/9j/4AAQSkZJRgABAQEASABIAAD/2wBDADIiJSwlHzIsKSw4NTI7S31RS0VFS5ltc1p9tZ++u7Kfr6zI4f/zyNT/16yv+v/9////////wfD/////////////2wBDATU4OEtCS5NRUZP/zq/O////////////////////////////////////////////////////////////////////wAARCAAwADEDASIAAhEBAxEB/8QAGQAAAwEBAQAAAAAAAAAAAAAAAAMEAgUB/8QAJxAAAgIBAwMDBQEAAAAAAAAAAAECAxEEEjEhQVETMmEFIkJxgZH/xAAYAQEBAQEBAAAAAAAAAAAAAAADAgABBP/EABwRAAMBAAMBAQAAAAAAAAAAAAABAhESITEDQf/aAAwDAQACEQMRAD8A6gALnLLwjjeHUtCVqTwurMO/H4mJrdNbfcjx124z9r+CNp+FpT+k71Nm7duf6OlB7oJ+UQOKb6xw/kr09m+OHyjTXeHbXWoaAAIES6qbU1HtgXVJ5b7FdlUbPcsiNuyThxjgG0/RZpZg6mOI57tjCb11T7uAetqS6Zz4ElrCeLfhnW4goyXL6C9HY3fjyhN97unl9EuEN+nwbtc+yWCcTeiueMdnQAAEPOAu2vevDXDGAb0xzNTXYp9U2vKEfx/4dlxT5PPTj4J4jT9WlhHTXBVrMU2+clOnjGMGorCyZnQ3JuMmsja4KEMEzLT7IqtRoAAQg//Z" />

ويمكننا مثلا التحكم بها من خلال css وعمل rotate أو reflection أو أي نوع من التأثيرات!

ما الفرق بين الحالتين؟

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

السلام عليكم

 

- ربما التوافقية ودعم أغلب المتصفحات التي لا تدعم خصائص CSS3 سيكون استخدام هذه الدوال أحد الحلول .

- الحاجة لإعادة تحجيم الصور وطباعة أختام على الصور لحفظ حقوق الصور سيكون استخدام مكتبة GD مناسب .

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

السلام عليكم

 

- ربما التوافقية ودعم أغلب المتصفحات التي لا تدعم خصائص CSS3 سيكون استخدام هذه الدوال أحد الحلول .

 

وارد, ولكن عن نفسي آخر ما قد أفكر فيه هو نقل معالجة الصور و التأثيرات من طرف الزبون إلى طرف السيرفر لسبب كهذا, في اسوء الأحوال سأختار التخلى عن الـ effect في المتصفحات القديمة على أن أنقل المعالجة إلى طرف الخادم .. ولكن يبقى هذا الاحتمال وارداً!

 

- الحاجة لإعادة تحجيم الصور وطباعة أختام على الصور لحفظ حقوق الصور سيكون استخدام مكتبة GD مناسب .

نسبياً هذا من ضمن ما اشير إليه, فالفكرة العامة هنا, أنك عندما تفكر في مشروع مرتبط بـ image manipulation أو image processing فلن تفيدك كل ما تقدمه الـ CSS من تاثيرات و أشكال وتحكم!

 

فالفرق في الحالتين, أن التأثيرات المضافة إلى الصورة من خلال الـ php-gd, ستصبح جزأ من الصورة أو بالأحرى ستتولد صورة جديدة بالشكل الذي حددته لها!

أما مع الـ css فالصورة بقيت كما هي ولكن استطعت توفير المؤثرات المطلوبة من خلال التعامل مع المتصفح دون توليد صورة جديدة .. فإذا كنت اريد فقط عرض بعض المؤثرات الصورية ضمن صفحة ويب سأختار html+css حتماً

أما مع مشروع من مثل online photo processor فسأكون مضطراً لاستخدام php-gd لهذه المهمة. 

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

وعليكم السلام

صحيح أن css3 تُقدم ميزات هائلة في هذا المجال لكن لا يمكنك إنشاء كل التأثيرات على الصور بإستخدامها، على سبيل المثال كيف يمكنك إنشاء مثل تأثير slice بإستخدام css ؟ لا يمكن ذلك (يمكنك مشاهدات عدد من التأثيرات في هذا الموضوع رغم أن المكتبة مازالت تجريبية وبطيئة و ...)

 

- ربما التوافقية ودعم أغلب المتصفحات التي لا تدعم خصائص CSS3 سيكون استخدام هذه الدوال أحد الحلول .

- الحاجة لإعادة تحجيم الصور وطباعة أختام على الصور لحفظ حقوق الصور سيكون استخدام مكتبة GD مناسب .

إضافةً لهاتين النقطتين : ماذا لو أردت إستخدام php في مجال غير الويب ؟ عن طريق PHP-GTK أو عن طريق سكربت command line يقوم بإنشاء الصور أو تعديلها، ففي هذه الحالة لن تستطيع إستخدام css  :) post-268329-0-62210100-1370664901.png

تم تعديل بواسطه Abd Allatif
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

السلام عليكم

 

وارد, ولكن عن نفسي آخر ما قد أفكر فيه هو نقل معالجة الصور و التأثيرات من طرف الزبون إلى طرف السيرفر لسبب كهذا, في اسوء الأحوال سأختار التخلى عن الـ effect في المتصفحات القديمة على أن أنقل المعالجة إلى طرف الخادم .. ولكن يبقى هذا الاحتمال وارداً!

- بكل تأكيد كلامك سليم , فأداء وسرعة التطبيق على الخادم من أهم الشروط الواجب توافرها في التطبيق , فلا يعقل نقل عملية التأثيرات على الصور لمعالجتها على الخادم في كل عملية طلب للصفحة من جهة العميل , عدد قليل من الزوار لموقعك كفيل بتوقف الخادم إذا استخدمنا مكتبة GD لإظهار التأثيرات بدلاً من css , ولكن ربما في بعض الأحيان نحتاج لتطبيق تأثيرات ثابتة على الصور عند رفعها وحفظ النسخة المعدلة منها على الخادم لإستخدامها عند طلب الصفحة , وفي هذه الحالة لن نستهلك موارد الخادم إلا مرة واحدة فقط لتطبيق التأثير عند رفع الصورة الجديدة .

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

من فضلك سجل دخول لتتمكن من التعليق

ستتمكن من اضافه تعليقات بعد التسجيل



سجل دخولك الان

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .