Skip to content

Commit

Permalink
Add supported for WEBP
Browse files Browse the repository at this point in the history
* Supported crop, resize (aspect ratio and not), rotate, flip, watermark text and image.
* From webp can save/show as gif, jpg, png, webp.
* Transparency webp is not supported prior PHP 7.0. Can't fix.
* Animated webp is not supported for both GD and Imagick.
  • Loading branch information
ve3 committed Jul 28, 2021
1 parent 5554a75 commit 48a7b10
Show file tree
Hide file tree
Showing 26 changed files with 403 additions and 253 deletions.
4 changes: 4 additions & 0 deletions Rundiz/Image/AbstractImage.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ public function __set($name, $value)
*/
protected function buildSourceImageData($source_image_path)
{
$WebP = new Extensions\WebP();
$WebP->checkWebPConstant();
unset($WebP);

if (is_file($source_image_path)) {
$source_image_path = realpath($source_image_path);
$image_data = $this->getImageFileData($source_image_path);
Expand Down
6 changes: 6 additions & 0 deletions Rundiz/Image/AbstractProperties.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,10 @@ abstract class AbstractProperties
protected $watermark_image_height;


/**
* Unable to set source image from this kind of image.
*/
const RDIERROR_SOURCE_IMG_NOT_SUPPORTED = 1;


}
8 changes: 7 additions & 1 deletion Rundiz/Image/Drivers/Gd.php
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,13 @@ private function setupSourceImageObject()
// add alpha, alpha blending to support transparency png
imagealphablending($this->source_image_object, false);
imagesavealpha($this->source_image_object, true);
}
} elseif ($this->source_image_type === IMAGETYPE_WEBP) {
// webp
$this->source_image_object = imagecreatefromwebp($this->source_image_path);
// add alpha, alpha blending to support transparency png
imagealphablending($this->source_image_object, false);
imagesavealpha($this->source_image_object, true);
}// endif;

