خرج الصورة
يمكن إنشاء صورة باستخدام دوال image* حيث * هي صيغة الملف، وهذه الدوال لها الصيغة المشتركة التالية:
bool image___(resource $im [, mixed $to [ other parameters]] )
الحفظ إلى ملف
يمكنك تمرير اسم الملف أو مجرى ملف مفتوح للمتغير $to
إذا كنت تريد حفظ الصورة إلى ملف، إذا مررت مجرى فلا تحتاج لإغلاقه لأنّ مكتبة GD تغلقه تلقائيًا، مثلًا لحفظ ملف PNG:
imagepng($image, "/path/to/target/file.png"); $stream = fopen("phar://path/to/target.phar/file.png", "wb"); imagepng($image2, $stream); // لا حاجة لإغلاق المجرى
تأكد عند استخدام fopen
من أنك تستخدم الراية b
وليس الراية t
لأن الملف هو خرج ثنائي، ولا تحاول أن تمرر fopen("php://temp", $f)
أو fopen("php://memory", $f)
لأنّ الدالة تُغلق المجرى بعد الاستدعاء ولن تبقى قادرًا على استدعائه أو استخدامه لاسترداد محتوياته مثلًا.
الخرج كرد HTTP
لا تحتاج إلى تمرير شيء (أو مرر null) كوسيط ثانٍ إذا كنت تريد أن ترجع هذه الصورة مباشرةً كرد للصورة (لإنشاء بطاقات ديناميكية مثلًا)، لكنك تحتاج إلى تحديد نوع المحتوى في رد HTTP:
header("Content-Type: $mimeType");
$mimeType
هو نوع الصياغة المُرجعة في الترويسة MIME
مثل image/png
وimage/gif
وimage/jpeg
.
الكتابة إلى متغير
يوجد طريقتين للكتابة إلى متغير:
- استخدام المخزن المؤقت للخرج (OB):
ob_start(); // تمرير null للكتابة افتراضيًا في مجرى الخرج القياسي imagepng($image, null, $quality); $binary = ob_get_clean();
- استخدام مغلِّف المجرى:
قد يكون لديك سبب ما لعدم استخدام المخزن المؤقت للخرج كأن يكون لديك بالفعل مخزن مؤقت قيد التشغيل لذا تحتاج إلى بديل، يمكنك تسجيل مغلَّف مجرى جديد باستخدام الدالة stream_wrapper_register
لذا يمكنك تمرير مجرى إلى دالة إظهار الصورة واستعادته لاحقًا.
<?php class GlobalStream{ private $var; public function stream_open(string $path){ this->var =& $GLOBALS[parse_url($path)["host"]]; return true; } public function stream_write(string $data){ $this->var .= $data; return strlen($data); } } stream_wrapper_register("global", GlobalStream::class); $image = imagecreatetruecolor(100, 100); imagefill($image, 0, 0, imagecolorallocate($image, 0, 0, 0)); $stream = fopen("global://myImage", ""); imagepng($image, $stream); echo base64_encode($myImage);
في هذا المثال يكتب الصنف GlobalStream
أي دخل إلى المتغير المرجعي (أي الكتابة بشكل غير مباشر إلى المتغير العام للاسم المعطى)، يمكن استرجاع المتغير العام لاحقًا بشكلٍ مباشر.
يجب الانتباه إلى عدة أمور:
-
صنف مغلِّف المجرى المنفَّذ بشكلٍ كامل يجب أن يشبه هذا الصنف لكن وفقًا للاختبارات باستخدام تابع
__call
السحري فإنّه من الممكن استدعاءstream_open
وstream_write
وstream_close
فقط من الدوال الداخلية. -
لا توجد رايات مطلوبة في استدعاء
fopen
لكن يجب أن تمرر سلسلة فارغة على الأقل، لأنّ الدالةfopen
تتوقع مثل هذا المعامل، حتى لو لم تستخدمها في تنفيذstream_open
يبقى هذا المعامل مطلوبًا. -
تستدعى الدالة
stream_write
عدة مرات وفقًا للاختبارات، تذكر أن تستخدم إسناد الدمج.=
وليس إسناد المتغير المباشر=
.
مثال: في وسم <img>
في HTML، يمكن توفير صورة بشكلٍ مباشر بدلًا من استخدام رابط خارجي:
echo '<img src="data:image/png;base64,' . base64_encode($binary) . '">';
إنشاء صورة
نستخدم الدالة imagecreatetruecolor
لإنشاء صورة فارغة:
$img = imagecreatetruecolor($width, $height);
المتغير $img
هو متغير مورد الآن بعرض $width
وطول $height
بكسل، لاحظ أنّ العرض يُحسب من اليسار إلى اليمين والطول من الأعلى إلى الأسفل.
يمكن أن يُنشأ أيضًا مورد الصورة من دوال إنشاء الصورة مثل imagecreatefrompng
وimagecreatefromjpeg
ودوال imagecreatefrom*
أخرى.
قد تُحرَّر موارد الصورة لاحقًا عندما لا توجد مراجع إليها، لكن لتحرير الذاكرة بشكلٍ مباشر (قد يكون هذا مهمًا عند معالجة عدة صور كبيرة) يمكننا استخدام imagedestroy()
على الصورة عندما لا تبقى حاجة لاستخدامها وتكون هذه ممارسة جيدة.
imagedestroy($image);
تحويل صورة
إنّ الصور التي تُنشأ من تحويل الصور لا تعدّل الصورة حتى تُخرجها، لذا يمكن أن يكون محوِّل الصورة ببساطة عبارة عن ثلاثة أسطر من الشيفرة:
function convertJpegToPng(string $filename, string $outputFile) { $im = imagecreatefromjpeg($filename); imagepng($im, $outputFile); imagedestroy($im); }
اقتصاص الصورة وتغيير حجمها
يمكنك استخدام الدالة imagecopyresampled
إذا كان لديك صورة وتريد إنشاء صورة جديدة بأبعاد جديدة، أنشئ أولًا صورة جديدة بالأبعاد المرغوبة:
// صورة جديدة $dst_img = imagecreatetruecolor($width, $height);
خزّن الصورة الأصلية في متغير، يمكنك القيام بذلك باستخدام إحدى دوال createimagefrom*
حيث يمكن أن تكون *
هي jpeg
أو gif
أوpng
أوstring
، مثال:
// الصورة الأصلية $src_img=imagecreatefromstring(file_get_contents($original_image_path));
ثم استخدم الدالة imagecopyresampled
لنسخ كل الصورة الأصلية (أو جزء منها) (src_img)
إلى الصورة الجديدة (dst_img)
:
imagecopyresampled($dst_img, $src_img, $dst_x ,$dst_y, $src_x, $src_y, $dst_width, $dst_height, $src_width, $src_height);
لضبط أبعاد src_*
وdst_*
، استخدم الصورة التالية:
إذا كنت تريد الآن نسخ كامل الصورة المصدر (الأصلية) إلى كامل منطقة الهدف (بدون اقتصاص):
$src_x = $src_y = $dst_x = $dst_y = 0; // عرض الصورة الجديدة $dst_width = $width; // طول الصورة الجديدة $dst_height = $height; // عرض الصورة الأصلية $src_width = imagesx($src_img); // طول الصورة الأصلية $src_height = imagesy($src_img);
مكتبة Imagick
التثبيت
-
باستخدام
apt
في الأنظمة المعتمدة على Debian:
sudo apt-get install php5-imagick
-
باستخدام
Homebrew
في أنظمةOSX/macOs
:
brew install imagemagick
- باستخدام الإصدارات الثنائية: التعليمات في موقع imagemagick.
الاستخدام
<?php $imagen = new Imagick('imagen.jpg'); // إذا وضعت قيمة المعامل 0 ستتم المحافظة على نسبة العرض $imagen->thumbnailImage(100, 0); echo $imagen; ?>
تحويل صورة إلى سلسلة نصية بالأساس 64
يُظهر هذا المثال كيفية تحويل صورة إلى سلسلة نصية بالأساس 64 (أي سلسلة نصية يمكنك استخدامها مباشرةً في السمة src
لوسم img
)، يستخدم هذا المثال مكتبة Imagick لكن يمكن استخدام مكتبات أخرى مثل GD.
<?php // (1) $img = new Imagick('image.jpg'); // (2) $img->resizeImage(320, 240); // (3) $imgBuff = $img->getimageblob(); // (4) $img->clear(); // (5) $img = base64_encode($imgBuff); echo "<img alt='Embedded Image' src='data:image/jpeg;base64,$img' />";
في الموضع (1) يُحمَّل الملف image.jpg
للمعالجة، مسار الملف نسبي إلى ملف .php
المتضمن هذه الشيفرة لذا في هذا المثال يجب أن يكون ملف image.jpg
في نفس مجلد السكربت.
في الموضع (2) يتغير حجم الصورة للحجم المُعطى كطول وعرض وإذا أردت تغيير دقة الصورة أيضًا مع تغيير الحجم يمكنك استخدام الدالة $img->resampleimage(320, 240)
، لاحظ أنّه يمكنك ضبط المعامل الثاني إلى 0 للمحافظة على نسبة عرض الصورة.
في الموضع (3) تُرجع الدالة تمثيل الصورة على شكل سلسلة نصية غير مشفرة.
في الموضع (4) يُزال المورد image.jpg
من الكائن $img
ويُدمَّر الكائن مما يحرر موارد النظام المحجوزة لمعالجة الصورة.
في الموضع (5) تُنشأ نسخة بتشفير الأساس 64 من السلسلة النصية السابقة غير المشفرة ثم تُعرَض كصورة في الصفحة، لاحظ أنّه قد يتغير الجزء image/jpeg
في السمة src
وذلك بالاعتماد على نوع الصورة التي تستخدمها (png أوjpeg مثلًا).
ترجمة -وبتصرف- للفصول [Image Processing with GD - Imagick] من كتاب PHP Notes for Professionals book
اقرأ أيضًا
- المقال التالي: مدخل إلى تعلم الآلة (Machine learning) في PHP
- المقال السابق: اصطلاحات ومواضيع متفرقة مهمة لكل مبرمج PHP
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.