Ngày nay, nhu cầu về sử dụng đồ hoạ đang bùng nổ rất mạnh mẽ, kéo theo sự phát triển của các thư viện đồ hoạ trong những năm gần đây. Bài viết ra đời, nhằm cung cấp đến bạn đọc một số hàm để xử lý đồ hoạ trong PHP.
PHP Ryan Lê 2016-03-14 03:30:49

Giới thiệu

Ngày nay, nhu cầu về sử dụng đồ hoạ đang bùng nổ rất mạnh mẽ, kéo theo sự phát triển không có điểm dừng của các thư viện đồ hoạ trong những năm gần đây. Tiêu biểu có thể kể đến OpenGL, DirectX,... và nhiều thư viện đồ hoạ mạnh mẽ khác. Bài viết ra đời, nhằm hướng dẫn đến bạn đọc một số hàm để thao tác, xử lý đồ hoạ trong ngôn ngữ lập trình PHP.  Trong đó, GD cũng chính là thư viện đồ hoạ được tôi đề cập đến trong bài viết này.

Tiền đề bài viết

Trong quá trình phát triển các dự án từ STDIO, tôi thường xuyên được anh La Kiến Vinh giao các công việc liên quan đến xử lý đồ hoạ. Do đó tôi có nhiều cơ hội để tiếp xúc đến nhiều thư viện đồ hoạ khác nhau để phục vụ cho nhiều công việc. Mới đây, tôi lại có dịp làm quen với GD - một thư viện đồ hoạ cũng được sử dụng khá rộng rãi hiện nay. Được sự đề nghị từ anh, tôi chia sẻ đến bạn đọc một số kiến thức cơ bản mà tôi tích luỹ được.

Đối tượng hướng đến

Để dễ dàng hiểu và vận dụng được các kiến thức tôi cung cấp trong bài viết, đối tượng cần nắm rõ về ngôn ngữ lập trình PHP. Các đối tượng còn lại cũng có thể xem bài viết theo tiêu chí là tham khảo.

Sơ lược về thư viện đồ hoạ GD

Trước khi bước vào nội dung chính của bài, tôi xin trình bày sơ lược về một số thông tin liên quan đến thư viện đồ hoạ này.

GD được ra đời bởi Thomas Boutell và các thành viên khác trong nhóm ông lần đầu tiên vào năm 1994. GD là một mã nguồn mở, được xây dựng từ ANSI C và có giao diện cho nhiều loại ngôn ngữ lập trình khác nhau, có thể kể đến như Perl, Python, PHP,... Phiên bản mới nhất hiện đang được sử dụng và mang tính ổn định cao là 2.1.1, được tung ra vào ngày 14/01/2015. Các lập trình viên thường sử dụng thư viện này để hỗ trợ cho việc vẽ biểu đồ, đồ hoạ, hình ảnh, hoặc bất kỳ một thứ gì khác mà nó hỗ trợ.

Hiện nay, PHP được biết đến là ngôn ngữ sử dụng GD nhiều nhất. Và cũng trong bài viết này, PHP cũng chính là đối tượng được tôi sử dụng để chia sẻ kiến thức, cụ thể là các hàm để xử lý đồ hoạ được cung cấp từ thư viện GD.

Một số hàm thông dụng

Thư viện GD cung cấp một số lượng lớn hàm nhằm hỗ trợ nhiều chức năng khác nhau cho người sử dụng. Sau khi tìm hiểu và làm việc với nó, tôi chọn lọc ra một số hàm mà tôi cho là thông dụng nhất để trình bày trong bài viết này.

imagecreate

Hàm này hỗ trợ tạo nên một hình ảnh, chính xác hơn thì nó sẽ tạo ra một khung hình có kích thước, mà từ đó người dùng có thể thực hiện các thao tác khác tại đây. Bạn vui lòng xem các ví dụ bên dưới để hiểu rõ hơn.

Cú pháp

resource imagecreate(int $width, int $height)

Trong đó: $width$height là kích thước hình cần tạo.

Bạn cũng có thể tìm hiểu thêm về hàm imagecreatetruecolor() để tạo một khung ảnh tương tự như trên.

imagecreatefrompng

Bên cạnh việc tạo một khung ảnh như ở hàm bên trên, bạn cũng có thể tạo một khung ảnh để làm việc với một tấm hình PNG cho trước.

Cú pháp

resource imagecreatefrompng(string $filepath)

