mikuli.cz

:)
git clone https://git.sr.ht/~ashymad/mikuli.cz
Log | Files | Refs

image.php (11137B)


      1 <?php
      2 // Image extension, https://github.com/annaesvensson/yellow-image
      3 
      4 class YellowImage {
      5     const VERSION = "0.9.3";
      6     public $yellow;             // access to API
      7 
      8     // Handle initialisation
      9     public function onLoad($yellow) {
     10         $this->yellow = $yellow;
     11         $this->yellow->system->setDefault("imageUploadWidthMax", "1280");
     12         $this->yellow->system->setDefault("imageUploadHeightMax", "1280");
     13         $this->yellow->system->setDefault("imageUploadJpegQuality", "80");
     14         $this->yellow->system->setDefault("imageThumbnailJpegQuality", "80");
     15         $this->yellow->system->setDefault("imageJpegExtension", "auto");
     16     }
     17     
     18     // Handle update
     19     public function onUpdate($action) {
     20         if ($action=="clean") {
     21             $statusCode = 200;
     22             $path = $this->yellow->lookup->findMediaDirectory("coreThumbnailLocation");
     23             foreach ($this->yellow->toolbox->getDirectoryEntries($path, "/.*/", false, false) as $entry) {
     24                 if (!$this->yellow->toolbox->deleteFile($entry)) $statusCode = 500;
     25             }
     26             if ($statusCode==500) $this->yellow->toolbox->log("error", "Can't delete files in directory '$path'!");
     27         }
     28     }
     29 
     30     // Handle page content element
     31     public function onParseContentElement($page, $name, $text, $attributes, $type) {
     32         $output = null;
     33         if ($name=="image" && $type=="inline") {
     34             list($name, $alt, $style, $width, $height) = $this->yellow->toolbox->getTextArguments($text);
     35             if (!preg_match("/^\w+:/", $name)) {
     36                 if (is_string_empty($alt)) $alt = $this->yellow->language->getText("imageDefaultAlt");
     37                 if (is_string_empty($width)) $width = "100%";
     38                 if (is_string_empty($height)) $height = $width;
     39                 $path = $this->yellow->lookup->findMediaDirectory("coreImageLocation");
     40                 list($src, $width, $height) = $this->getImageInformation($path.$name, $width, $height);
     41             } else {
     42                 if (is_string_empty($alt)) $alt = $this->yellow->language->getText("imageDefaultAlt");
     43                 $src = $this->yellow->lookup->normaliseUrl("", "", "", $name);
     44                 $width = $height = 0;
     45             }
     46             $output = "<img src=\"".htmlspecialchars($src)."\"";
     47             if ($width && $height) $output .= " width=\"".htmlspecialchars($width)."\" height=\"".htmlspecialchars($height)."\"";
     48             if (!is_string_empty($alt)) $output .= " alt=\"".htmlspecialchars($alt)."\" title=\"".htmlspecialchars($alt)."\"";
     49             if (!is_string_empty($style)) $output .= " class=\"".htmlspecialchars($style)."\"";
     50             $output .= " />";
     51         }
     52         return $output;
     53     }
     54     
     55     // Handle media file changes
     56     public function onEditMediaFile($file, $action, $email) {
     57         if ($action=="upload") {
     58             $fileName = $file->get("fileNameTemp");
     59             list($widthInput, $heightInput, $orientation, $type) =
     60                 $this->yellow->toolbox->detectImageInformation($fileName, $file->get("type"));
     61             $widthMax = $this->yellow->system->get("imageUploadWidthMax");
     62             $heightMax = $this->yellow->system->get("imageUploadHeightMax");
     63             if ($type=="gif" || $type=="jpeg" || $type=="png") {
     64                 if ($widthInput>$widthMax || $heightInput>$heightMax) {
     65                     list($widthOutput, $heightOutput) = $this->getImageDimensionsFit($widthInput, $heightInput, $widthMax, $heightMax);
     66                     $image = $this->loadImage($fileName, $type);
     67                     $image = $this->resizeImage($image, $widthInput, $heightInput, $widthOutput, $heightOutput);
     68                     $image = $this->orientImage($image, $orientation);
     69                     if (!$this->saveImage($image, $fileName, $type, $this->yellow->system->get("imageUploadJpegQuality"))) {
     70                         $file->error(500, "Can't write file '$fileName'!");
     71                     }
     72                 } elseif ($orientation>1) {
     73                     $image = $this->loadImage($fileName, $type);
     74                     $image = $this->orientImage($image, $orientation);
     75                     if (!$this->saveImage($image, $fileName, $type, $this->yellow->system->get("imageUploadJpegQuality"))) {
     76                         $file->error(500, "Can't write file '$fileName'!");
     77                     }
     78                 }
     79             }
     80             if ($type=="jpeg") {
     81                 $file->fileName = dirname($file->fileName)."/".pathinfo($file->fileName, PATHINFO_FILENAME).$this->getImageExtension($file->fileName, $type);
     82                 $file->set("type", $this->yellow->toolbox->getFileType($file->fileName));
     83             }
     84         }
     85     }
     86 
     87     // Return image information, create thumbnail on demand
     88     public function getImageInformation($fileName, $widthOutput, $heightOutput) {
     89         $fileNameShort = substru($fileName, strlenu($this->yellow->lookup->findMediaDirectory("coreImageLocation")));
     90         list($widthInput, $heightInput, $orientation, $type) = $this->yellow->toolbox->detectImageInformation($fileName);
     91         $widthOutput = $this->convertValueAndUnit($widthOutput, $widthInput);
     92         $heightOutput = $this->convertValueAndUnit($heightOutput, $heightInput);
     93         if (($widthInput==$widthOutput && $heightInput==$heightOutput) || $type=="svg" || $type=="") {
     94             $src = $this->yellow->system->get("coreServerBase").$this->yellow->system->get("coreImageLocation").$fileNameShort;
     95             $width = $widthOutput;
     96             $height = $heightOutput;
     97         } else {
     98             $pathThumb = $this->yellow->lookup->findMediaDirectory("coreThumbnailLocation");
     99             $fileNameThumb = ltrim(str_replace(array("/", "\\", "."), "-", dirname($fileNameShort)."/".pathinfo($fileName, PATHINFO_FILENAME)), "-");
    100             $fileNameThumb .= "-".$widthOutput."x".$heightOutput;
    101             $fileNameThumb .= $this->getImageExtension($fileName, $type);
    102             $fileNameOutput = $pathThumb.$fileNameThumb;
    103             if ($this->isFileNotUpdated($fileName, $fileNameOutput)) {
    104                 $image = $this->loadImage($fileName, $type);
    105                 $image = $this->resizeImage($image, $widthInput, $heightInput, $widthOutput, $heightOutput);
    106                 $image = $this->orientImage($image, $orientation);
    107                 if (is_file($fileNameOutput)) $this->yellow->toolbox->deleteFile($fileNameOutput);
    108                 if (!$this->saveImage($image, $fileNameOutput, $type, $this->yellow->system->get("imageThumbnailJpegQuality")) ||
    109                     !$this->yellow->toolbox->modifyFile($fileNameOutput, $this->yellow->toolbox->getFileModified($fileName))) {
    110                     $this->yellow->page->error(500, "Can't write file '$fileNameOutput'!");
    111                 }
    112             }
    113             $src = $this->yellow->system->get("coreServerBase").$this->yellow->system->get("coreThumbnailLocation").$fileNameThumb;
    114             list($width, $height) = $this->yellow->toolbox->detectImageInformation($fileNameOutput);
    115         }
    116         return array($src, $width, $height);
    117     }
    118     
    119     // Return image dimensions that fit, scale proportional
    120     public function getImageDimensionsFit($widthInput, $heightInput, $widthMax, $heightMax) {
    121         $widthOutput = $widthMax;
    122         $heightOutput = $widthMax * ($heightInput / $widthInput);
    123         if ($heightOutput>$heightMax) {
    124             $widthOutput = $widthOutput * ($heightMax / $heightOutput);
    125             $heightOutput = $heightOutput * ($heightMax / $heightOutput);
    126         }
    127         return array(intval($widthOutput), intval($heightOutput));
    128     }
    129     
    130     // Return image extension
    131     public function getImageExtension($fileName, $type) {
    132         $jpegExtension = $this->yellow->system->get("imageJpegExtension");
    133         $fileExtension = ".".pathinfo($fileName, PATHINFO_EXTENSION);
    134         if ($jpegExtension!="auto" && $type=="jpeg") $fileExtension = $jpegExtension;
    135         return $fileExtension;
    136     }
    137 
    138     // Load image from file
    139     public function loadImage($fileName, $type) {
    140         $image = false;
    141         switch ($type) {
    142             case "gif":  $image = @imagecreatefromgif($fileName); break;
    143             case "jpeg": $image = @imagecreatefromjpeg($fileName); break;
    144             case "png":  $image = @imagecreatefrompng($fileName); break;
    145         }
    146         return $image;
    147     }
    148     
    149     // Save image to file
    150     public function saveImage($image, $fileName, $type, $quality) {
    151         $ok = false;
    152         switch ($type) {
    153             case "gif":  $ok = @imagegif($image, $fileName); break;
    154             case "jpeg": $ok = @imagejpeg($image, $fileName, $quality); break;
    155             case "png":  $ok = @imagepng($image, $fileName); break;
    156         }
    157         return $ok;
    158     }
    159 
    160     // Create image from scratch
    161     public function createImage($width, $height) {
    162         $image = imagecreatetruecolor($width, $height);
    163         imagealphablending($image, false);
    164         imagesavealpha($image, true);
    165         return $image;
    166     }
    167 
    168     // Resize image
    169     public function resizeImage($image, $widthInput, $heightInput, $widthOutput, $heightOutput) {
    170         $widthFit = $widthInput * ($heightOutput / $heightInput);
    171         $heightFit = $heightInput * ($widthOutput / $widthInput);
    172         $widthDiff = abs($widthOutput - $widthFit);
    173         $heightDiff = abs($heightOutput - $heightFit);
    174         $imageOutput = $this->createImage($widthOutput, $heightOutput);
    175         if ($heightFit>$heightOutput) {
    176             imagecopyresampled($imageOutput, $image, 0, $heightDiff/-2, 0, 0, $widthOutput, $heightFit, $widthInput, $heightInput);
    177         } else {
    178             imagecopyresampled($imageOutput, $image, $widthDiff/-2, 0, 0, 0, $widthFit, $heightOutput, $widthInput, $heightInput);
    179         }
    180         return $imageOutput;
    181     }
    182     
    183     // Orient image automatically
    184     public function orientImage($image, $orientation) {
    185         switch ($orientation) {
    186             case 2: imageflip($image, IMG_FLIP_HORIZONTAL); break;
    187             case 3: $image = imagerotate($image, 180, 0); break;
    188             case 4: imageflip($image, IMG_FLIP_VERTICAL); break;
    189             case 5: $image = imagerotate($image, 90, 0); imageflip($image, IMG_FLIP_VERTICAL); break;
    190             case 6: $image = imagerotate($image, -90, 0); break;
    191             case 7: $image = imagerotate($image, 90, 0); imageflip($image, IMG_FLIP_HORIZONTAL); break;
    192             case 8: $image = imagerotate($image, 90, 0); break;
    193         }
    194         return $image;
    195     }
    196     
    197     // Return value according to unit
    198     public function convertValueAndUnit($text, $valueBase) {
    199         $value = $unit = "";
    200         if (preg_match("/([\d\.]+)(\S*)/", $text, $matches)) {
    201             $value = $matches[1];
    202             $unit = $matches[2];
    203             if ($unit=="%") $value = $valueBase * $value / 100;
    204         }
    205         return intval($value);
    206     }
    207 
    208     // Check if file needs to be updated
    209     public function isFileNotUpdated($fileNameInput, $fileNameOutput) {
    210         return $this->yellow->toolbox->getFileModified($fileNameInput)!=$this->yellow->toolbox->getFileModified($fileNameOutput);
    211     }
    212 }