/classes/MediaAndFileUtil/ImageUtil.php
PHP | 473 lines | 431 code | 21 blank | 21 comment | 70 complexity | ec1ff0f0e706048a03c0d818419bdaa9 MD5 | raw file
Possible License(s): AGPL-3.0
- <?php
- namespace Indybay\MediaAndFileUtil;
- use Indybay\Common;
- use Indybay\DB\MediaAttachmentDB;
- /**
- * Main class for image management.
- *
- * This is mainly just a series of wrappers around php functions that may be
- * useful if we ever want to change which functions are used.
- *
- * Written December 2005
- * * Modification Log:
- * 12/2005-1/2005 zogren/Zachary Ogren/zogren@yahoo.com
- * initial development.
- */
- class ImageUtil extends Common {
- /**
- * Scales image by width.
- */
- public function scaleImageByWidthIfTooLarge($file_name, $copy_from, $copy_to, $max_width, $max_height = 0, $crop_height_and_fix_width = 0, $rotate = 0) {
- $new_file_info = [];;
- $new_file_info['file_name'] = $file_name;
- if (!file_exists($copy_from)) {
- echo $copy_from . ' does not exist!<br />';
- exit;
- }
- if (file_exists($copy_to)) {
- echo $copy_to . ' already exists!<br />';
- exit;
- }
- list($width_orig, $height_orig, $type) = getimagesize($copy_from);
- $new_file_info['image_width'] = $width_orig;
- $new_file_info['image_height'] = $height_orig;
- $new_file_info['file_size'] = filesize($copy_from);
- if ($max_width == 0) {
- $max_width = $width_orig;
- }
- if ($max_height == 0) {
- $max_height = $height_orig;
- }
- if ($width_orig > $max_width || $height_orig > $max_height ||
- ($crop_height_and_fix_width == 1 && ($width_orig != $max_width || $height_orig != $max_height)) || $rotate > 0) {
- $image_orig = '';
- if (strpos(strtolower($copy_to), '.jpeg') > 0 || strpos(strtolower($copy_to), '.jpg') > 0) {
- $image_orig = imagecreatefromjpeg($copy_from);
- }
- elseif (strpos($copy_to, '.png') > 0 || strpos($copy_to, '.png') > 0) {
- $image_orig = imagecreatefrompng($copy_from);
- if ($image_orig != '') {
- $copy_to = str_replace('.png', '.jpg', $copy_to);
- $file_name = str_replace('.png', '.jpg', $file_name);
- }
- }
- elseif (strpos($copy_to, '.gif') > 0 || strpos($copy_to, '.gif') > 0) {
- if ($type == 3) {
- $image_orig = imagecreatefrompng($copy_from);
- if ($image_orig != '') {
- $copy_to = str_replace('.png', '.jpg', $copy_to);
- $file_name = str_replace('.png', '.jpg', $file_name);
- }
- }
- else {
- $image_orig = imagecreatefromgif($copy_from);
- if ($image_orig != '') {
- $copy_to = str_replace('.gif', '.jpg', $copy_to);
- $file_name = str_replace('.gif', '.jpg', $file_name);
- }
- }
- }
- if ($image_orig != '') {
- if ($rotate > 0) {
- $image_orig = $this->imageRotateRightAngle($image_orig, $rotate);
- if ($rotate == 90 || $rotate == 270) {
- $width_orig2 = $height_orig;
- $height_orig = $width_orig;
- $width_orig = $width_orig2;
- $new_file_info['image_width'] = $width_orig;
- $new_file_info['image_height'] = $height_orig;
- }
- }
- if ($crop_height_and_fix_width == 1) {
- $width_new = $max_width;
- $height_new = $height_orig * ($max_width / $width_orig);
- if ($height_new < $max_height) {
- $height_new = $max_height;
- $width_new = $width_orig * ($max_height / $height_orig);
- }
- }
- else {
- $height_new = $height_orig * ($max_width / $width_orig);
- if ($height_new > $max_height) {
- $height_new = $max_height;
- $width_new = $width_orig * ($max_height / $height_orig);
- }
- else {
- $width_new = $max_width;
- $height_new = $height_orig * ($max_width / $width_orig);
- }
- }
- $new_file_info = [];
- $new_file_info['image_width'] = $width_new;
- $new_file_info['image_height'] = $height_new;
- // Fill background white for converted gifs.
- $image_new = imagecreatetruecolor($width_new, $height_new);
- $kek = imagecolorallocate($image_new,
- 255, 255, 255);
- imagefill($image_new, 0, 0, $kek);
- imagecopyresampled($image_new, $image_orig, 0, 0, 0, 0, $width_new, $height_new, $width_orig, $height_orig);
- imageinterlace($image_new, 1);
- imagejpeg($image_new, $copy_to, 100);
- if ($crop_height_and_fix_width == 1 && ($max_height != $height_new||$max_width != $width_new)) {
- $image_new2 = imagecreatetruecolor($max_width, $max_height);
- $kek = imagecolorallocate($image_new2,
- 255, 255, 255);
- imagefill($image_new, 0, 0, $kek);
- imagecopy($image_new2, $image_new, 0, 0, ($width_new - $max_width) / 2, ($height_new - $max_height) / 2, $max_width, $max_height);
- imageinterlace($image_new2, 1);
- imagejpeg($image_new2, $copy_to, 100);
- $new_file_info['image_width'] = $max_width;
- $new_file_info['image_height'] = $max_height;
- }
- $new_file_info['file_size'] = filesize($copy_to);
- $new_file_info['file_name'] = $file_name;
- }
- else {
- copy($copy_from, $copy_to);
- }
- }
- else {
- copy($copy_from, $copy_to);
- }
- return $new_file_info;
- }
- /**
- * Gets image info from full file path.
- */
- public function getImageInfoFromFullFilePath($full_file_path) {
- if (!file_exists($full_file_path)) {
- $image_info = '';
- }
- else {
- $image_size_info = getimagesize($full_file_path);
- $image_width = $image_size_info[0];
- $image_height = $image_size_info[1];
- $file_size = filesize($full_file_path);
- $image_info = [];
- $image_info['image_width'] = $image_width;
- $image_info['image_height'] = $image_height;
- $image_info['file_size'] = $file_size;
- }
- return $image_info;
- }
- /**
- * Makes image from PDF.
- */
- public function makeImageForPdf($media_attachment_id, $file_info) {
- $media_attachment_db_class = new MediaAttachmentDB();
- $upload_path = UPLOAD_PATH . '/';
- $date_rel_path = $file_info['relative_path'];
- $upload_dir = $upload_path . $date_rel_path;
- $existing_full_file_path = $upload_dir . $file_info['file_name'];
- $small_worked = FALSE;
- $large_worked = FALSE;
- $out = '';
- $ret = '';
- if (file_exists($existing_full_file_path)) {
- if (!is_readable($existing_full_file_path)) {
- sleep(5);
- }
- if (!is_readable($existing_full_file_path)) {
- echo '<!--Couldnt read file to convert to pdf-->';
- return '';
- }
- }
- else {
- echo '<!--Couldnt find file to convert to pdf-->';
- return '';
- }
- $exec_command = IMAGE_MAGICK_CONVERT . ' ' . escapeshellarg($existing_full_file_path . '[0]') . ' -colorspace rgb -bordercolor white -border 0 -alpha remove -background white -resize "140x140" -trim ' . escapeshellarg($existing_full_file_path . '_140_.jpg');
- exec($exec_command, $out, $ret);
- $fs = 0;
- $fs = @filesize($existing_full_file_path . '_140_.jpg');
- if ($fs + 0 > 10) {
- list($testw, $testh, $type) = getimagesize($existing_full_file_path . '_140_.jpg');
- if ($type == 2 && $testw + 0 > 0) {
- $image_orig = imagecreatefromjpeg($existing_full_file_path . '_140_.jpg');
- $image_new = imagecreatetruecolor($testw, $testh);
- $kek = imagecolorallocate($image_new, 255, 255, 255);
- imagefill($image_new, 0, 0, $kek);
- imagecopyresampled($image_new, $image_orig, 0, 0, 0, 0, $testw, $testh, $testw, $testh);
- imageinterlace($image_new, 1);
- imagejpeg($image_new, $existing_full_file_path . '_140_.jpg', 100);
- if (filesize($existing_full_file_path . '_140_.jpg') + 0 > 10) {
- list($testw, $testh, $type) = getimagesize($existing_full_file_path . '_140_.jpg');
- if ($type == 2 && $testw + 0 > 0) {
- $small_worked = TRUE;
- }
- }
- }
- }
- $exec_command = IMAGE_MAGICK_CONVERT . ' ' . escapeshellarg($existing_full_file_path . '[0]') . ' -colorspace rgb -bordercolor white -border 0 -alpha remove -background white -resize "600x900" -trim ' . escapeshellarg($existing_full_file_path . '_600_.jpg');
- exec($exec_command);
- $fs = 0;
- $fs = @filesize($existing_full_file_path . '_600_.jpg');
- if ($fs + 0 > 10) {
- list($testw, $testh, $type) = getimagesize($existing_full_file_path . '_600_.jpg');
- if ($type == 2 && $testw + 0 > 0) {
- $image_orig = imagecreatefromjpeg($existing_full_file_path . '_600_.jpg');
- $image_new = imagecreatetruecolor($testw, $testh);
- $kek = imagecolorallocate($image_new, 255, 255, 255);
- imagefill($image_new, 0, 0, $kek);
- imagecopyresampled($image_new, $image_orig, 0, 0, 0, 0, $testw, $testh, $testw, $testh);
- imageinterlace($image_new, 1);
- imagejpeg($image_new, $existing_full_file_path . '_600_.jpg', 100);
- if (filesize($existing_full_file_path . '_600_.jpg') + 0 > 10) {
- list($testw, $testh, $type) = getimagesize($existing_full_file_path . '_600_.jpg');
- if ($type == 2 && $testw + 0 > 0) {
- $large_worked = TRUE;
- }
- }
- }
- }
- else {
- echo "\n<!--Couldn't generate thumbnail for pdf-->\n";
- }
- $alt_tag = $file_info['file_name'];
- if ($large_worked) {
- $media_attachment_db_class->addMediaAttachment($file_info['file_name'] . '_600_.jpg', $file_info['file_name'] . '_600_.jpg', $date_rel_path, $alt_tag, $file_info['original_file_name'],
- 15, 0, UPLOAD_TYPE_THUMBNAIL_MEDIUM, UPLOAD_STATUS_VALIDATED, $media_attachment_id, 0, 0, 0);
- }
- if ($small_worked) {
- $media_attachment_db_class->addMediaAttachment($file_info['file_name'] . '_140_.jpg', $file_info['file_name'] . '_140_.jpg', $date_rel_path, $alt_tag, $file_info['original_file_name'],
- 15, 0, UPLOAD_TYPE_THUMBNAIL_SMALL, UPLOAD_STATUS_VALIDATED, $media_attachment_id, 0, 0, 0);
- }
- }
- /**
- * Makes image from video.
- */
- public function makeImageForVideo($media_attachment_id, $file_info) {
- $media_attachment_db_class = new MediaAttachmentDB();
- $upload_path = UPLOAD_PATH . '/';
- $date_rel_path = $file_info['relative_path'];
- $upload_dir = $upload_path . $date_rel_path;
- $existing_full_file_path = $upload_dir . $file_info['file_name'];
- $small_worked = FALSE;
- $large_worked = FALSE;
- $exec_command = FFMPEGTHUMBNAILER . ' -f -s 160 -i "' . $existing_full_file_path . '" -o ' . $existing_full_file_path . '_160_.png';
- exec($exec_command);
- $fs = 0;
- $fs = @filesize($existing_full_file_path . '_160_.png');
- if ($fs + 0 > 10) {
- list($testw, $testh, $type) = getimagesize($existing_full_file_path . '_160_.png');
- if ($type == 3 && $testw + 0 > 0) {
- $image_orig = imagecreatefrompng($existing_full_file_path . '_160_.png');
- $image_new = imagecreatetruecolor($testw, $testh);
- $kek = imagecolorallocate($image_new, 255, 255, 255);
- imagefill($image_new, 0, 0, $kek);
- imagecopyresampled($image_new, $image_orig, 0, 0, 0, 0, $testw, $testh, $testw, $testh);
- imageinterlace($image_new, 1);
- imagepng($image_new, $existing_full_file_path . '_160_.png');
- if (filesize($existing_full_file_path . '_160_.png') + 0 > 10) {
- list($small_testw, $small_testh, $type) = getimagesize($existing_full_file_path . '_160_.png');
- if ($type == 3 && $small_testw + 0 > 0) {
- $small_worked = TRUE;
- }
- }
- }
- }
- $exec_command = FFMPEGTHUMBNAILER . ' -f -s 600 -i "' . $existing_full_file_path . '" -o ' . $existing_full_file_path . '_600_.png';
- exec($exec_command);
- $fs = 0;
- $fs = @filesize($existing_full_file_path . '_600_.png');
- if ($fs + 0 > 10) {
- list($testw, $testh, $type) = getimagesize($existing_full_file_path . '_600_.png');
- if ($type == 3 && $testw + 0 > 0) {
- $image_orig = imagecreatefrompng($existing_full_file_path . '_600_.png');
- $image_new = imagecreatetruecolor($testw, $testh);
- $kek = imagecolorallocate($image_new, 255, 255, 255);
- imagefill($image_new, 0, 0, $kek);
- imagecopyresampled($image_new, $image_orig, 0, 0, 0, 0, $testw, $testh, $testw, $testh);
- imageinterlace($image_new, 1);
- imagepng($image_new, $existing_full_file_path . '_600_.png');
- if (filesize($existing_full_file_path . '_600_.png') + 0 > 10) {
- list($testw, $testh, $type) = getimagesize($existing_full_file_path . '_600_.png');
- if ($type == 3 && $testw + 0 > 0) {
- $large_worked = TRUE;
- }
- }
- }
- }
- // @fixme: 'alt_tag' not defined but should be, so define it here:
- $file_info['alt_tag'] = isset($file_info['alt_tag']) ? $file_info['alt_tag'] : '';
- if ($large_worked) {
- $media_attachment_db_class->addMediaAttachment($file_info['file_name'] . '_600_.png',
- $file_info['file_name'] . '_600_.png', $date_rel_path, $file_info['alt_tag'], $file_info['original_file_name'],
- 16, 0, UPLOAD_TYPE_THUMBNAIL_MEDIUM, UPLOAD_STATUS_VALIDATED, $media_attachment_id, 0, $testw, $testh);
- }
- if ($small_worked) {
- $media_attachment_db_class->addMediaAttachment($file_info['file_name'] . '_160_.png',
- $file_info['file_name'] . '_160_.png', $date_rel_path, $file_info['alt_tag'], $file_info['original_file_name'],
- 16, 0, UPLOAD_TYPE_THUMBNAIL_SMALL, UPLOAD_STATUS_VALIDATED, $media_attachment_id, 0, $small_testw, $small_testh);
- }
- }
- /**
- * Makes preview version of non-browser-playable video.
- */
- public function makeH264ForVideo(array $file_info) {
- $media_attachment_db_class = new MediaAttachmentDB();
- $existing_full_file_path = UPLOAD_PATH . '/' . $file_info['relative_path'] . $file_info['file_name'];
- $suffix = '_preview_.mp4';
- if (!file_exists($existing_full_file_path . $suffix)) {
- exec(FFMPEG . ' -i ' . escapeshellarg($existing_full_file_path) . ' ' . escapeshellarg($existing_full_file_path . $suffix));
- if (file_exists($existing_full_file_path . $suffix) && filesize($existing_full_file_path . $suffix)) {
- return $media_attachment_db_class->addMediaAttachment($file_info['file_name'] . $suffix,
- $file_info['file_name'] . $suffix, $file_info['relative_path'], $file_info['alt_tag'], $file_info['original_file_name'],
- 30, 0, UPLOAD_TYPE_H264, UPLOAD_STATUS_VALIDATED, $file_info['media_attachment_id'], filesize($existing_full_file_path . $suffix), $file_info['image_width'], $file_info['image_height']);
- }
- }
- }
- /**
- * Returns GD image handle of rotated image.
- *
- * $imgSrc - GD image handle of source image
- * $angle - angle of rotation. Needs to be positive integer
- * angle shall be 0,90,180,270, but if you give other it
- * will be rouned to nearest right angle (i.e. 52->90 degs,
- * 96->90 degs)
- */
- public function imageRotateRightAngle($imgSrc, $angle) {
- // Ensuring we got really RightAngle (if not we choose the closest one)
- $angle = min(((int) (($angle + 45) / 90) * 90), 270);
- // No need to fight.
- if ($angle == 0) {
- return($imgSrc);
- }
- // Dimenstion of source image.
- $srcX = imagesx($imgSrc);
- $srcY = imagesy($imgSrc);
- switch ($angle) {
- case 90:
- $imgDest = imagecreatetruecolor($srcY, $srcX);
- for ($x = 0; $x < $srcX; $x++) {
- for ($y = 0; $y < $srcY; $y++) {
- imagecopy($imgDest, $imgSrc, $srcY - $y - 1, $x, $x, $y, 1, 1);
- }
- }
- break;
- case 180:
- $imgDest = $this->imageFlip($imgSrc, IMAGE_FLIP_BOTH);
- break;
- case 270:
- $imgDest = imagecreatetruecolor($srcY, $srcX);
- for ($x = 0; $x < $srcX; $x++) {
- for ($y = 0; $y < $srcY; $y++) {
- imagecopy($imgDest, $imgSrc, $y, $srcX - $x - 1, $x, $y, 1, 1);
- }
- }
- break;
- }
- return($imgDest);
- }
- /**
- * Flips image.
- */
- public function imageflip($image, $mode) {
- $w = imagesx($image);
- $h = imagesy($image);
- $flipped = imagecreate($w, $h);
- if ($mode) {
- for ($y = 0; $y < $h; $y++) {
- imagecopy($flipped, $image, 0, $y, 0, $h - $y - 1, $w, 1);
- }
- }
- else {
- for ($x = 0; $x < $w; $x++) {
- imagecopy($flipped, $image, $x, 0, $w - $x - 1, 0, 1, $h);
- }
- }
- return $flipped;
- }
- /**
- * Gets width and height of a video using ffprobe.
- */
- public function getVideoDimensions(array &$file_info): bool {
- $path = UPLOAD_PATH . '/' . $file_info['relative_path'] . $file_info['file_name'];
- if (!is_readable($path)) {
- trigger_error("Could not read $path");
- return FALSE;
- }
- $command = FFPROBE . ' -v error -select_streams v:0 -show_entries stream -of json ' . escapeshellarg($path);
- exec($command, $output, $return_var);
- if ($return_var) {
- trigger_error("Error code $return_var running $command");
- return FALSE;
- }
- $probe = json_decode(implode($output));
- $width = (int) ($probe->streams[0]->width ?? 0);
- $height = (int) ($probe->streams[0]->height ?? 0);
- if ($width < 1 || $height < 1) {
- trigger_error("Could not get dimensions for $path");
- return FALSE;
- }
- // Swap width and height if video is rotated.
- if (!empty($probe->streams[0]->tags->rotate) && in_array($probe->streams[0]->tags->rotate, [90, 270])) {
- $tmp = $width;
- $width = $height;
- $height = $tmp;
- }
- $media_attachment_db_class = new MediaAttachmentDB();
- $media_attachment_db_class->updateVideoDimensions((int) $file_info['media_attachment_id'], $width, $height);
- $file_info['image_width'] = $width;
- $file_info['image_height'] = $height;
- return TRUE;
- }
- /**
- * Gets width and height of a video using ffprobe.
- */
- public function getVideoBrowserCompat(array &$file_info) {
- $path = UPLOAD_PATH . '/' . $file_info['relative_path'] . $file_info['file_name'];
- if (!is_readable($path)) {
- trigger_error("Could not read $path");
- return FALSE;
- }
- $command = FFPROBE . ' -v error -select_streams v:0 -show_entries stream=codec_name -of json ' . escapeshellarg($path);
- exec($command, $output, $return_var);
- if ($return_var) {
- trigger_error("Error code $return_var running $command");
- return FALSE;
- }
- $probe = json_decode(implode($output));
- $codec = $probe->streams[0]->codec_name ?? '';
- $file_info['browser_compat'] = $codec === 'h264' ? 1 : 0;
- $media_attachment_db_class = new MediaAttachmentDB();
- $media_attachment_db_class->updateVideoBrowserCompat((int) $file_info['media_attachment_id'], $file_info['browser_compat']);
- }
- }