Trong đó: $filepath là đường dẫn đến file hình ảnh cần khởi tạo.

Bạn cũng có thể thực hiện tương tự với một tấm hình JPEG với hàm imagecreatefromjpeg().

imagepng và imagejpeg

Trong quá trình thực hiện các thao tác của bạn lên khung ảnh, chắc chắn rằng lúc nào đó bạn sẽ cần lưu lại các thao tác đó, hoặc hiển thị chúng ra ngoài. Thì khi đó imagepng()imagejpeg() sẽ là 2 lựa chọn của bạn. Ở dưới tôi sẽ chỉ mô tả cú pháp của imagepng() và bạn hoàn toàn có thể thao tác tương tự với imagejpeg().

Cú pháp

bool imagepng(resource $image[, string $filepath[, int $quality[, int $filters]]])

Trong đó:

  • $image là biến chứa đối tượng mà bạn đã thao tác lên đó.
  • $filepath là đường dẫn nơi bạn lưu trữ file. Nếu không có, hoặc đường dẫn không tồn tại, đối tượng sẽ được xuất ra.
  • $quality là mức độ nén, có giá trị từ 0 đến 9.
  • $filters là bộ lọc cho phép giảm kích thước của hình ảnh.

imagedestroy

Bên cạnh việc khởi tạo một hình ảnh thì GD cũng cung cấp cho người sử dụng cách để huỷ đối tượng đó ra khỏi vùng nhớ.

Cú pháp

bool imagedestroy(resource $image)

Trong đó: $image là biến chứa đối tượng cần huỷ.

imagecolorallocate

Giúp khởi tạo một màu sắc kiểu RGB được truyền vào từ tham số của hàm.

Cú pháp

int imagecolorallocate(resource $image, int $red, int $green, int $blue)

Trong đó:

  • $image là biến chứa đối tượng mà bạn đang thao tác lên đó.
  • $red$green$blue chứa giá trị của 3 kênh màu RGB tương ứng.

Bạn có thể tự tìm hiểu thêm hàm imagecolorallocatealpha() để khởi tạo một màu sắc khác với cách trên.

imagefilledrectangle

Hàm vẽ hình chữ nhật đầy (hình chữ nhật không rỗng bên trong). Bạn có thể tự tìm hiểu cách vẽ hình chữ nhật rỗng bên trong với hàm imagerectangle().

Cú pháp

bool imagefilledrectangle(resource $image, int $x1, int $y1, int $x2, int $y2, int $color)

Trong đó:

  • $image là đối tượng đang thao tác.
  • $x1, $y1 là toạ độ điểm đầu.
  • $x1, $y1 là toạ độ điểm cuối.
  • $color là màu sắc của hình chữ nhật.

Lưu ý: Điểm đầu và điểm cuối ở đây là 2 điểm đối nhau qua đường chéo của hình chữ nhật

imagestring

Hàm này cho phép vẽ một chuỗi ký tự.

Cú pháp

bool imagestring(resource $image, int $font, int $x, int $y, string $string, int $color)

Trong đó:

  • $image là đối tượng bạn đang thao tác đến.
  • $font là font chữ bạn mong muốn. Có thể chọn từ 1 đến 5 để sử dụng các font đã hỗ trợ sẵn, hoặc bạn cũng có thể load một font mới với hàm imageloadfont().
  • $x, $y là toạ độ vị trí cần vẽ (toạ độ này được tính ở góc trên bên trái khi chuỗi được vẽ ra).
  • $string là chuỗi cần vẽ.
  • $color là màu sắc của chuỗi khi vẽ.

Bạn có thể tự tìm hiểu thêm một hàm để vẽ chuỗi khác là imagettftext().

imageftbbox

Cú pháp

array imageftbbox(float $size, float $angle, string $fontfile, string $text)

Trong đó:

  • $size là font size của chuỗi truyền vào.
  • $angle là tỷ lệ quay của chuỗi. 0 ứng với bình thường, 45 ứng với chữ sẽ nghiêng 45 độ, 360 ứng với bình thường,...
  • $fontfile là font chữ của chuỗi.
  • $text là chuỗi truyền vào.

