رندر کردن اشکال هندسی و متن روی تصاویر با PHP — به زبان ساده

۲۲۴ بازدید
آخرین به‌روزرسانی: ۰۸ مهر ۱۴۰۲
زمان مطالعه: ۷ دقیقه
رندر کردن اشکال هندسی و متن روی تصاویر با PHP — به زبان ساده

PHP یک کتابخانه به نام GD برای دستکاری تصاویر دارد. اما با استفاده از این کتابخانه، علاوه بر دستکاری تصاویر موجود می‌توان تصاویری را از صفر نیز ایجاد کرد. تابع‌های مختلفی در این کتابخانه وجود دارند که می‌توانند برای ترسیم شکل‌هایی مانند بیضی، دایره، مستطیل، چندضلعی، و خطوط ساده مورد استفاده قرار گیرند. با بهره‌گیری از برخی معادله‌های ریاضی می‌توان الگوهای زیبایی با استفاده از این کتابخانه ایجاد کرد. تابع‌هایی نیز برای قرار دادن متن روی تصاویر رندر شده وجود دارند که امکانات زیادی در اختیار ما قرار می‌دهند. در این راهنما با روش رسم شکل‌های ساده در PHP و چگونگی رندر کردن متن با استفاده از فونت دلخواه آشنا می‌شویم.

رسم شکل‌های ساده در PHP با استفاده از GD

ما در این بخش با شکل‌های ساده آشنا می‌شویم و سپس ضخامت خط، قلم‌موها و سبک‌های مختلف خطوط را نیز در ادامه بررسی می‌کنیم.

رسم خطوط

شما می‌توانید با استفاده از تابع زیر یک خط ساده مستقیم بین دو نقطه مفروض رسم کنید:

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

پارامتر image$ یک منبع تصویر است که قبلاً با استفاده از تابع‌هایی مانند ()imagecreatetruecolor یا ()imagecreatefromjpeg ایجاد شده است. ما از ()imagecreatetruecolor در سراسر این راهنما برای ایجاد تصاویر جدید از صفر استفاده می‌کنیم. این تابع در صورتی که پارامتر y1 با y2 برابر باشد، یک خط افقی ایجاد می‌کند. به طور مشابه اگر پارامترهای x1 و x2 برابر باشند، یک خط عمودی رسم می‌شود.

رسم دایره و کمان

