This is a challenge for me and since I did not code for more than 3 years, so, look for advice.
The idea is to design a basic but expendable application to perform several actions on the image such resize and rotate.
Per SOLID Single Responsibility (SRP), each action is needed to be coded as a separate class. Another important task is to implement presets as separated classes including one or more of the implemented actions.
The following is what I did, unfortunately it violates the rules and seems not expandable.
This is the Action class, the parent class for actions such as Resize and Watermark:
<?php
class Action
{
protected $image;
protected $mimeType;
protected $extension;
protected $w, $h;
public function __construct($source)
{
if ($source) {
$info = getimagesize($source);
$this->mimeType = $info['mime'];
$this->w = $info[0];
$this->h = $info[1];
$this->extension = substr(strrchr($source, '.'), 0);
$this->loadImage($source);
}
}
public function getImage()
{
return $this->image;
}
public function loadImage($source)
{
switch ($this->mimeType) {
case 'image/jpeg':
$this->image = imagecreatefromjpeg($source);
break;
case 'image/png':
$this->image = imagecreatefrompng($source);
break;
case 'image/gif':
$this->image = imagecreatefromgif($source);
break;
default:
throw new Exception('Invalid image: ' . $source);
break;
}
}
public function saveImage($filename, $quality = 80)
{
header('Content-type: ' . $this->mimeType);
$filename .= $this->extension;
switch ($this->mimeType) {
case 'image/jpeg':
$result = imagejpeg($this->image, $filename, round($quality));
break;
case 'image/png':
$result = imagepng($this->image, $filename, round(9 * $quality / 100));
break;
case 'image/gif':
$result = imagegif($this->image, $filename);
break;
default:
throw new Exception('Unsupported format');
}
if (!$result) {
throw new Exception('Unable to save image: ' . $filename);
}
}
public function __destruct()
{
if ($this->image) {
imagedestroy($this->image);
}
}
}
This is the Watermark action class:
<?php
require_once("Action.php");
class WaterMark extends Action {
private $text;
private $x, $y;
private $fontSize;
private $font;
private $color;
public function __construct($source, $fontSize, $x, $y, $text) {
parent::__construct($source);
$this->fontSize = $fontSize;
$this->x = $x;
$this->y = $y;
$this->text = $text;
}
public function setFont($path = './fonts/ChelaOne-Regular.ttf') {
$this->font = $path;
}
public function setColor($red = 200, $green = 150, $blue = 240) {
// setup the text color
$this->color = imagecolorallocate($this->image, $red, $green, $blue);
}
public function watermark() {
imagettftext($this->image, $this->fontSize, 0, $this->x, $this->y, $this->color, $this->font, $this->text);
// imagefilter($this->image, IMG_FILTER_GRAYSCALE);
// parent::saveImage('watermark aaaaa');
}
}
This is the Rotate action class:
<?php
require_once("Action.php");
class Rotate extends Action {
private $angle;
public function __construct($source, $angle = 45) {
parent::__construct($source);
$this->angle = $angle;
}
public function rotate() {
$this->image = imagerotate($this->image, $this->angle, 0);
//parent::saveImage('rotate');
}
}
I have other action classes. These are working charmingly individually using the following CLI command:
php apply.php source.jpg watermarkImage
Here is the apply.php
<?php
require_once("Watermark.php");
$source = $argv[1];
$filename = $argv[2];
$watermark = new Watermark($source, 40, 100, 150, "Copyright 2018");
$watermark->setFont();
$watermark->watermark();
$watermark->saveImage($filename);
?>
I would like to have your feedback improving the above scenario as well as the default presets classes including one or more of the actions to be used like this:
php apply.php PresetName source.jpg watermarkImage
I am sure these sort of challenges improve the capacity building of others interested to design and code better.
Thank you in advance,
Aucun commentaire:
Enregistrer un commentaire