Nhận vào một chuỗi và các thông số liên quan rồi trả về một mảng gồm 8 phần tử chứa toạ độ các điểm như sau:

  • Phần tử 0 và 1: Toạ độ của x và y tại vị trí góc dưới bên trái của chuỗi.
  • Phần tử 2 và 3: Toạ độ của x và y tại vị trí góc dưới bên phải của chuỗi.
  • Phần tử 4 và 5: Toạ độ của x và y tại vị trí góc trên bên phải của chuỗi.
  • Phần tử 6 và 7: Toạ độ của x và y tại vị trí góc trên bên trái của chuỗi.

Bằng cách có được toạ độ các điểm này bạn có thể dễ dàng tính được độ dài, rộng của một chuỗi như sau:

function GetWidthString($str, $font_size, $font)
{
	$dims = imagettfbbox($font_size, 0, $font, $str);
	return ($dims[4] - $dims[6]);
}

function GetHeighString($str, $font_size, $font)
{
	$dims = imagettfbbox($font_size, 0, $font, $str);
	return ($dims[3] - $dims[5]);
}

Lưu ý: Vì các chuỗi tôi cần dùng không có tỷ lệ quay nên tôi mặc định là 0, bạn cũng có thể xây dựng một hàm khác cho phù hợp hơn với công việc bạn cần làm.

imagecopymerge

Hỗ trợ lấy một phần (hoặc toàn bộ) tấm ảnh này vẽ lên một tấm ảnh khác tại vị trí mong muốn.

Cú pháp

bool imagecopymerge(resource $dst_im, resource $src_im, int $dst_x, int $dst_y,
                    int $src_x, int $src_y, int $src_w, int $src_h, int $pct)

Trong đó:

  • $dst_im là tấm ảnh được vẽ lên.
  • $src_im là tấm ảnh cần lấy để vẽ.
  • $dst_x, $dst_y là vị trí muốn vẽ trên tấm ảnh được vẽ.
  • $src_x, $src_y là vị trí để bắt đầu lấy tấm ảnh.
  • $src_w, $src_h là chiều rộng và chiều dài cần lấy từ tấm ảnh cần lấy.
  • $pct là độ trong suốt của phần ảnh sau khi được vẽ lên, có giá trị từ 1 đến 100.

Một số ví dụ

Để bạn đọc dễ dàng nắm bắt được, và hiểu rõ hơn về các hàm nói trên, tôi tiến hành build một số ví dụ như sau:

Ví dụ 1

Vẽ một khung ảnh với màu đen với kích thước 200x200

<?php
header("Content-Type: image/png");
$im = imagecreate(200, 200);
$background_color = imagecolorallocate($im, 0, 0, 0);
imagepng($im);
imagedestroy($im);
?>

Kết quả

example_1

Ví dụ 2

Tạo một khung ảnh với một tấm ảnh cho trước và vẽ một tấm ảnh khác lên tấm ảnh đó. Cụ thể tôi sẽ có 2 tấm ảnh như sau:

example_2a

Tôi mong muốn sẽ vẽ tấm ảnh thứ 2 vào ô trắng của tấm ảnh thứ 1(toạ độ tại điểm cần vẽ là 66, 38). Đoạn code sau sẽ giúp tôi thực hiện điều đó:

<?php
$dest = imagecreatefrompng ('dest_image.png');
$src = imagecreatefrompng('src_image.png');
imagecopymerge($dest, $src, 66, 38, 0, 0, 256, 256, 100);
imagepng($dest);
imagedestroy($src);
imagedestroy($dest);
?>

Kết quả

example_2b

Ví dụ 3

Vẽ một chuỗi ký tự  'Hello STDIO!' với màu trắng và có nền màu cam.

<?php
header("Content-Type: image/png");
$im = imagecreate(200, 200);
$background_color = imagecolorallocate($im, 183, 183, 183);

$color_text = imagecolorallocate($im, 255, 255, 255);
$background_text = imagecolorallocate($im, 236, 135, 14);

//draw background
imagefilledrectangle($im, 40, 45, 160, 70, $background_text);
//draw text
imagestring($im, 5, 50, 50, 'Hello STDIO!', $color_text);

imagepng($im);
imagedestroy($im);
?>

Kết quả

example_3

Tổng kết

Sử dụng cái gì đó có sẵn là không khó, chỉ cần bạn dành thời gian để tìm hiểu, tôi tin chắc bạn sẽ chinh phục được. Kết thúc bài viết, tôi mong muốn gửi đến bạn đọc một nguồn tài liệu mới để tham khảo, từ đó có thể tìm hiểu thêm phục vụ cho việc phát triển các sản phẩm của các bạn.

Tham khảo

http://libgd.github.io