تابع (imagearc($image, $cx, $cy, $width, $height, $start, $end, $color می‌تواند با استفاده از پارامترهای cx$ و cy$ به عنوان مرکز، کمان‌های دایره‌ای رسم کند. پارامترهای width$ و height$ اندازه کمان را روی محورهای مختلف تعیین می‌کنند. پارامترهای start$ و end$ زاویه آغاز و پایان کمان را برحسب درجه مشخص می‌سازند. اگر می‌خواهید کمان‌های کاملی را از 0 تا 360 درجه رسم کنید می‌توانید از تابع زیر نیز استفاده کنید:

رسم مستطیل و چندضلعی

شما می‌توانید با استفاده از تابع (imagerectangle($image, $x1, $y1, $x2, $y2, $color مستطیل‌هایی را روی یک تصویر رسم کنید. مقادیر x1 و y1 گوشه سمت بالا-چپ را مشخص می‌کنند. مقادیر پارامتر x2 و y2 گوشه راست-پایین مستطیل را مشخص می‌کنند. همچنین یک تابع به صورت زیر وجود دارد که می‌تواند یک چندضلعی با هر تعداد ضلع یا نقطه ایجاد کند:

imagepolygon($image, $points, $num_points, $color)

پارامتر points$ آرایه‌ای است که در آن دو عنصر با هم جفت می‌شوند تا مختصات نقطه مفروض را تشکیل دهند.

تابع دیگری به نام ()imageopenpolygon به نسخه 7.0 PHP اضافه شده است که یک خط بین نقطه اول و آخر رسم نمی‌کند.

جمع‌بندی ایجاد یک رسم

ما در مثال زیر از همه تابع‌هایی که تا به این جا معرفی کردیم برای ایجاد یک رسم از کلبه، خورشید و زمین استفاده کرده‌ایم.

1<?php
2 
3header("Content-type: image/png");
4 
5$img_width = 800;
6$img_height = 600;
7 
8$img = imagecreatetruecolor($img_width, $img_height);
9 
10$black = imagecolorallocate($img, 0, 0, 0);
11$white = imagecolorallocate($img, 255, 255, 255);
12$red   = imagecolorallocate($img, 255, 0, 0);
13$green = imagecolorallocate($img, 0, 255, 0);
14$blue  = imagecolorallocate($img, 0, 0, 255);
15$orange = imagecolorallocate($img, 255, 200, 0);
16 
17imagefill($img, 0, 0, $white);
18 
19imagerectangle($img, $img_width*2/10, $img_height*5/10, $img_width*4/10, $img_height*8/10, $red);
20imagerectangle($img, $img_width*4/10, $img_height*5/10, $img_width*8/10, $img_height*8/10, $red);
21 
22imagepolygon($img, [$img_width*3/10, $img_height*2/10, $img_width*2/10, $img_height*5/10, $img_width*4/10, $img_height*5/10], 3, $red);
23imageopenpolygon($img, [$img_width*3/10, $img_height*2/10, $img_width*7/10, $img_height*2/10, $img_width*8/10, $img_height*5/10], 3, $red);
24 
25imageellipse($img, 100, 100, 100, 100, $orange);
26imagearc($img, $img_width*3/10, $img_height*8/10, 100, 200, 180, 360, $red);
27 
28imageline($img, 0, $img_height*8/10, $img_width, $img_height*8/10, $green);
29 
30imagepng($img);
31 
32?>

نکته مهم در این کد آن است که چگونه باید مقدار مختصات مختلف را محاسبه کنیم. ما همه چیز را نسبت به اندازه تصویر اصلی رسم کرده‌ایم و از این رو از متغیرهای img_height$ و img_width$ برای محاسبه مختصات نقطه‌های مختلف استفاده کرده‌ایم.

Render Text and Shapes on Images in PHP

کنترل کردن ضخامت، سبک و رنگ خط

تصویر فوق چند مشکل دارد که شامل خطوط بسیار نازک و عدم داشتن رنگ است. همه این مشکلات را می‌تواند به سادگی با استفاده از تابع‌هایی مانند ()imagesetthickness و ()imagefilledrectangle حل کرد.

ضخامت خط

تابع (imagesetthickness($image, $thickness ضخامت خطوط رندر شده را هنگام ترسیم مستطیل، چندضلعی و شکل‌های دیگر تنظیم می‌کند. برای نمونه تعیین مقدار برابر با thickness$ باعث می‌شود که همه شکل‌های رسم شده با استفاده از تابع‌های ()imagerectangle() ،imagearc و ()imagepolygon دارای ضخامت خط برابر با 5 پیکسل باشند.

رسم شکل‌های تو پر

همه تابع‌های رسم یک نسخه با رنگ‌آمیزی داخلی نیز دارند که آن شکل خاص را با رنگ مذکور پر می‌کند. برای نمونه ()imagefilledrectangle باعث می‌شود که مستطیل رسم شده با رنگ مذکور پر شود.

استفاده از قلم‌مو

یکی از تابع‌های بسیار مفید GD، تابع (imagesetbrush($image, $brush است. پارامتر brush$ در این تابع یک منبع تصویر دیگر است که می‌توان برای رسم خطوط از آن استفاده کرد. برای نمونه می‌توان از یک تصویر برداری شفاف گل به عنوان یک قلم‌مو استفاده کرد و الگوهای گل گلی زیبایی روی تصویر ایجاد کرد. قطعه کد زیر برای استفاده از یک تکه ابر به عنوان قلم‌مو هنگام رسم یک نقطه طراحی شده است. این وضعیت باعث می‌شود که یک ابر به آسمان اضافه شود.

1<?php
2 
3$img = imagecreatetruecolor($img_width, $img_height);
4 
5$clouds = imagecreatefrompng('clouds.png');
6$clouds = imagescale($clouds, 250);
7 
8imagesetthickness($img, 5);
9imagesetbrush($img, $clouds);
10 
11imageline($img, $img_width*9/10, 50, $img_width*9/10, 50, IMG_COLOR_BRUSHED);
12 
13?>

برای نمونه ما از تصویر ابر زیر استفاده و آن را کوچک‌تر کردیم تا اندازه مناسبی برای پروژه‌مان داشته باشد.

cloud image

اینک کد کامل تصویر کلبه به صورت زیر است. در این کد دو نسخه از هر شکل ارائه شده است که یکی با صرفاً با خطوط بیرونی رسم می‌شود و دیگر با رنگ‌آمیزی درونی ترسیم شده است.

1<?php
2 
3header("Content-type: image/png");
4$img_width = 800;
5$img_height = 600;
6 
7$img = imagecreatetruecolor($img_width, $img_height);
8 
9$clouds = imagecreatefrompng('clouds.png');
10$clouds = imagescale($clouds, 250);
11 
12imagesetthickness($img, 5);
13imagesetbrush($img, $clouds);
14 
15$black = imagecolorallocate($img, 0, 0, 0);
16$white = imagecolorallocate($img, 255, 255, 255);
17$red   = imagecolorallocate($img, 255, 0, 0);
18$green = imagecolorallocate($img, 0, 255, 0);
19$blue  = imagecolorallocate($img, 0, 200, 250);
20$orange = imagecolorallocate($img, 255, 200, 0);
21$brown = imagecolorallocate($img, 220, 110, 0);
22 
23imagefill($img, 0, 0, $white);
24 
25imagefilledrectangle($img, 0, 0, $img_width, $img_height*8/10, $blue);
26 
27imagefilledrectangle($img, $img_width*2/10, $img_height*5/10, $img_width*4/10, $img_height*8/10, $red);
28imagefilledrectangle($img, $img_width*4/10 - 2, $img_height*5/10, $img_width*8/10, $img_height*8/10, $red);
29 
30imagefilledpolygon($img, [$img_width*3/10, $img_height*2/10, $img_width*2/10, $img_height*5/10, $img_width*4/10, $img_height*5/10], 3, $red);
31imagefilledpolygon($img, [$img_width*3/10, $img_height*2/10, $img_width*7/10, $img_height*2/10, $img_width*8/10, $img_height*5/10, $img_width*4/10, $img_height*5/10], 4, $red);
32 
33imagefilledarc($img, 100, 100, 100, 100, 0, 360, $orange, IMG_ARC_PIE);
34imagefilledarc($img, $img_width*3/10, $img_height*8/10, 100, 200, 180, 360, $brown, IMG_ARC_PIE);
35 
36imagefilledrectangle($img, 0, $img_height*8/10, $img_width, $img_height, $green);
37 
38imagerectangle($img, $img_width*2/10, $img_height*5/10, $img_width*4/10, $img_height*8/10, $black);
39imagerectangle($img, $img_width*4/10 - 2, $img_height*5/10, $img_width*8/10, $img_height*8/10, $black);
40 
41imagepolygon($img, [$img_width*3/10, $img_height*2/10, $img_width*2/10, $img_height*5/10, $img_width*4/10, $img_height*5/10], 3, $black);
42imageopenpolygon($img, [$img_width*3/10, $img_height*2/10, $img_width*7/10, $img_height*2/10, $img_width*8/10, $img_height*5/10], 3, $black);
43 
44imagearc($img, 100, 100, 100, 100, 0, 360, $black);
45imagearc($img, $img_width*3/10, $img_height*8/10, 100, 200, 180, 360, $black);
46 
47imageline($img, $img_width*9/10, 50, $img_width*9/10, 50, IMG_COLOR_BRUSHED);
48 
49imagerectangle($img, -100, $img_height*8/10, $img_width*11/10, $img_height*11/10, $black);
50 
51imagepng($img);
52?>

نتیجه نهایی کد GD فوق در زبان PHP به صورت زیر است:

PHP GD code

رندر کردن متن روی تصاویر

کتابخانه GD در PHP دارای چهار تابع مختلف است که امکان رندر کردن چندین کاراکتر یا تنها یک کاراکتر را در جهت افقی یا عمودی ارائه‌ کند. این تابع‌ها به صورت ()imagechar() ،imagecharup() ،imagestring و ()imagestringup هستند. همه این تابع‌ها شش پارامتر می‌پذیرند، از این رو صرفاً به بررسی تابع ()imagechar می‌پردازیم.

پارامتر font$ در تابع به سادگی اندازه متن رندر شده را تعیین می‌کند. این پارامتر تنها مقادیر عدد صحیح از 1 تا 5 می‌پذیرد. پارامتر string$ متنی است که می‌خواهیم روی تصویر رندر شود. اگر یک رشته چند کاراکتری به تابع‌های char ارسال کنید تنها کاراکتر نخست روی تصویر رندر خواهد شد. تابع‌های ()imagecharup و ()imagestringup متن را به صورت عمودی از پایین به بالا رندر می‌کنند.

زمانی که نوبت به رندر کردن متن می‌رسد، این چهار تابع که در بخش فوق معرفی کردیم بسیار محدود هستند. متوجه خواهید شد که حتی بزرگ‌ترین اندازه فونت نیز برای استفاده‌های معمول کوچک‌تر از حد نرمال است. ضمناً متن تنها می‌تواند به صورت افقی یا عمودی نوشته شود.

خوشبختانه GD یک تابع به صورت (imagettftext($image, $size, $angle, $x, $y, $color, $fontfile, $text دارد که می‌تواند متن را با هر فونت دلخواهی رندر کند. پارامتر fontfile$ برای تعیین مسیر فونت TrueType دلخواه برای نمایش متن استفاده می‌شود. پارامترهای x$ و y$ موقعیت شروع متن رندر شوند را تعیین می‌کنند.

در مثال زیر همه این تابع‌ها برای ایجاد جلوه‌های زیبایی روی یک متن استفاده می‌شوند.

1<?php
2 
3header("Content-type: image/png");
4$img_width = 800;
5$img_height = 600;
6 
7$img = imagecreatetruecolor($img_width, $img_height);
8 
9$black = imagecolorallocate($img, 0, 0, 0);
10$white = imagecolorallocate($img, 255, 255, 255);
11$red   = imagecolorallocate($img, 255, 0, 0);
12$green = imagecolorallocate($img, 0, 255, 0);
13$blue  = imagecolorallocate($img, 0, 200, 250);
14$orange = imagecolorallocate($img, 255, 200, 0);
15$brown = imagecolorallocate($img, 220, 110, 0);
16 
17imagefill($img, 0, 0, $white);
18 
19imagestringup($img, 5, $img_width*19/20, $img_height*19/20, 'This sentence was written using imagestringup()!', $blue);
20imagestring($img, 5, $img_width/20, $img_height/20, 'This sentence was written using imagestring()!', $red);
21 
22$passion_one = dirname(__FILE__) . '/PassionOne-Regular.ttf';
23imagettftext($img, 32, 0, $img_width/20, $img_height*2/10, $black, $passion_one, 'This is Passion One Font!');
24 
25$merriweather = dirname(__FILE__) . '/Merriweather-Regular.ttf';
26imagettftext($img, 24, 90, $img_width*9/10, $img_height*19/20, $black, $merriweather, 'This is Merriweather Regular Font!');
27 
28$patua_one = dirname(__FILE__) . '/PatuaOne-Regular.ttf';
29imagettftext($img, 32, 0, $img_width/20, $img_height*3/10 + 2, $black, $patua_one, 'This is Patua One Font!');
30imagettftext($img, 32, 0, $img_width/20, $img_height*3/10, $orange, $patua_one, 'This is Patua One Font!');
31 
32$monoton = dirname(__FILE__) . '/Monoton-Regular.ttf';
33imagettftext($img, 72, 0, $img_width/20, $img_height*5.5/10 - 5, $brown, $monoton, 'MONOTON');
34imagettftext($img, 72, 0, $img_width/20, $img_height*5.5/10 + 5, $orange, $monoton, 'MONOTON');
35imagettftext($img, 72, 0, $img_width/20, $img_height*5.5/10, $blue, $monoton, 'MONOTON');
36 
37$kaushan = dirname(__FILE__) . '/KaushanScript-Regular.ttf';
38imagettftext($img, 84, 0, $img_width/20, $img_height*8/10 - 2, $brown, $kaushan, 'Good Night!');
39imagettftext($img, 84, 0, $img_width/20, $img_height*8/10 + 2, $black, $kaushan, 'Good Night!');
40imagettftext($img, 84, 0, $img_width/20 - 2, $img_height*8/10, $brown, $kaushan, 'Good Night!');
41imagettftext($img, 84, 0, $img_width/20 + 2, $img_height*8/10, $black, $kaushan, 'Good Night!');
42imagettftext($img, 84, 0, $img_width/20, $img_height*8/10, $white, $kaushan, 'Good Night!');
43 
44imagepng($img);
45?>

همان طور که مشاهده می‌کنید، ما همان متن را با همان فونت در موقعیت‌های مختلف روی تصویر رندر کرده‌ایم تا برخی جلوه‌ها مانند سایه‌های مقدماتی روی متن ایجاد کنیم. نکته مهم که باید به خاطر داشته باشید این است که متن رندر شده با هر تابع، در نهایت وقتی همپوشانی داشته باشد زیر متن دیگر پنهان می‌شود. تصویر نهایی که پس از اجرای کد فوق به دست می‌آید به صورت زیر است:

php_gd_text

سخن پایانی

هدف این مقاله آشنا ساختن شما با تابع‌های مختلف GD برای رسم شکل‌های ساده از صفر در PHP بوده است. با کمک گرفتن از برخی معادله‌های ساده ریاضی می‌توان از این تابع‌ها برای ایجاد شکل‌های پیچیده‌ای مانند چندضلعی‌های منظم، مستطیل‌های با گوشه‌های گرد و غیره استفاده کرد.

کتابخانه GD در PHP چند تابع بسیار مفید برای رندر کردن متن روی یک تصویر دارد. هنگام استفاده از یک فونت زیبا باید مطمئن شوید که متن رندر شده زمانی که روی تصاویر معمولی بارگذاری شده از مسیرهای مختلف قرار می‌گیرند ظاهر نامناسبی پیدا می‌کند.

اگر این مطلب برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

==

بر اساس رای ۲ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
tutsplus
نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *