Portrait images rotating 90 degrees anti-clockwise with 6.9.10-68 Q16

Started by timbo79, August 10, 2020, 10:17:32 AM

Previous topic - Next topic

timbo79

Hi all,

My first post here so please go easy on me! :)

I'm afraid I'm not a developer I just mess with things until they work or I break something else.

I'm using ImageMagick together with Xenforo to process images.

A developer created an add-on for me that extracts some exif data from the images (using exiftool) that are uploaded as attachments and displays it below the images (it's a photography forum).

It's working perfectly for horizontal/landscape orientation images but for vertical/portrait orientation they are being rotated 90 degrees clockwise.

The problem is that it's working fine on my developers test server but not on my production server.

They did point me to this post https://forum.cgru.info/viewtopic.php?f=34&p=4719 where someone is having a similar problem with version 6.9.10-68 Q16 and fixed it by rolling back to a previous version.

Unfortunately right now I'm on a shared server and can't roll back, although I will be moving to a dedicated server soon so I can try this to see if rolling back will fix it.

However, first I just wanted to check if there's another option?

Below is the imagick.php that I'm using:


Thank you!





<?phpnamespace XF\Image;class Imagick extends AbstractDriver{	/**	 * @var \Imagick	 */	protected $imagick;	public static function isDriverUsable()	{		return class_exists('Imagick');	}	protected function _imageFromFile($file, $type)	{		switch ($type)		{			case IMAGETYPE_GIF:			case IMAGETYPE_JPEG:			case IMAGETYPE_PNG:				$image = new \Imagick($file);				break;			default:				throw new \InvalidArgumentException("Unknown image type '$type'");		}		$this->setImage($image);		return true;	}	protected function _createImage($width, $height)	{		$image = new \Imagick();		$background = new \ImagickPixel('white');		$image->newImage($width, $height, $background);		$this->setImage($image);		return true;	}	public function getImage()	{		return $this->imagick;	}	public function setImage(\Imagick $image)	{		$image->setImageBackgroundColor(new \ImagickPixel('transparent'));		$image = $image->coalesceImages();		$this->imagick = $image;		$this->updateDimensions();	}	protected function updateDimensions()	{		$this->width = $this->imagick->getImageWidth();		$this->height = $this->imagick->getImageHeight();	}	protected function isOldImagick()	{		// imagick module < 3 or ImageMagick < 6.3.2 don't support the 4th thumbnailImage param		$oldImagick = version_compare(phpversion('imagick'), '3', '<');		$version = $this->imagick->getVersion();		if (preg_match('#ImageMagick (\d+\.\d+\.\d+)#i', $version['versionString'], $match))		{			if (version_compare($match[1], '6.3.2', '<'))			{				$oldImagick = true;			}		}		return $oldImagick;	}	public function resizeTo($width, $height)	{		$scaleUp = ($width > $this->width || $height > $this->height);		try		{            foreach ($this->imagick AS $frame)            {                if ($scaleUp)                {                    $frame->resizeImage($width, $height, \Imagick::FILTER_LANCZOS, 1, true);				$frame->unsharpMaskImage(0 , 0.5 , 1 , 0.05);                }                else if ($this->isOldImagick())                {                    $frame->resizeImage($width, $height, \Imagick::FILTER_LANCZOS, 1, true);				$frame->unsharpMaskImage(0 , 0.5 , 1 , 0.05);                }                else                {                    $frame->resizeImage($width, $height, \Imagick::FILTER_LANCZOS, 1, true);				$frame->unsharpMaskImage(0 , 0.5 , 1 , 0.05);                }                $frame->setImagePage($width, $height, 0, 0);            }			$this->updateDimensions();		}		catch (\Exception $e) {}		return $this;	}	public function crop($width, $height, $x = 0, $y = 0, $srcWidth = null, $srcHeight = null)	{		foreach ($this->imagick AS $frame)		{			$frame->cropImage($srcWidth ?: $width, $srcHeight ?: $height, $x, $y);			if ($this->isOldImagick())			{				$frame->thumbnailImage($width, $height, false);			}			else			{				$frame->thumbnailImage($width, $height, false, true);			}			$frame->setImagePage($frame->getImageWidth(), $frame->getImageHeight(), 0, 0);		}		$this->updateDimensions();		return $this;	}	public function rotate($angle)	{		foreach ($this->imagick AS $frame)		{			$frame->rotateImage(new \ImagickPixel('none'), $angle);		}		$this->updateDimensions();		return $this;	}	public function flip($mode)	{		foreach ($this->imagick AS $frame)		{			switch ($mode)			{				case self::FLIP_HORIZONTAL:					$frame->flopImage();					break;				case self::FLIP_VERTICAL:					$frame->flipImage();					break;				case self::FLIP_BOTH:					$frame->flopImage();					$frame->flipImage();					break;				default:					throw new \InvalidArgumentException("Unknown flip mode");			}		}		$this->updateDimensions();		return $this;	}	public function setOpacity($opacity)	{		foreach ($this->imagick AS $frame)		{			$frame->evaluateImage(\Imagick::EVALUATE_MULTIPLY, $opacity, \Imagick::CHANNEL_ALPHA);		}		return $this;	}	public function appendImageAt($x, $y, $toAppend)	{		if (!($toAppend instanceof \Imagick))		{			throw new \InvalidArgumentException('Image to append must be a valid Imagick object.');		}		foreach ($this->imagick AS $frame)		{			$frame->compositeImage($toAppend, $toAppend->getImageCompose(), $x, $y);		}		return $this;	}	protected function _unsharpMask($radius, $sigma, $amount, $threshold)	{		foreach ($this->imagick AS $frame)		{			$frame->unsharpMaskImage($radius, $sigma, $amount, $threshold);		}		return $this;	}	public function save($file, $format = null, $quality = null)	{		if ($format === null)		{			$format = $this->type;		}		if ($quality === null)		{			$quality = 82;		}		if (method_exists($this->imagick, 'getImageProfiles'))		{			$profiles = $this->imagick->getImageProfiles('icc');            		//$this->imagick->stripImage();			if ($profiles && !empty($profiles['icc']))			{				$this->imagick->setImageProfile('icc', $profiles['icc']);			}		}		else		{			$this->imagick->stripImage();		}		switch ($format)		{			case IMAGETYPE_GIF:				if (is_callable(array($this->imagick, 'optimizeimagelayers')))				{					$optimized = @$this->imagick->optimizeimagelayers();					if ($optimized instanceof \Imagick)					{						$this->imagick = $optimized;					}					$deconstructed = @$this->imagick->deconstructImages();					if ($deconstructed instanceof \Imagick)					{						$this->imagick = $deconstructed;					}				}				$success = $this->imagick->setImageFormat('gif');				break;			case IMAGETYPE_JPEG:				$success = $this->imagick->setImageFormat('jpeg')					&& $this->imagick->setImageCompression(\Imagick::COMPRESSION_JPEG)					&& $this->imagick->setImageCompressionQuality($quality);				break;			case IMAGETYPE_PNG:				$success = $this->imagick->setImageFormat('png');				break;			default:				throw new \InvalidArgumentException('Invalid format given. Expects IMAGETYPE_XXX constant.');		}		if ($success)		{			try			{				return $this->imagick->writeImages($file, true);			}			catch (\ImagickException $e) {}		}		return false;	}	public function output($format = null, $quality = null)	{		if ($format === null)		{			$format = $this->type;		}		if ($quality === null)		{			$quality = 82;		}		$this->imagick->stripImage();		switch ($format)		{			case IMAGETYPE_GIF:				$success = $this->imagick->optimizeImageLayers();				break;			case IMAGETYPE_JPEG:				$success = $this->imagick->setImageFormat('jpeg')					&& $this->imagick->setImageCompression(\Imagick::COMPRESSION_JPEG)					&& $this->imagick->setImageCompressionQuality($quality);				break;			case IMAGETYPE_PNG:				$success = $this->imagick->setImageFormat('png');				break;			default:				throw new \InvalidArgumentException('Invalid format given. Expects IMAGETYPE_XXX constant.');		}		if ($success)		{			try			{				echo $this->imagick->getImagesBlob();			}			catch (\ImagickException $e) {}		}	}	public function isValid()	{		return $this->imagick->valid();	}	public function __destruct()	{		if ($this->imagick)		{			$this->imagick->destroy();			$this->imagick = null;		}	}}







StarGeek

From the sound of things, ImageMagick isn't preserving/honoring the EXIF:Orientation.  And while your code does appear to have a subroutine to deal with rotation, it doesn't look like this is the code that would actually extract the the Orientation for the image.

I should point out that this is a forum for Exiftool and your example code is completely about ImageMagick.  As far as I can tell, exiftool isn't even called from it.
"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype

timbo79

Quote from: StarGeek on August 10, 2020, 10:45:52 AM
From the sound of things, ImageMagick isn't preserving/honoring the EXIF:Orientation.  And while your code does appear to have a subroutine to deal with rotation, it doesn't look like this is the code that would actually extract the the Orientation for the image.

I should point out that this is a forum for Exiftool and your example code is completely about ImageMagick.  As far as I can tell, exiftool isn't even called from it.

Thanks for replying, I really appreciate it. You are right, I should probably find a forum that is focused on ImageMagick. I'm scratching my head now wondering why I posted this here!