/** * Uncompress this file contents and return the result. * Obviously, if a multi-gigibyte file is read with no immediate destination, * you'll probably run out of memory. * * @param Filestore\File|bool $dst The destination to write the uncompressed data to * If not provided, just returns the data. * * @return mixed */ public function uncompress($dst = false) { $zd = gzopen($this->_file->getLocalFilename(), "r"); if (!$zd) return false; $contents = ''; while (!feof($zd)) { $contents .= gzread($zd, 2048); } gzclose($zd); if($dst){ $dst->putContents($contents); } else{ return $contents; } }
/** * Resize this image and save the output as another File object. * * This is used on conjunction with getPreview* and getQuickPreview. * QuickPreview creates the destination file in the correct directory * and getPreview* methods request the actual resizing. * * @param Filestore\File $file The destination file * @param int $width Width of the final image (in px) * @param int $height Height of the final image (in px) * @param string $mode Mode (part of the geometry) */ private function _resizeTo(Filestore\File $file, $width, $height, $mode){ if(!$this->isImage()){ // :/ return; } \Core\Utilities\Logger\write_debug('Resizing image ' . $this->getFilename('') . ' to ' . $width . 'x' . $height . $mode); $m = $this->getMimetype(); // Make sure the directory of the destination file exists! // By touching the file, Core will create all parent directories as necessary. $file->putContents(''); if($m == 'image/gif' && exec('which convert 2>/dev/null')){ // The GIF resizer handles EVERYTHING :) // Granted of course, that imagemagick's convert is available on the server. $resize = escapeshellarg($mode . $width . 'x' . $height); exec('convert ' . escapeshellarg($this->getFilename()) . ' -resize ' . $resize . ' ' . escapeshellarg($file->getFilename())); \Core\Utilities\Logger\write_debug('Resizing complete (via convert)'); return; } // Traditional resizing logic. switch ($m) { case 'image/jpeg': $thumbType = 'JPEG'; $thumbWidth = $width; $thumbHeight = $height; if($width <= 200 && $height <= 200 && function_exists('exif_thumbnail')){ // Try to write out from the thumbnail img instead of the full size. // This is done to increase server performance. // eg: resizing a 5MB JPEG can take upwards of 50-100ms, // whereas the embedded thumbnail will take only 2-10ms. // Not to mention professional JPEG management tools such as PS and Gimp // produce marginally higher-quality thumbnails than GD will. // (The resulting filesize is negligible.) // Of course if the requested image is larger than a thumbnail size, (200x200 in this case), // using the thumbnail is counter-productive! $img = exif_thumbnail($this->getFilename(), $thumbWidth, $thumbHeight, $thumbType); if($img){ \Core\Utilities\Logger\write_debug('JPEG has thumbnail data of ' . $thumbWidth . 'x' . $thumbHeight . '!'); $file->putContents($img); $img = imagecreatefromjpeg($file->getFilename()); } else{ $img = imagecreatefromjpeg($this->getFilename()); } } else{ $img = imagecreatefromjpeg($this->getFilename()); } break; case 'image/png': $img = imagecreatefrompng($this->getFilename()); break; case 'image/gif': $img = imagecreatefromgif($this->getFilename()); break; default: // Hmmm... \Core\Utilities\Logger\write_debug('Resizing complete (failed, not sure what it was)'); return; } if ($img) { $sW = imagesx($img); $sH = imagesy($img); $nW = $sW; $nH = $sH; switch($mode){ // Standard mode, images are scaled down (only) while preserving aspect ratio case '': case '<': if ($nW > $width) { $nH = $width * $sH / $sW; $nW = $width; } if ($nH > $height) { $nW = $height * $sW / $sH; $nH = $height; } break; // Only resize up case '>': if ($nW < $width) { $nH = $width * $sH / $sW; $nW = $width; } if ($nH < $height) { $nW = $height * $sW / $sH; $nH = $height; } break; // Resize to new size, regardless about aspect ratio case '!': $nW = $width; $nH = $height; break; // Resize image based on smallest dimension case '^': $ratioheight = $sW / $height; $ratiowidth = $sH / $width; if($ratioheight > 1 && $ratiowidth > 1){ // The image is larger than any of the dimensions, I can use the reduction logic. if(($width * $sH / $sW) > ($height * $sW / $sH)){ $nH = $width * $sH / $sW; $nW = $width; } else{ $nH = $height; $nW = $height * $sW / $sH; } } elseif($ratiowidth > $ratioheight){ // The image needs to be increased in size, this logic is slightly different. $nW = $width; $nH = round($width * $sH / $sW); } else{ $nH = $height; $nW = round($height * $sW / $sH); } } // If it's a JPEG, try to find the original thumbnail. /*if(false && $m == 'image/jpeg'){ $type = 'JPEG'; $img = exif_thumbnail($this->getFilename(), $nW, $nH, $type); $file->putContents($img); return; }*/ $img2 = imagecreatetruecolor($nW, $nH); imagealphablending($img2, false); imagesavealpha($img2, true); imagealphablending($img, true); // Assign a transparency color. //$trans = imagecolorallocatealpha($img2, 0, 0, 0, 0); //imagefill($img2, 0, 0, $trans); imagecopyresampled($img2, $img, 0, 0, 0, 0, $nW, $nH, $sW, $sH); imagedestroy($img); switch ($m) { case 'image/jpeg': imagejpeg($img2, $file->getFilename(), 60); \Core\Utilities\Logger\write_debug('Resizing complete (via imagejpeg)'); break; case 'image/png': imagepng($img2, $file->getFilename(), 9); \Core\Utilities\Logger\write_debug('Resizing complete (via imagepng)'); break; case 'image/gif': imagegif($img2, $file->getFilename()); \Core\Utilities\Logger\write_debug('Resizing complete (via imagegif)'); break; default: // Hmmm... \Core\Utilities\Logger\write_debug('Resizing complete (failed, not sure what it was)'); return; } } }