From 797f19e881e658a48a0f3d5a429eb075a9b13215 Mon Sep 17 00:00:00 2001 From: skodak Date: Sat, 13 Sep 2008 19:38:44 +0000 Subject: [PATCH] MDL-14589 image resizing and conversion support --- lib/file/file_storage.php | 114 ++++++++++++++++++++++++++++++++++++++ lib/file/stored_file.php | 37 +++++++++++++ 2 files changed, 151 insertions(+) diff --git a/lib/file/file_storage.php b/lib/file/file_storage.php index 631dd66390..177cee6b5f 100644 --- a/lib/file/file_storage.php +++ b/lib/file/file_storage.php @@ -615,6 +615,120 @@ class file_storage { return new stored_file($this, $newrecord); } + /** + * Creates new image file from existing. + * @param mixed $file_record object or array describing new file + * @param mixed file id or stored file object + * @param int $newwidth in pixels + * @param int $newheight in pixels + * @param bool $keepaspectratio + * @param int $quality depending on image type 0-100 for jpeg, 0-9 (0 means no comppression) for png + * @return object stored_file instance + */ + public function convert_image($file_record, $fid, $newwidth=null, $newheight=null, $keepaspectratio=true, $quality=null) { + global $DB; + + if ($fid instanceof stored_file) { + $fid = $fid->get_id(); + } + + $file_record = (array)$file_record; // we support arrays too, do not modify the submitted record! + + if (!$file = $this->get_file_by_id($fid)) { // make sure file really exists and we we correct data + throw new file_exception('storedfileproblem', 'File does not exist'); + } + + if (!$imageinfo = $file->get_imageinfo()) { + throw new file_exception('storedfileproblem', 'File is not an image'); + } + + if (!isset($file_record['filename'])) { + $file_record['filename'] == $file->get_filename(); + } + + if (!isset($file_record['mimetype'])) { + $file_record['mimetype'] = mimeinfo('type', $file_record['filename']); + } + + $width = $imageinfo['width']; + $height = $imageinfo['height']; + $mimetype = $imageinfo['mimetype']; + + if ($keepaspectratio) { + if (0 >= $newwidth and 0 >= $newheight) { + // no sizes specified + $newwidth = $width; + $newheight = $height; + + } else if (0 < $newwidth and 0 < $newheight) { + $xheight = ($newwidth*($height/$width)); + if ($xheight < $newheight) { + $newheight = (int)$xheight; + } else { + $newwidth = (int)($newheight*($width/$height)); + } + + } else if (0 < $newwidth) { + $newheight = (int)($newwidth*($height/$width)); + + } else { //0 < $newheight + $newwidth = (int)($newheight*($width/$height)); + } + + } else { + if (0 >= $newwidth) { + $newwidth = $width; + } + if (0 >= $newheight) { + $newheight = $height; + } + } + + $img = imagecreatefromstring($file->get_content()); + if ($height != $newheight or $width != $newwidth) { + $newimg = imagecreatetruecolor($newwidth, $newheight); + if (!imagecopyresized($newimg, $img, 0, 0, 0, 0, $newwidth, $newheight, $width, $height)) { + // weird + throw new file_exception('storedfileproblem', 'Can not resize image'); + } + imagedestroy($img); + $img = $newimg; + } + + ob_start(); + switch ($file_record['mimetype']) { + case 'image/gif': + imagegif($img); + break; + + case 'image/jpeg': + if (is_null($quality)) { + imagejpeg($img); + } else { + imagejpeg($img, NULL, $quality); + } + break; + + case 'image/png': + $quality = int($quality); + imagepng($img, NULL, $quality, NULL); + break; + + default: + throw new file_exception('storedfileproblem', 'Unsupported mime type'); + } + + $content = ob_get_contents(); + ob_end_clean(); + imagedestroy($img); + + if (!$content) { + throw new file_exception('storedfileproblem', 'Can not convert image'); + } + + return $this->create_file_from_string($file_record, $content); + } + /** * Move one or more files from a given itemid location in the current user's draft files * to a new filearea. Note that you can't rename files using this function. diff --git a/lib/file/stored_file.php b/lib/file/stored_file.php index 9b9e018321..1373210873 100644 --- a/lib/file/stored_file.php +++ b/lib/file/stored_file.php @@ -162,6 +162,43 @@ class stored_file { } } + /** + * Returns information about image, + * information is determined from the file content + * @return mixed array with width, height and mimetype; false if not an image + */ + public function get_imageinfo() { + if (!$imageinfo = getimagesize($this->get_content_file_location())) { + return false; + } + $image = array('width'=>$imageinfo[0], 'height'=>$imageinfo[1], 'mimetype'=>image_type_to_mime_type($imageinfo[2])); + if (empty($image['width']) or empty($image['height']) or empty($image['mimetype'])) { + // gd can not parse it, sorry + return false; + } + return $image; + } + + /** + * Verifies the file is a valid web image - gif, png and jpeg only. + * It should be ok to serve this image from server without any other security workarounds. + * @return bool true if file ok + */ + public function is_valid_image() { + $mimetype = $this->get_mimetype(); + if ($mimetype !== 'image/gif' and $mimetype !== 'image/jpeg' and $mimetype !== 'image/png') { + return false; + } + if (!$info = $this->get_imageinfo()) { + return false; + } + if ($info['mimetype'] !== $mimetype) { + return false; + } + // ok, GD likes this image + return true; + } + public function get_contextid() { return $this->file_record->contextid; } -- 2.39.5