nfTlWNl rn Ѻq$³*dm^̓|[N oY›( ݗ/. vu˼ƒPQ?ltjd/ 7uⓙ}]w&]T;m]ى8XzHVr-\e*~-VД5NS˦7#¬JV9VwRF}1/H8ͦ*`iBNA$wci+xnU \FwtMGɻUڡ3$mMٰzHk35"[rMxo2巒tFhz:[ҋ0C,1I:r; sǐ䩮9Ʉ/(?$ ׋]9ݾ3" q`})3 +3L?-=_ &$*#lsl'Cn:z5c>$:ҁ#c0pWUe^qH7$v#))EI]†޶D9鸏C:eN B7+N6U*>j7m&%Lkx:0N 1#N ց*~W7jf^7_BJ]gk6p,vkD//A: }4Q#*u' 8 !K1Bi&1_٭ k/k,N>c[s?R-.ވMX+owVSTT`YЗ@otO@R _(5oqW=~_ IDZU$rL!~ڼDn~Hm]E ##['t%3-$OF<㜆qGi~Ktfgc(yEATecYfT W3w> F#pdtnٹAq7]l.+]`&$t%3-9..ˣ"9RcsZ_EsЙ6Xz" /;ঊE~9\Ka[V2م)G#Xc$l.C5 i1Y :ʺJ$+}6XvICjXU^387@v BMKp=~U4O#&F{mM{!+${]N7CfL@Q \Co1Rz ?&#~ZC]'>70]zُd⎺~+@O^Z0!$F\j3 W;t;3]Fivaf@}gd =,*G˶ d X?gD./4"t$D 1*ۍ9+L21ѐ]Β>E`::+X }׋\_.6_tF5 k6~OIO\1 ZyJYRC?LɭkoOer`-!_PH'M}arzq?Ut;GBg۳bI 96"hT~II(=.O4uO[uhVj!(ѫr_#F3dVHC_z(ܾAT~țBmRmL-&c(tIz[gqvZFXK9gjqź%rT zֶ䏢UgFZՕ Y| #UM9A Wn &@\V=iSVnR6Q)&M0X>,5j(н P-V?w. ((WJB|[5|Pue5#A+ܶ95JB6"L)0#2PMagxڅfP\UN >L68h`ߛ~طqeXK.^_LƆjrkH\N"鑶#K'k$.TUA]"OO 'O@ Y}AD^!ɟHgU(bʚ_ ĢQ$3ͻ/n uUB"a[=FVcd=ww8_pb.P(נV̍ayUz~OTӷb0\eaQǺf+ת{kl9R+{`|2jQ[چf1kQ*Q|_C o4=aNV(3~O1,F'6g&[ Kx8v\C &d-;j5$(pY!PoZ#x>)s<y???ŏƄ} %;6!3 eɍ9 +KQ<{+q"wO#MF7%1wtD MVJBH q) H yͩ|`g|Zmţ{ hnh \דT|؉lLOwҜvG2 q&'}VTS! _0ysLS&srqnau> dSsfe2huzXN$h7,x 3@DabRp` I~}2 )Bs8a!R8[ی̙Ͼ֖#SP2|ke 5K_z!;ТG.dT w폎tb!" 'يN/:n83av\8z5#؂ \4@:|,dwuZ{yy?'khϓH+}] gP zaH4M痤$0ө e!H^j) L_, ӯ^̩}kT#L؀Cr2qGp,uQMbJ>ing $imageString): self { $gdImage = @imagecreatefromstring($imageString); if ($gdImage === false) { throw new Exception('Value cannot be converted to an image'); } $mimeType = self::identifyMimeType($imageString); $renderingFunction = self::identifyRenderingFunction($mimeType); $drawing = new self(); $drawing->setImageResource($gdImage); $drawing->setRenderingFunction($renderingFunction); $drawing->setMimeType($mimeType); return $drawing; } private static function identifyRenderingFunction(string $mimeType): string { switch ($mimeType) { case self::MIMETYPE_PNG: return self::RENDERING_PNG; case self::MIMETYPE_JPEG: return self::RENDERING_JPEG; case self::MIMETYPE_GIF: return self::RENDERING_GIF; } return self::RENDERING_DEFAULT; } /** * @throws Exception */ private static function identifyMimeType(string $imageString): string { $temporaryFileName = File::temporaryFilename(); file_put_contents($temporaryFileName, $imageString); $mimeType = self::identifyMimeTypeUsingExif($temporaryFileName); if ($mimeType !== null) { unlink($temporaryFileName); return $mimeType; } $mimeType = self::identifyMimeTypeUsingGd($temporaryFileName); if ($mimeType !== null) { unlink($temporaryFileName); return $mimeType; } unlink($temporaryFileName); return self::MIMETYPE_DEFAULT; } private static function identifyMimeTypeUsingExif(string $temporaryFileName): ?string { if (function_exists('exif_imagetype')) { $imageType = @exif_imagetype($temporaryFileName); $mimeType = ($imageType) ? image_type_to_mime_type($imageType) : null; return self::supportedMimeTypes($mimeType); } return null; } private static function identifyMimeTypeUsingGd(string $temporaryFileName): ?string { if (function_exists('getimagesize')) { $imageSize = @getimagesize($temporaryFileName); if (is_array($imageSize)) { $mimeType = $imageSize['mime'] ?? null; return self::supportedMimeTypes($mimeType); } } return null; } private static function supportedMimeTypes(?string $mimeType = null): ?string { if (in_array($mimeType, self::SUPPORTED_MIME_TYPES, true)) { return $mimeType; } return null; } /** * Get image resource. * * @return null|GdImage|resource */ public function getImageResource() { return $this->imageResource; } /** * Set image resource. * * @param GdImage|resource $value * * @return $this */ public function setImageResource($value) { $this->imageResource = $value; if ($this->imageResource !== null) { // Get width/height $this->width = (int) imagesx($this->imageResource); $this->height = (int) imagesy($this->imageResource); } return $this; } /** * Get rendering function. * * @return string */ public function getRenderingFunction() { return $this->renderingFunction; } /** * Set rendering function. * * @param string $value see self::RENDERING_* * * @return $this */ public function setRenderingFunction($value) { $this->renderingFunction = $value; return $this; } /** * Get mime type. * * @return string */ public function getMimeType() { return $this->mimeType; } /** * Set mime type. * * @param string $value see self::MIMETYPE_* * * @return $this */ public function setMimeType($value) { $this->mimeType = $value; return $this; } /** * Get indexed filename (using image index). */ public function getIndexedFilename(): string { $extension = strtolower($this->getMimeType()); $extension = explode('/', $extension); $extension = $extension[1]; return $this->uniqueName . $this->getImageIndex() . '.' . $extension; } /** * Get hash code. * * @return string Hash code */ public function getHashCode() { return md5( $this->renderingFunction . $this->mimeType . $this->uniqueName . parent::getHashCode() . __CLASS__ ); } }