3 namespace Friendica\Util;
5 use Friendica\Core\Cache;
6 use Friendica\Core\Logger;
7 use Friendica\Core\System;
17 * Maps Mime types to Imagick formats
21 public static function getFormatsMap()
24 'image/jpeg' => 'JPG',
33 * Returns supported image mimetypes and corresponding file extensions
37 public static function supportedTypes()
42 if (class_exists('Imagick')) {
43 // Imagick::queryFormats won't help us a lot there...
44 // At least, not yet, other parts of friendica uses this array
49 } elseif (imagetypes() & IMG_PNG) {
59 * Guess image mimetype from filename or from Content-Type header
61 * @param string $filename Image filename
62 * @param boolean $fromcurl Check Content-Type header from curl request
63 * @param string $header passed headers to take into account
68 public static function guessType($filename, $fromcurl = false, $header = '')
70 Logger::info('Image: guessType: ' . $filename . ($fromcurl ? ' from curl headers' : ''));
74 $h = explode("\n", $header);
76 $data = array_map("trim", explode(":", trim($l), 2));
77 if (count($data) > 1) {
83 if (array_key_exists('Content-Type', $headers)) {
84 $type = $headers['Content-Type'];
89 // Guessing from extension? Isn't that... dangerous?
90 if (class_exists('Imagick') && file_exists($filename) && is_readable($filename)) {
92 * Well, this not much better,
93 * but at least it comes from the data inside the image,
94 * we won't be tricked by a manipulated extension
96 $image = new Imagick($filename);
97 $type = $image->getImageMimeType();
99 $ext = pathinfo($filename, PATHINFO_EXTENSION);
100 $types = self::supportedTypes();
101 $type = 'image/jpeg';
102 foreach ($types as $m => $e) {
110 Logger::info('Image: guessType: type=' . $type);
118 * @throws \Friendica\Network\HTTPException\InternalServerErrorException
120 public static function getInfoFromURLCached($url)
128 $data = DI::cache()->get($url);
130 if (empty($data) || !is_array($data)) {
131 $data = self::getInfoFromURL($url);
133 DI::cache()->set($url, $data);
142 * @throws \Friendica\Network\HTTPException\InternalServerErrorException
144 public static function getInfoFromURL($url)
152 $img_str = Network::fetchUrl($url, true, 4);
158 $filesize = strlen($img_str);
161 if (function_exists("getimagesizefromstring")) {
162 $data = @getimagesizefromstring($img_str);
164 $tempfile = tempnam(get_temppath(), "cache");
166 $stamp1 = microtime(true);
167 file_put_contents($tempfile, $img_str);
168 DI::profiler()->saveTimestamp($stamp1, "file", System::callstack());
170 $data = getimagesize($tempfile);
173 } catch (\Exception $e) {
178 $data['size'] = $filesize;
185 * @param integer $width
186 * @param integer $height
187 * @param integer $max
190 public static function getScalingDimensions($width, $height, $max)
192 if ((!$width) || (!$height)) {
193 return ['width' => 0, 'height' => 0];
196 if ($width > $max && $height > $max) {
197 // very tall image (greater than 16:9)
198 // constrain the width - let the height float.
200 if ((($height * 9) / 16) > $width) {
202 $dest_height = intval(($height * $max) / $width);
203 } elseif ($width > $height) {
204 // else constrain both dimensions
206 $dest_height = intval(($height * $max) / $width);
208 $dest_width = intval(($width * $max) / $height);
214 $dest_height = intval(($height * $max) / $width);
216 if ($height > $max) {
217 // very tall image (greater than 16:9)
218 // but width is OK - don't do anything
220 if ((($height * 9) / 16) > $width) {
221 $dest_width = $width;
222 $dest_height = $height;
224 $dest_width = intval(($width * $max) / $height);
228 $dest_width = $width;
229 $dest_height = $height;
234 return ['width' => $dest_width, 'height' => $dest_height];