]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-14589 image resizing and conversion support
authorskodak <skodak>
Sat, 13 Sep 2008 19:38:44 +0000 (19:38 +0000)
committerskodak <skodak>
Sat, 13 Sep 2008 19:38:44 +0000 (19:38 +0000)
lib/file/file_storage.php
lib/file/stored_file.php

index 631dd663903b9342c595114cedfc2ba155942b37..177cee6b5fbfd01ce0c14e78113d8765e635f935 100644 (file)
@@ -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.
index 9b9e018321ae8f9a23ad0011f8037c9ec26aecb2..1373210873a445bd1ccdc85e7fec445dc5752d47 100644 (file)
@@ -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;
     }