php
How to create dynamic images with C#?
Overview
Lang.Php.Graph namespace contains Image class that represents PHP resource related to GD image that can be obtained using functions like imagecreatetruecolor
. Image class is also container for image related methods.
On PHP side we have a number of functions with name starting from image
prefix accepting GD image resource as first argument like this.
1 |
int imagecolorallocate ( resource $image , int $red , int $green , int $blue ) |
On C# side we can use instance methods usually with shorter names and with reduced argument list. For example imagecreatetruecolor
equivalent is defined as:
1 2 |
[DirectCall("imagecolorallocate", "this,0,1,2")] public Color ColorAllocate(int red, int green, int blue) |
And we can use this method like this:
1 |
var color = myImage.ColorAllocate(0, 127, 255); |
Color, Font and other
Lets take a look at imagestring
function defined as
1 |
bool imagestring ( resource $image , int $font , int $x , int $y , string $string , int $color ) |
This function accepts font and color as integer value, so it is easy to make mistake by putting any integer value that was not intended to be font or color.
To avoid this ambiguity Lang.Php.Graph
namespace contains classes like Color
or Font
. By using this classes we can produce more reliable code even if on PHP side they are nothing more than integers. That’s why DrawString (imagestring equivalent) is defined as
1 2 |
[DirectCall("imagestring", "this,0,1,2,3,4")] public bool DrawString(Font font, int x, int y, string text, Color color) |
How can we use Color
class?
ColorAllocate
method returns Color
while its PHP prototype returns int
(if success) or FALSE
when action fails.
Meticulous approach to programming requires error checking. Color
class contains static function IsValid
, defined as
1 2 |
[UseBinaryExpression("!==", "false", "$0")] public static bool IsValid(Color image) |
And its typical usage is
1 2 3 |
color = myImage.ColorAllocate(i, 255 - i, 0); if (Color.IsValid(color)) myImage.DrawLine(0, HEIGHT - 1, i, 0, color); |
which is translated into
1 2 3 |
$color = imagecolorallocate($myImage, $i, 255 - $i, 0); if (false !== $color) imageline($myImage, 0, self::HEIGHT - 1, $i, 0, $color); |
Example
Code below is a part of example available on GitHub. Class DynamicImage
can generate images like this
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
[Page("image")] class DynamicImage : PhpDummy { #region Static Methods // Public Methods public static void PhpMain() { int compression = FilterInput.ValidateInt(FilterInput.Type.Get, "compression", IntFlags.AllowHex, new IntOptions() { Default = 90 }).Value; if (Script.Get.ContainsKey("format") && Script.Get["format"] == "jpg") CreateImage(true, compression); else CreateImage(false, compression); } // Private Methods private static void CreateImage(bool jpg, int compression) { if (compression < 0) compression = 0; else if (compression > 100) compression = 100; if (jpg) header(Image.HEADER_CONTENT_TYPE_JPG); else header(Image.HEADER_CONTENT_TYPE_PNG); var myImage = Image.CreateTrueColor(WIDTH, HEIGHT); if (Image.IsValid(myImage)) { Color color = myImage.ColorAllocate(255, 0, 0); // first call is background for (int i = 0; i < WIDTH; i++) { color = myImage.ColorAllocate(i, 255 - i, 0); myImage.DrawLine(0, HEIGHT - 1, i, 0, color); color = myImage.ColorAllocate(i, 0, 255 - i); myImage.DrawLine(WIDTH - 1, 0, WIDTH - 1 - i, HEIGHT - 1, color); } color = myImage.ColorAllocate(0, 0, 255); myImage.DrawString(Font.Font4, 10, 30, "Hello", color); color = myImage.ColorAllocate(255, 255, 255); myImage.DrawString(Font.Font4, 10, 50, "C# to PHP is fantastic", color); if (jpg) myImage.Jpeg(null, compression); else myImage.Png(); myImage.Destroy(); } } #endregion Static Methods #region Fields public const int HEIGHT = 100; public const int WIDTH = 256; #endregion Fields } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
class DynamicImage { const HEIGHT = 100; const WIDTH = 256; public static function PhpMain() { global $_GET; $compression = filter_input(INPUT_GET, 'compression', FILTER_VALIDATE_INT, array('options' => array('default' => 90), 'flags' => FILTER_FLAG_ALLOW_HEX)); if (array_key_exists('format', $_GET) && $_GET['format'] == 'jpg') self::CreateImage(true, $compression); else self::CreateImage(false, $compression); } private static function CreateImage($jpg, $compression) { if ($compression < 0) $compression = 0; else if ($compression > 100) $compression = 100; if ($jpg) header('Content-Type: image/jpg'); else header('Content-Type: image/png'); $myImage = imagecreatetruecolor(self::WIDTH, self::HEIGHT); if (false !== $myImage) { $color = imagecolorallocate($myImage, 255, 0, 0); for($i = 0; $i < self::WIDTH; $i++) { $color = imagecolorallocate($myImage, $i, 255 - $i, 0); imageline($myImage, 0, self::HEIGHT - 1, $i, 0, $color); $color = imagecolorallocate($myImage, $i, 0, 255 - $i); imageline($myImage, self::WIDTH - 1, 0, self::WIDTH - 1 - $i, self::HEIGHT - 1, $color); } $color = imagecolorallocate($myImage, 0, 0, 255); imagestring($myImage, 4, 10, 30, 'Hello', $color); $color = imagecolorallocate($myImage, 255, 255, 255); imagestring($myImage, 4, 10, 50, 'C# to PHP is fantastic', $color); if ($jpg) imagejpeg($myImage, null, $compression); else imagepng($myImage); imagedestroy($myImage); } } } |