if ($this->source_image_object != null) {
$this->status = true;
Expand Down
87 changes: 45 additions & 42 deletions Rundiz/Image/Drivers/Gd/Crop.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,48 +58,38 @@ public function execute($width, $height, $start_x = '0', $start_y = '0', $fill =
}

// begins crop
if ($this->Gd->source_image_type === IMAGETYPE_GIF) {
// gif
if ($fill == 'transparent') {
imagefill($this->Gd->destination_image_object, 0, 0, $transwhite);
imagecolortransparent($this->Gd->destination_image_object, $transwhite);
} else {
imagefill($this->Gd->destination_image_object, 0, 0, $$fill);
}

imagecopy($this->Gd->destination_image_object, $this->Gd->source_image_object, 0, 0, $start_x, $start_y, $width, $height);

// fill "again" in case that cropping image is larger than source image.
if ($width > imagesx($this->Gd->source_image_object) || $height > imagesy($this->Gd->source_image_object)) {
switch ($this->Gd->source_image_type) {
case IMAGETYPE_GIF:
// fill first time to prevent transparency become black.
if ($fill == 'transparent') {
imagefill($this->Gd->destination_image_object, 0, 0, $transwhite);
imagecolortransparent($this->Gd->destination_image_object, $transwhite);
} else {
imagefill($this->Gd->destination_image_object, 0, 0, $$fill);
}
}
} elseif ($this->Gd->source_image_type === IMAGETYPE_JPEG) {
// jpg
imagecopy($this->Gd->destination_image_object, $this->Gd->source_image_object, 0, 0, $start_x, $start_y, $width, $height);

if ($fill != 'transparent') {
imagefill($this->Gd->destination_image_object, 0, 0, $$fill);
}
} elseif ($this->Gd->source_image_type === IMAGETYPE_PNG) {
// png
if ($fill == 'transparent') {
imagefill($this->Gd->destination_image_object, 0, 0, $transwhite);
imagecolortransparent($this->Gd->destination_image_object, $black);
imagealphablending($this->Gd->destination_image_object, false);
imagesavealpha($this->Gd->destination_image_object, true);
} else {
imagefill($this->Gd->destination_image_object, 0, 0, $$fill);
}

imagecopy($this->Gd->destination_image_object, $this->Gd->source_image_object, 0, 0, $start_x, $start_y, $width, $height);

// fill "again" in case that cropping image is larger than source image.
if ($width > imagesx($this->Gd->source_image_object) || $height > imagesy($this->Gd->source_image_object)) {
// do crop.
imagecopy($this->Gd->destination_image_object, $this->Gd->source_image_object, 0, 0, $start_x, $start_y, $width, $height);
// fill "again" in case that cropping image is larger than source image.
if ($width > imagesx($this->Gd->source_image_object) || $height > imagesy($this->Gd->source_image_object)) {
if ($fill == 'transparent') {
imagefill($this->Gd->destination_image_object, 0, 0, $transwhite);
imagecolortransparent($this->Gd->destination_image_object, $transwhite);
} else {
imagefill($this->Gd->destination_image_object, 0, 0, $$fill);
}
}
break;
case IMAGETYPE_JPEG:
// do crop.
imagecopy($this->Gd->destination_image_object, $this->Gd->source_image_object, 0, 0, $start_x, $start_y, $width, $height);
// do fill.
if ($fill != 'transparent') {
imagefill($this->Gd->destination_image_object, 0, 0, $$fill);
}
break;
case IMAGETYPE_PNG:
case IMAGETYPE_WEBP:
// fill first time to prevent transparency become black.
if ($fill == 'transparent') {
imagefill($this->Gd->destination_image_object, 0, 0, $transwhite);
imagecolortransparent($this->Gd->destination_image_object, $black);
Expand All @@ -108,12 +98,25 @@ public function execute($width, $height, $start_x = '0', $start_y = '0', $fill =
} else {
imagefill($this->Gd->destination_image_object, 0, 0, $$fill);
}
}
} else {
$this->Gd->status = false;
$this->Gd->status_msg = 'Unable to crop this kind of image.';
return false;
}
// do crop.
imagecopy($this->Gd->destination_image_object, $this->Gd->source_image_object, 0, 0, $start_x, $start_y, $width, $height);
// fill "again" in case that cropping image is larger than source image.
if ($width > imagesx($this->Gd->source_image_object) || $height > imagesy($this->Gd->source_image_object)) {
if ($fill == 'transparent') {
imagefill($this->Gd->destination_image_object, 0, 0, $transwhite);
imagecolortransparent($this->Gd->destination_image_object, $black);
imagealphablending($this->Gd->destination_image_object, false);
imagesavealpha($this->Gd->destination_image_object, true);
} else {
imagefill($this->Gd->destination_image_object, 0, 0, $$fill);
}
}
break;
default:
$this->Gd->status = false;
$this->Gd->status_msg = 'Unable to crop this kind of image.';
return false;
}// endswitch;

// clear unused variables
if ($this->isResourceOrGDObject($this->Gd->source_image_object)) {
Expand Down
44 changes: 23 additions & 21 deletions Rundiz/Image/Drivers/Gd/Resize.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,27 +32,29 @@ public function execute($width, $height)
}

// begins resize
if ($this->Gd->source_image_type === IMAGETYPE_GIF) {
// gif
$transwhite = imagecolorallocatealpha($this->Gd->destination_image_object, 255, 255, 255, 127);
imagefill($this->Gd->destination_image_object, 0, 0, $transwhite);
imagecolortransparent($this->Gd->destination_image_object, $transwhite);
imagecopyresampled($this->Gd->destination_image_object, $this->Gd->source_image_object, 0, 0, 0, 0, $width, $height, $source_image_width, $source_image_height);
unset($transwhite);
} elseif ($this->Gd->source_image_type === IMAGETYPE_JPEG) {
// jpg
imagecopyresampled($this->Gd->destination_image_object, $this->Gd->source_image_object, 0, 0, 0, 0, $width, $height, $source_image_width, $source_image_height);
} elseif ($this->Gd->source_image_type === IMAGETYPE_PNG) {
// png
imagealphablending($this->Gd->destination_image_object, false);
imagesavealpha($this->Gd->destination_image_object, true);
imagecopyresampled($this->Gd->destination_image_object, $this->Gd->source_image_object, 0, 0, 0, 0, $width, $height, $source_image_width, $source_image_height);
} else {
$this->Gd->status = false;
$this->Gd->status_msg = 'Unable to resize this kind of image.';
unset($source_image_height, $source_image_width);
return false;
}
switch ($this->Gd->source_image_type) {
case IMAGETYPE_GIF:
$transwhite = imagecolorallocatealpha($this->Gd->destination_image_object, 255, 255, 255, 127);
imagefill($this->Gd->destination_image_object, 0, 0, $transwhite);
imagecolortransparent($this->Gd->destination_image_object, $transwhite);
imagecopyresampled($this->Gd->destination_image_object, $this->Gd->source_image_object, 0, 0, 0, 0, $width, $height, $source_image_width, $source_image_height);
unset($transwhite);
break;
case IMAGETYPE_JPEG:
imagecopyresampled($this->Gd->destination_image_object, $this->Gd->source_image_object, 0, 0, 0, 0, $width, $height, $source_image_width, $source_image_height);
break;
case IMAGETYPE_PNG:
case IMAGETYPE_WEBP:
imagealphablending($this->Gd->destination_image_object, false);
imagesavealpha($this->Gd->destination_image_object, true);
imagecopyresampled($this->Gd->destination_image_object, $this->Gd->source_image_object, 0, 0, 0, 0, $width, $height, $source_image_width, $source_image_height);
break;
default:
$this->Gd->status = false;
$this->Gd->status_msg = 'Unable to resize this kind of image.';
unset($source_image_height, $source_image_width);
return false;
}// endswitch;

// clear unused variable
if ($this->isResourceOrGDObject($this->Gd->source_image_object)) {
Expand Down
4 changes: 1 addition & 3 deletions Rundiz/Image/Drivers/Gd/Rotate.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ public function execute($degree = 90)
// rotate by degree
switch ($this->Gd->source_image_type) {
case IMAGETYPE_GIF:
// gif
// set source image width and height
$source_image_width = imagesx($this->Gd->source_image_object);
$source_image_height = imagesy($this->Gd->source_image_object);
Expand All @@ -46,13 +45,12 @@ public function execute($degree = 90)
unset($source_image_height, $source_image_width, $transwhite);
break;
case IMAGETYPE_JPEG:
// jpg
$white = imagecolorallocate($this->Gd->source_image_object, 255, 255, 255);
$this->Gd->destination_image_object = imagerotate($this->Gd->source_image_object, $degree, $white);
unset($white);
break;
case IMAGETYPE_PNG:
// png
case IMAGETYPE_WEBP:
$transwhite = imageColorAllocateAlpha($this->Gd->source_image_object, 0, 0, 0, 127);
$this->Gd->destination_image_object = imagerotate($this->Gd->source_image_object, $degree, $transwhite);
imagealphablending($this->Gd->destination_image_object, false);
Expand Down
15 changes: 11 additions & 4 deletions Rundiz/Image/Drivers/Gd/Save.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,24 @@ public function execute($file_name)
// save to file. each image types use different ways to save.
if ($check_file_ext === 'gif') {
// if save to gif
if ($this->Gd->source_image_type === IMAGETYPE_PNG) {
// if source image is png file.
if (
$this->Gd->source_image_type === IMAGETYPE_PNG ||
$this->Gd->source_image_type === IMAGETYPE_WEBP
) {
// if source image is png or webp file.
// preserve transparency part.
$this->fillTransparentDestinationImage();
}

$save_result = imagegif($this->Gd->destination_image_object, $file_name);
} elseif ($check_file_ext === 'jpg') {
// if save to jpg
if ($this->Gd->source_image_type === IMAGETYPE_PNG || $this->Gd->source_image_type === IMAGETYPE_GIF) {
// if source image is png or gif file.
if (
$this->Gd->source_image_type === IMAGETYPE_PNG ||
$this->Gd->source_image_type === IMAGETYPE_GIF ||
$this->Gd->source_image_type === IMAGETYPE_WEBP
) {
// if source image is png or gif or webp file.
// convert transparency png to white before save.
$this->fillWhiteDestinationImage();
}
Expand Down
15 changes: 11 additions & 4 deletions Rundiz/Image/Drivers/Gd/Show.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,11 @@ public function execute($file_ext = '')
// show image to browser.
if ($check_file_ext === 'gif') {
// if save to gif
if ($this->Gd->source_image_type === IMAGETYPE_PNG) {
// if source image is png file.
if (
$this->Gd->source_image_type === IMAGETYPE_PNG ||
$this->Gd->source_image_type === IMAGETYPE_WEBP
) {
// if source image is png or webp file.
// preserve transparency part.
$this->fillTransparentDestinationImage();
}
Expand All @@ -47,8 +50,12 @@ public function execute($file_ext = '')
}
} elseif ($check_file_ext === 'jpg') {
// if save to jpg
if ($this->Gd->source_image_type === IMAGETYPE_PNG || $this->Gd->source_image_type === IMAGETYPE_GIF) {
// if source image is png or gif file.
if (
$this->Gd->source_image_type === IMAGETYPE_PNG ||
$this->Gd->source_image_type === IMAGETYPE_GIF ||
$this->Gd->source_image_type === IMAGETYPE_WEBP
) {
// if source image is png or gif or webp file.
// convert transparency png to white before save.
$this->fillWhiteDestinationImage();
}
Expand Down
7 changes: 1 addition & 6 deletions Rundiz/Image/Drivers/Gd/Watermark.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,10 @@ public function applyImage($wm_img_start_x = 0, $wm_img_start_y = 0)
{
switch ($this->Gd->watermark_image_type) {
case IMAGETYPE_GIF:
// gif
case IMAGETYPE_JPEG:
// jpg
imagecopy($this->Gd->source_image_object, $this->Gd->watermark_image_object, $wm_img_start_x, $wm_img_start_y, 0, 0, $this->Gd->watermark_image_width, $this->Gd->watermark_image_height);
break;
case IMAGETYPE_PNG:
// png
if ($this->Gd->source_image_type === IMAGETYPE_GIF) {
// if source image is gif (which maybe transparent) and watermark image is png. so, this cannot just use imagecopy() function.
// see more at http://stackoverflow.com/questions/4437557/using-gd-in-php-how-can-i-make-a-transparent-png-watermark-on-png-and-gif-files
Expand Down Expand Up @@ -208,7 +205,6 @@ public function applyText(
// copy text to image
switch ($this->Gd->source_image_type) {
case IMAGETYPE_GIF:
// gif
$this->applyWatermarkToGifImage(
$wm_txt_object,
$wm_txt_width,
Expand All @@ -218,10 +214,9 @@ public function applyText(
);
break;
case IMAGETYPE_PNG:
// png
case IMAGETYPE_WEBP:
imagealphablending($this->Gd->source_image_object, true);
case IMAGETYPE_JPEG:
// jpg
default:
imagecopy($this->Gd->source_image_object, $wm_txt_object, $wm_txt_start_x, $wm_txt_start_y, 0, 0, $wm_txt_width, $wm_txt_height);
break;
Expand Down
Loading

0 comments on commit 48a7b10

Please sign in to comment.