3 namespace Friendica\Util;
5 use Friendica\BaseObject;
6 use Friendica\Core\Cache;
7 use Friendica\Core\Logger;
8 use Friendica\Core\System;
18 * Maps Mime types to Imagick formats
22 public static function getFormatsMap()
25 'image/jpeg' => 'JPG',
34 * Returns supported image mimetypes and corresponding file extensions
38 public static function supportedTypes()
43 if (class_exists('Imagick')) {
44 // Imagick::queryFormats won't help us a lot there...
45 // At least, not yet, other parts of friendica uses this array
50 } elseif (imagetypes() & IMG_PNG) {
60 * Guess image mimetype from filename or from Content-Type header
62 * @param string $filename Image filename
63 * @param boolean $fromcurl Check Content-Type header from curl request
64 * @param string $header passed headers to take into account
69 public static function guessType($filename, $fromcurl = false, $header = '')
71 Logger::info('Image: guessType: ' . $filename . ($fromcurl ? ' from curl headers' : ''));
75 $h = explode("\n", $header);
77 $data = array_map("trim", explode(":", trim($l), 2));
78 if (count($data) > 1) {
84 if (array_key_exists('Content-Type', $headers)) {
85 $type = $headers['Content-Type'];
90 // Guessing from extension? Isn't that... dangerous?
91 if (class_exists('Imagick') && file_exists($filename) && is_readable($filename)) {
93 * Well, this not much better,
94 * but at least it comes from the data inside the image,
95 * we won't be tricked by a manipulated extension
97 $image = new Imagick($filename);
98 $type = $image->getImageMimeType();
100 $ext = pathinfo($filename, PATHINFO_EXTENSION);
101 $types = self::supportedTypes();
102 $type = 'image/jpeg';
103 foreach ($types as $m => $e) {
111 Logger::info('Image: guessType: type=' . $type);
119 * @throws \Friendica\Network\HTTPException\InternalServerErrorException
121 public static function getInfoFromURLCached($url)
129 $data = Cache::get($url);
131 if (empty($data) || !is_array($data)) {
132 $data = self::getInfoFromURL($url);
134 Cache::set($url, $data);
143 * @throws \Friendica\Network\HTTPException\InternalServerErrorException
145 public static function getInfoFromURL($url)
153 $img_str = Network::fetchUrl($url, true, 4);
159 $filesize = strlen($img_str);
162 if (function_exists("getimagesizefromstring")) {
163 $data = @getimagesizefromstring($img_str);
165 $tempfile = tempnam(get_temppath(), "cache");
167 $stamp1 = microtime(true);
168 file_put_contents($tempfile, $img_str);
169 DI::app()->getProfiler()->saveTimestamp($stamp1, "file", System::callstack());
171 $data = getimagesize($tempfile);
174 } catch (\Exception $e) {
179 $data['size'] = $filesize;
186 * @param integer $width
187 * @param integer $height
188 * @param integer $max
191 public static function getScalingDimensions($width, $height, $max)
193 if ((!$width) || (!$height)) {
194 return ['width' => 0, 'height' => 0];
197 if ($width > $max && $height > $max) {
198 // very tall image (greater than 16:9)
199 // constrain the width - let the height float.
201 if ((($height * 9) / 16) > $width) {
203 $dest_height = intval(($height * $max) / $width);
204 } elseif ($width > $height) {
205 // else constrain both dimensions
207 $dest_height = intval(($height * $max) / $width);
209 $dest_width = intval(($width * $max) / $height);
215 $dest_height = intval(($height * $max) / $width);
217 if ($height > $max) {
218 // very tall image (greater than 16:9)
219 // but width is OK - don't do anything
221 if ((($height * 9) / 16) > $width) {
222 $dest_width = $width;
223 $dest_height = $height;
225 $dest_width = intval(($width * $max) / $height);
229 $dest_width = $width;
230 $dest_height = $height;
235 return ['width' => $dest_width, 'height' => $dest_height];