ソースを参照

Added image optimisation for uploaded files

markseu 7 年 前
コミット
b7ed0e2b4f
3 ファイル変更54 行追加17 行削除
  1. 4 1
      system/config/config.ini
  2. 10 9
      system/plugins/core.php
  3. 40 7
      system/plugins/image.php

+ 4 - 1
system/config/config.ini

@@ -68,10 +68,13 @@ EditUserHome: /
 EditLoginRestrictions: 0
 EditLoginSessionTimeout: 2592000
 EditBruteForceProtection: 25
+ImageAlt: Image
+ImageUploadWidthMax: 1280
+ImageUploadHeightMax: 1280
+ImageUploadJpgQuality: 80
 ImageThumbnailLocation: /media/thumbnails/
 ImageThumbnailDir: media/thumbnails/
 ImageThumbnailJpgQuality: 80
-ImageAlt: Image
 UpdatePluginsUrl: https://github.com/datenstrom/yellow-plugins
 UpdateThemesUrl: https://github.com/datenstrom/yellow-themes
 UpdateInformationFile: update.ini

+ 10 - 9
system/plugins/core.php

@@ -2991,20 +2991,21 @@ class YellowToolbox {
     }
     
     // Detect image dimensions and type for gif/jpg/png/svg
-    public function detectImageInformation($fileName) {
+    public function detectImageInformation($fileName, $fileType = "") {
         $width = $height = 0;
         $type = "";
         $fileHandle = @fopen($fileName, "rb");
         if ($fileHandle) {
-            if (substru(strtoloweru($fileName), -3)=="gif") {
+            if(empty($fileType)) $fileType = $this->getFileType($fileName);
+            if ($fileType=="gif") {
                 $dataSignature = fread($fileHandle, 6);
                 $dataHeader = fread($fileHandle, 7);
                 if (!feof($fileHandle) && ($dataSignature=="GIF87a" || $dataSignature=="GIF89a")) {
                     $width = (ord($dataHeader[1])<<8) + ord($dataHeader[0]);
                     $height = (ord($dataHeader[3])<<8) + ord($dataHeader[2]);
-                    $type = "gif";
+                    $type = $fileType;
                 }
-            } elseif (substru(strtoloweru($fileName), -3)=="jpg") {
+            } elseif ($fileType=="jpg") {
                 $dataBufferSizeMax = filesize($fileName);
                 $dataBufferSize = min($dataBufferSizeMax, 4096);
                 if ($dataBufferSize) $dataBuffer = fread($fileHandle, $dataBufferSize);
@@ -3015,7 +3016,7 @@ class YellowToolbox {
                         if ($dataBuffer[$pos+1]=="\xc0" || $dataBuffer[$pos+1]=="\xc2") {
                             $width = (ord($dataBuffer[$pos+7])<<8) + ord($dataBuffer[$pos+8]);
                             $height = (ord($dataBuffer[$pos+5])<<8) + ord($dataBuffer[$pos+6]);
-                            $type = "jpg";
+                            $type = $fileType;
                             break;
                         }
                         $length = (ord($dataBuffer[$pos+2])<<8) + ord($dataBuffer[$pos+3]) + 2;
@@ -3032,15 +3033,15 @@ class YellowToolbox {
                         }
                     }
                 }
-            } elseif (substru(strtoloweru($fileName), -3)=="png") {
+            } elseif ($fileType=="png") {
                 $dataSignature = fread($fileHandle, 8);
                 $dataHeader = fread($fileHandle, 16);
                 if (!feof($fileHandle) && $dataSignature=="\x89PNG\r\n\x1a\n") {
                     $width = (ord($dataHeader[10])<<8) + ord($dataHeader[11]);
                     $height = (ord($dataHeader[14])<<8) + ord($dataHeader[15]);
-                    $type = "png";
+                    $type = $fileType;
                 }
-            } elseif (substru(strtoloweru($fileName), -3)=="svg") {
+            } elseif ($fileType=="svg") {
                 $dataBufferSizeMax = filesize($fileName);
                 $dataBufferSize = min($dataBufferSizeMax, 4096);
                 if ($dataBufferSize) $dataBuffer = fread($fileHandle, $dataBufferSize);
@@ -3049,7 +3050,7 @@ class YellowToolbox {
                     $dataBuffer = ($pos = strposu($dataBuffer, ">")) ? substru($dataBuffer, 0, $pos) : $dataBuffer;
                     if (preg_match("/ width=\"(\d+)\"/", $dataBuffer, $matches)) $width = $matches[1];
                     if (preg_match("/ height=\"(\d+)\"/", $dataBuffer, $matches)) $height = $matches[1];
-                    $type = "svg";
+                    $type = $fileType;
                 }
             }
             fclose($fileHandle);

+ 40 - 7
system/plugins/image.php

@@ -1,20 +1,23 @@
 <?php
 // Image plugin, https://github.com/datenstrom/yellow-plugins/tree/master/image
-// Copyright (c) 2013-2017 Datenstrom, https://datenstrom.se
+// Copyright (c) 2013-2018 Datenstrom, https://datenstrom.se
 // This file may be used and distributed under the terms of the public license.
 
 class YellowImage {
-    const VERSION = "0.7.4";
+    const VERSION = "0.7.5";
     public $yellow;             //access to API
     public $graphicsLibrary;    //graphics library support? (boolean)
 
     // Handle initialisation
     public function onLoad($yellow) {
         $this->yellow = $yellow;
+        $this->yellow->config->setDefault("imageAlt", "Image");
+        $this->yellow->config->setDefault("imageUploadWidthMax", "1280");
+        $this->yellow->config->setDefault("imageUploadHeightMax", "1280");
+        $this->yellow->config->setDefault("imageUploadJpgQuality", "80");
         $this->yellow->config->setDefault("imageThumbnailLocation", "/media/thumbnails/");
         $this->yellow->config->setDefault("imageThumbnailDir", "media/thumbnails/");
-        $this->yellow->config->setDefault("imageThumbnailJpgQuality", 80);
-        $this->yellow->config->setDefault("imageAlt", "Image");
+        $this->yellow->config->setDefault("imageThumbnailJpgQuality", "80");
         $this->graphicsLibrary = $this->isGraphicsLibrary();
     }
 
@@ -46,6 +49,25 @@ class YellowImage {
         return $output;
     }
     
+    // Handle media file changes
+    public function onEditMediaFile($file, $action) {
+        if ($action=="upload" && $this->graphicsLibrary) {
+            $fileName = $file->fileName;
+            $fileType = $this->yellow->toolbox->getFileType($file->get("fileNameShort"));
+            list($widthInput, $heightInput, $type) = $this->yellow->toolbox->detectImageInformation($fileName, $fileType);
+            $widthMax = $this->yellow->config->get("imageUploadWidthMax");
+            $heightMax = $this->yellow->config->get("imageUploadHeightMax");
+            if (($widthInput>$widthMax || $heightInput>$heightMax) && ($type=="gif" || $type=="jpg" || $type=="png")) {
+                list($widthOutput, $heightOutput) = $this->getImageDimensionsFit($widthInput, $heightInput, $widthMax, $heightMax);
+                $image = $this->loadImage($fileName, $type);
+                $image = $this->resizeImage($image, $widthInput, $heightInput, $widthOutput, $heightOutput);
+                if (!$this->saveImage($image, $fileName, $type, $this->yellow->config->get("imageUploadJpgQuality"))) {
+                    $file->error(500, "Can't write file '$fileName'!");
+                }
+            }
+        }
+    }
+    
     // Handle command
     public function onCommand($args) {
         list($command) = $args;
@@ -88,7 +110,7 @@ class YellowImage {
             if ($this->isFileNotUpdated($fileName, $fileNameOutput)) {
                 $image = $this->loadImage($fileName, $type);
                 $image = $this->resizeImage($image, $widthInput, $heightInput, $widthOutput, $heightOutput);
-                if (!$this->saveImage($image, $fileNameOutput, $type) ||
+                if (!$this->saveImage($image, $fileNameOutput, $type, $this->yellow->config->get("imageThumbnailJpgQuality")) ||
                     !$this->yellow->toolbox->modifyFile($fileNameOutput, $this->yellow->toolbox->getFileModified($fileName))) {
                     $this->yellow->page->error(500, "Can't write file '$fileNameOutput'!");
                 }
@@ -98,6 +120,17 @@ class YellowImage {
         }
         return array($src, $width, $height);
     }
+    
+    // Return image dimensions that fit, scale proportional
+    public function getImageDimensionsFit($widthInput, $heightInput, $widthMax, $heightMax) {
+        $widthOutput = $widthMax;
+        $heightOutput = $widthMax * ($heightInput / $widthInput);
+        if ($heightOutput>$heightMax) {
+            $widthOutput = $widthOutput * ($heightMax / $heightOutput);
+            $heightOutput = $heightOutput * ($heightMax / $heightOutput);
+        }
+        return array(intval($widthOutput), intval($heightOutput));
+    }
 
     // Load image from file
     public function loadImage($fileName, $type) {
@@ -111,11 +144,11 @@ class YellowImage {
     }
     
     // Save image to file
-    public function saveImage($image, $fileName, $type) {
+    public function saveImage($image, $fileName, $type, $quality) {
         $ok = false;
         switch ($type) {
             case "gif": $ok = @imagegif($image, $fileName); break;
-            case "jpg": $ok = @imagejpeg($image, $fileName, $this->yellow->config->get("imageThumbnailJpgQuality")); break;
+            case "jpg": $ok = @imagejpeg($image, $fileName, $quality); break;
             case "png": $ok = @imagepng($image, $fileName); break;
         }
         return $ok;