1<?php 2/** 3 * DokuWiki Plugin mediathumbnails (thumb_engine class and subclasses) 4 * 5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6 * @author Thomas Schäfer <thomas.schaefer@itschert.net> 7 */ 8 9abstract class thumb_engine { 10 11 private ?thumbnail $thumbnail = null; 12 13 public function __construct(thumbnail $thumbnail) { 14 $this->thumbnail = $thumbnail; 15 } 16 17 protected function getSourceFilepath() { 18 return $this->thumbnail->getSourceFilepath(); 19 } 20 21 protected function getTargetFilepath() { 22 return $this->thumbnail->getFilepath(); 23 } 24 25 protected function getTargetMaxDimension() { 26 return $this->thumbnail->getMaxDimension(); 27 } 28 29 public function act() { 30 if ($this->act_internal()) { 31 // Set timestamp to the source file's timestamp (this is used to check in later passes if the file already exists in the correct version). 32 if (filemtime($this->getSourceFilepath()) !== filemtime($this->getTargetFilepath())) { 33 touch($this->getTargetFilepath(), filemtime($this->getSourceFilepath())); 34 } 35 return true; 36 } 37 return false; 38 } 39 40 // Checks if a thumbnail file for the current file version has already been created 41 protected function thumb_needs_update() { 42 return !file_exists($this->getTargetFilepath()) || filemtime($this->getTargetFilepath()) !== filemtime($this->getSourceFilepath()); 43 } 44 45 public abstract function act_internal(); 46 47 public abstract function getFileSuffix(); 48} 49 50class thumb_pdf_engine extends thumb_engine { 51 52 public function getFileSuffix() { 53 return "jpg"; 54 } 55 56 public function act_internal() { 57 if ($this->thumb_needs_update()) { 58 $im = new imagick($this->getSourceFilepath()."[0]"); 59 // the following line was in the original code. Issue #6 (https://github.com/ternite/dokuwiki-plugin-mediathumbnails/issues/6) 60 // indicated there might be problems with colors, so I uncommented the line (TS, 2025-10-11) 61 //$im->setImageColorspace(255); 62 $im->setResolution(300, 300); 63 $im->setCompressionQuality(95); 64 $im->setImageFormat('jpeg'); 65 //$im->resizeImage($this->getTargetMaxDimension(),0,imagick::FILTER_LANCZOS,0.9); 66 //$im->thumbnailImage($this->getTargetMaxDimension(),$this->getTargetMaxDimension(),true,false); 67 $im->writeImage($this->getTargetFilepath()); 68 $im->clear(); 69 $im->destroy(); 70 71 // unfortunately, resizeImage or thumbnailImage leads to a black thumbnail in my setup, so I reopen the file and resize it now. 72 $im = new imagick($this->getTargetFilepath()); 73 $im->thumbnailImage($this->getTargetMaxDimension(),$this->getTargetMaxDimension(),true,false); 74 $im->writeImage($this->getTargetFilepath()); 75 $im->clear(); 76 $im->destroy(); 77 78 return true; 79 } else { 80 return true; 81 } 82 } 83} 84 85class thumb_img_engine extends thumb_engine { 86 87 public function getFileSuffix() { 88 return getFileSuffix($this->getSourceFilepath()); 89 } 90 91 public function act_internal() { 92 if ($this->thumb_needs_update()) { 93 $im = new imagick( $this->getSourceFilepath() ); 94 $im->thumbnailImage($this->getTargetMaxDimension(),$this->getTargetMaxDimension(),true,false); 95 $im->writeImage($this->getTargetFilepath()); 96 $im->clear(); 97 $im->destroy(); 98 99 return true; 100 } else { 101 return true; 102 } 103 } 104} 105 106class thumb_zip_engine extends thumb_engine { 107 108 private array $thumb_paths; 109 private $file_suffix = ""; 110 111 public function __construct(thumbnail $thumbnail, array $thumb_paths) { 112 parent::__construct($thumbnail); 113 $this->thumb_paths = $thumb_paths; 114 } 115 116 public function getFileSuffix() { 117 return $this->file_suffix; 118 } 119 120 public function act_internal() { 121 122 $zip = new ZipArchive; 123 if ($zip->open($this->getSourceFilepath()) !== true) { 124 // file is no zip or cannot be opened 125 return false; 126 } 127 128 // The media file exists and acts as a zip file! 129 130 // Check all possible paths (configured in configuration key 'thumb_paths') if there is a file available 131 foreach($this->thumb_paths as $thumbnail_path) { 132 $this->file_suffix = substr(strrchr($thumbnail_path,'.'),1); 133 134 if ($zip->locateName($thumbnail_path) !== false) { 135 136 if (!$this->thumb_needs_update()) { 137 return true; 138 } 139 140 // Get the thumbnail file! 141 $fp = $zip->getStream($thumbnail_path); 142 if(!$fp) { 143 return false; 144 } 145 146 $thumbnaildata = ''; 147 while (!feof($fp)) { 148 $thumbnaildata .= fread($fp, 8192); 149 } 150 151 fclose($fp); 152 153 // Write thumbnail file to media folder 154 file_put_contents($this->getTargetFilepath(), $thumbnaildata); 155 156 return true; 157 } 158 } 159 160 return true; 161 } 162}