예제 #1
0
	/**
	 * 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;
		}
	}
예제 #2
0
	/**
	 * 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;
			}
		}
	}