Move Object\Image static methods to Util\Images

- Optimize imports in modified files
This commit is contained in:
Hypolite Petovan 2019-10-17 21:26:15 -04:00
parent b543ee8ac7
commit 03bf1dcbd3
15 changed files with 322 additions and 217 deletions

View file

@ -45,6 +45,7 @@ use Friendica\Object\Image;
use Friendica\Protocol\Activity; use Friendica\Protocol\Activity;
use Friendica\Protocol\Diaspora; use Friendica\Protocol\Diaspora;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Images;
use Friendica\Util\Network; use Friendica\Util\Network;
use Friendica\Util\Proxy as ProxyUtils; use Friendica\Util\Proxy as ProxyUtils;
use Friendica\Util\Strings; use Friendica\Util\Strings;
@ -1167,7 +1168,7 @@ function api_statuses_update($type)
api_user() api_user()
); );
if (DBA::isResult($r)) { if (DBA::isResult($r)) {
$phototypes = Image::supportedTypes(); $phototypes = Images::supportedTypes();
$ext = $phototypes[$r[0]['type']]; $ext = $phototypes[$r[0]['type']];
$description = $r[0]['desc'] ?? ''; $description = $r[0]['desc'] ?? '';
$_REQUEST['body'] .= "\n\n" . '[url=' . System::baseUrl() . '/photos/' . $r[0]['nickname'] . '/image/' . $r[0]['resource-id'] . ']'; $_REQUEST['body'] .= "\n\n" . '[url=' . System::baseUrl() . '/photos/' . $r[0]['nickname'] . '/image/' . $r[0]['resource-id'] . ']';
@ -2564,7 +2565,7 @@ function api_get_attachments(&$body)
$attachments = []; $attachments = [];
foreach ($images[1] as $image) { foreach ($images[1] as $image) {
$imagedata = Image::getInfoFromURL($image); $imagedata = Images::getInfoFromURLCached($image);
if ($imagedata) { if ($imagedata) {
$attachments[] = ["url" => $image, "mimetype" => $imagedata["mime"], "size" => $imagedata["size"]]; $attachments[] = ["url" => $image, "mimetype" => $imagedata["mime"], "size" => $imagedata["size"]];
@ -2711,7 +2712,7 @@ function api_get_entitities(&$text, $bbcode)
$start = iconv_strpos($text, $url, $offset, "UTF-8"); $start = iconv_strpos($text, $url, $offset, "UTF-8");
if (!($start === false)) { if (!($start === false)) {
$image = Image::getInfoFromURL($url); $image = Images::getInfoFromURLCached($url);
if ($image) { if ($image) {
// If image cache is activated, then use the following sizes: // If image cache is activated, then use the following sizes:
// thumb (150), small (340), medium (600) and large (1024) // thumb (150), small (340), medium (600) and large (1024)
@ -2719,19 +2720,19 @@ function api_get_entitities(&$text, $bbcode)
$media_url = ProxyUtils::proxifyUrl($url); $media_url = ProxyUtils::proxifyUrl($url);
$sizes = []; $sizes = [];
$scale = Image::getScalingDimensions($image[0], $image[1], 150); $scale = Images::getScalingDimensions($image[0], $image[1], 150);
$sizes["thumb"] = ["w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"]; $sizes["thumb"] = ["w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"];
if (($image[0] > 150) || ($image[1] > 150)) { if (($image[0] > 150) || ($image[1] > 150)) {
$scale = Image::getScalingDimensions($image[0], $image[1], 340); $scale = Images::getScalingDimensions($image[0], $image[1], 340);
$sizes["small"] = ["w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"]; $sizes["small"] = ["w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"];
} }
$scale = Image::getScalingDimensions($image[0], $image[1], 600); $scale = Images::getScalingDimensions($image[0], $image[1], 600);
$sizes["medium"] = ["w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"]; $sizes["medium"] = ["w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"];
if (($image[0] > 600) || ($image[1] > 600)) { if (($image[0] > 600) || ($image[1] > 600)) {
$scale = Image::getScalingDimensions($image[0], $image[1], 1024); $scale = Images::getScalingDimensions($image[0], $image[1], 1024);
$sizes["large"] = ["w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"]; $sizes["large"] = ["w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"];
} }
} else { } else {
@ -4740,7 +4741,7 @@ function save_media_to_database($mediatype, $media, $type, $album, $allow_cid, $
} }
if ($filetype == "") { if ($filetype == "") {
$filetype=Image::guessType($filename); $filetype = Images::guessType($filename);
} }
$imagedata = @getimagesize($src); $imagedata = @getimagesize($src);
if ($imagedata) { if ($imagedata) {

View file

@ -10,7 +10,7 @@ use Friendica\Core\L10n;
use Friendica\Core\Renderer; use Friendica\Core\Renderer;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\Object\Image; use Friendica\Util\Images;
use Friendica\Util\Strings; use Friendica\Util\Strings;
/** /**
@ -79,7 +79,7 @@ function fbrowser_content(App $a)
function _map_files1($rr) function _map_files1($rr)
{ {
$a = \get_app(); $a = \get_app();
$types = Image::supportedTypes(); $types = Images::supportedTypes();
$ext = $types[$rr['type']]; $ext = $types[$rr['type']];
$filename_e = $rr['filename']; $filename_e = $rr['filename'];

View file

@ -29,6 +29,7 @@ use Friendica\Protocol\Activity;
use Friendica\Util\ACLFormatter; use Friendica\Util\ACLFormatter;
use Friendica\Util\Crypto; use Friendica\Util\Crypto;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Images;
use Friendica\Util\Map; use Friendica\Util\Map;
use Friendica\Util\Security; use Friendica\Util\Security;
use Friendica\Util\Strings; use Friendica\Util\Strings;
@ -142,7 +143,7 @@ function photos_post(App $a)
Logger::log('mod_photos: REQUEST ' . print_r($_REQUEST, true), Logger::DATA); Logger::log('mod_photos: REQUEST ' . print_r($_REQUEST, true), Logger::DATA);
Logger::log('mod_photos: FILES ' . print_r($_FILES, true), Logger::DATA); Logger::log('mod_photos: FILES ' . print_r($_FILES, true), Logger::DATA);
$phototypes = Image::supportedTypes(); $phototypes = Images::supportedTypes();
$can_post = false; $can_post = false;
$visitor = 0; $visitor = 0;
@ -694,7 +695,7 @@ function photos_post(App $a)
} }
if ($type == "") { if ($type == "") {
$type = Image::guessType($filename); $type = Images::guessType($filename);
} }
Logger::log('photos: upload: received file: ' . $filename . ' as ' . $src . ' ('. $type . ') ' . $filesize . ' bytes', Logger::DEBUG); Logger::log('photos: upload: received file: ' . $filename . ' as ' . $src . ' ('. $type . ') ' . $filesize . ' bytes', Logger::DEBUG);
@ -846,7 +847,7 @@ function photos_content(App $a)
return; return;
} }
$phototypes = Image::supportedTypes(); $phototypes = Images::supportedTypes();
$_SESSION['photo_return'] = $a->cmd; $_SESSION['photo_return'] = $a->cmd;

View file

@ -9,16 +9,16 @@
*/ */
use Friendica\App; use Friendica\App;
use Friendica\Core\Config;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Core\Logger; use Friendica\Core\Logger;
use Friendica\Core\System;
use Friendica\Core\Session; use Friendica\Core\Session;
use Friendica\Core\Config; use Friendica\Core\System;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Model\Photo; use Friendica\Model\Photo;
use Friendica\Model\User; use Friendica\Model\User;
use Friendica\Object\Image; use Friendica\Object\Image;
use Friendica\Util\Images;
use Friendica\Util\Strings; use Friendica\Util\Strings;
function wall_upload_post(App $a, $desktopmode = true) function wall_upload_post(App $a, $desktopmode = true)
@ -166,7 +166,7 @@ function wall_upload_post(App $a, $desktopmode = true)
} }
if ($filetype == "") { if ($filetype == "") {
$filetype = Image::guessType($filename); $filetype = Images::guessType($filename);
} }
// If there is a temp name, then do a manual check // If there is a temp name, then do a manual check

View file

@ -25,6 +25,7 @@ use Friendica\Model\Photo;
use Friendica\Network\Probe; use Friendica\Network\Probe;
use Friendica\Object\Image; use Friendica\Object\Image;
use Friendica\Protocol\Activity; use Friendica\Protocol\Activity;
use Friendica\Util\Images;
use Friendica\Util\Map; use Friendica\Util\Map;
use Friendica\Util\Network; use Friendica\Util\Network;
use Friendica\Util\ParseUrl; use Friendica\Util\ParseUrl;
@ -76,7 +77,7 @@ class BBCode extends BaseObject
if (preg_match("/\[img\](.*?)\[\/img\]/ism", $attacheddata, $matches)) { if (preg_match("/\[img\](.*?)\[\/img\]/ism", $attacheddata, $matches)) {
$picturedata = Image::getInfoFromURL($matches[1]); $picturedata = Images::getInfoFromURLCached($matches[1]);
if ($picturedata) { if ($picturedata) {
if (($picturedata[0] >= 500) && ($picturedata[0] >= $picturedata[1])) { if (($picturedata[0] >= 500) && ($picturedata[0] >= $picturedata[1])) {
@ -305,7 +306,7 @@ class BBCode extends BaseObject
$post['preview'] = $pictures[0][2]; $post['preview'] = $pictures[0][2];
$post['text'] = trim(str_replace($pictures[0][0], '', $body)); $post['text'] = trim(str_replace($pictures[0][0], '', $body));
} else { } else {
$imgdata = Image::getInfoFromURL($pictures[0][1]); $imgdata = Images::getInfoFromURLCached($pictures[0][1]);
if ($imgdata && substr($imgdata['mime'], 0, 6) == 'image/') { if ($imgdata && substr($imgdata['mime'], 0, 6) == 'image/') {
$post['type'] = 'photo'; $post['type'] = 'photo';
$post['image'] = $pictures[0][1]; $post['image'] = $pictures[0][1];
@ -446,7 +447,7 @@ class BBCode extends BaseObject
} }
// guess mimetype from headers or filename // guess mimetype from headers or filename
$type = Image::guessType($mtch[1], true); $type = Images::guessType($mtch[1], true);
if ($i) { if ($i) {
$Image = new Image($i, $type); $Image = new Image($i, $type);

View file

@ -9,7 +9,7 @@ use Exception;
use Friendica\Core\Config\Cache\ConfigCache; use Friendica\Core\Config\Cache\ConfigCache;
use Friendica\Database\Database; use Friendica\Database\Database;
use Friendica\Database\DBStructure; use Friendica\Database\DBStructure;
use Friendica\Object\Image; use Friendica\Util\Images;
use Friendica\Util\Network; use Friendica\Util\Network;
use Friendica\Util\Strings; use Friendica\Util\Strings;
@ -569,7 +569,7 @@ class Installer
if (class_exists('Imagick')) { if (class_exists('Imagick')) {
$imagick = true; $imagick = true;
$supported = Image::supportedTypes(); $supported = Images::supportedTypes();
if (array_key_exists('image/gif', $supported)) { if (array_key_exists('image/gif', $supported)) {
$gif = true; $gif = true;
} }

View file

@ -25,6 +25,7 @@ use Friendica\Protocol\Diaspora;
use Friendica\Protocol\OStatus; use Friendica\Protocol\OStatus;
use Friendica\Protocol\Salmon; use Friendica\Protocol\Salmon;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Images;
use Friendica\Util\Network; use Friendica\Util\Network;
use Friendica\Util\Strings; use Friendica\Util\Strings;
@ -719,7 +720,7 @@ class Contact extends BaseObject
} }
// Creating the path to the avatar, beginning with the file suffix // Creating the path to the avatar, beginning with the file suffix
$types = Image::supportedTypes(); $types = Images::supportedTypes();
if (isset($types[$avatar['type']])) { if (isset($types[$avatar['type']])) {
$file_suffix = $types[$avatar['type']]; $file_suffix = $types[$avatar['type']];
} }

View file

@ -17,8 +17,8 @@ use Friendica\Database\DBA;
use Friendica\Database\DBStructure; use Friendica\Database\DBStructure;
use Friendica\Model\Storage\IStorage; use Friendica\Model\Storage\IStorage;
use Friendica\Object\Image; use Friendica\Object\Image;
use Friendica\Protocol\DFRN;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Images;
use Friendica\Util\Network; use Friendica\Util\Network;
use Friendica\Util\Security; use Friendica\Util\Security;
use Friendica\Util\Strings; use Friendica\Util\Strings;
@ -425,7 +425,7 @@ class Photo extends BaseObject
} }
if (empty($type)) { if (empty($type)) {
$type = Image::guessType($image_url, true); $type = Images::guessType($image_url, true);
} }
$Image = new Image($img_str, $type); $Image = new Image($img_str, $type);
@ -664,7 +664,7 @@ class Photo extends BaseObject
public static function stripExtension($name) public static function stripExtension($name)
{ {
$name = str_replace([".jpg", ".png", ".gif"], ["", "", ""], $name); $name = str_replace([".jpg", ".png", ".gif"], ["", "", ""], $name);
foreach (Image::supportedTypes() as $m => $e) { foreach (Images::supportedTypes() as $m => $e) {
$name = str_replace("." . $e, "", $name); $name = str_replace("." . $e, "", $name);
} }
return $name; return $name;

View file

@ -22,6 +22,7 @@ use Friendica\Model\TwoFactor\AppSpecificPassword;
use Friendica\Object\Image; use Friendica\Object\Image;
use Friendica\Util\Crypto; use Friendica\Util\Crypto;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Images;
use Friendica\Util\Network; use Friendica\Util\Network;
use Friendica\Util\Strings; use Friendica\Util\Strings;
use Friendica\Worker\Delivery; use Friendica\Worker\Delivery;
@ -829,7 +830,7 @@ class User
$filename = basename($photo); $filename = basename($photo);
$img_str = Network::fetchUrl($photo, true); $img_str = Network::fetchUrl($photo, true);
// guess mimetype from headers or filename // guess mimetype from headers or filename
$type = Image::guessType($photo, true); $type = Images::guessType($photo, true);
$Image = new Image($img_str, $type); $Image = new Image($img_str, $type);
if ($Image->isValid()) { if ($Image->isValid()) {

View file

@ -6,11 +6,9 @@
namespace Friendica\Object; namespace Friendica\Object;
use Exception; use Exception;
use Friendica\Core\Cache;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Core\Logger;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Util\Network; use Friendica\Util\Images;
use Imagick; use Imagick;
use ImagickPixel; use ImagickPixel;
@ -32,31 +30,6 @@ class Image
private $type; private $type;
private $types; private $types;
/**
* @brief supported mimetypes and corresponding file extensions
* @return array
*/
public static function supportedTypes()
{
if (class_exists('Imagick')) {
// Imagick::queryFormats won't help us a lot there...
// At least, not yet, other parts of friendica uses this array
$t = [
'image/jpeg' => 'jpg',
'image/png' => 'png',
'image/gif' => 'gif'
];
} else {
$t = [];
$t['image/jpeg'] ='jpg';
if (imagetypes() & IMG_PNG) {
$t['image/png'] = 'png';
}
}
return $t;
}
/** /**
* @brief Constructor * @brief Constructor
* @param string $data * @param string $data
@ -67,9 +40,9 @@ class Image
public function __construct($data, $type = null) public function __construct($data, $type = null)
{ {
$this->imagick = class_exists('Imagick'); $this->imagick = class_exists('Imagick');
$this->types = static::supportedTypes(); $this->types = Images::supportedTypes();
if (!array_key_exists($type, $this->types)) { if (!array_key_exists($type, $this->types)) {
$type='image/jpeg'; $type = 'image/jpeg';
} }
$this->type = $type; $this->type = $type;
@ -108,20 +81,6 @@ class Image
return $this->imagick; return $this->imagick;
} }
/**
* @brief Maps Mime types to Imagick formats
* @return array With with image formats (mime type as key)
*/
public static function getFormatsMap()
{
$m = [
'image/jpeg' => 'JPG',
'image/png' => 'PNG',
'image/gif' => 'GIF'
];
return $m;
}
/** /**
* @param string $data data * @param string $data data
* @return boolean * @return boolean
@ -142,7 +101,7 @@ class Image
/* /*
* Setup the image to the format it will be saved to * Setup the image to the format it will be saved to
*/ */
$map = self::getFormatsMap(); $map = Images::getFormatsMap();
$format = $map[$this->type]; $format = $map[$this->type];
$this->image->setFormat($format); $this->image->setFormat($format);
@ -712,6 +671,26 @@ class Image
return $string; return $string;
} }
/**
* @brief supported mimetypes and corresponding file extensions
* @return array
* @deprecated in version 2019.12 please use Util\Images::supportedTypes() instead.
*/
public static function supportedTypes()
{
return Images::supportedTypes();
}
/**
* @brief Maps Mime types to Imagick formats
* @return array With with image formats (mime type as key)
* @deprecated in version 2019.12 please use Util\Images::getFormatsMap() instead.
*/
public static function getFormatsMap()
{
return Images::getFormatsMap();
}
/** /**
* Guess image mimetype from filename or from Content-Type header * Guess image mimetype from filename or from Content-Type header
* *
@ -719,102 +698,24 @@ class Image
* @param boolean $fromcurl Check Content-Type header from curl request * @param boolean $fromcurl Check Content-Type header from curl request
* @param string $header passed headers to take into account * @param string $header passed headers to take into account
* *
* @return object * @return string|null
* @throws \ImagickException * @throws Exception
* @deprecated in version 2019.12 please use Util\Images::guessType() instead.
*/ */
public static function guessType($filename, $fromcurl = false, $header = '') public static function guessType($filename, $fromcurl = false, $header = '')
{ {
Logger::log('Image: guessType: '.$filename . ($fromcurl?' from curl headers':''), Logger::DEBUG); return Images::guessType($filename, $fromcurl, $header);
$type = null;
if ($fromcurl) {
$headers=[];
$h = explode("\n", $header);
foreach ($h as $l) {
$data = array_map("trim", explode(":", trim($l), 2));
if (count($data) > 1) {
list($k,$v) = $data;
$headers[$k] = $v;
}
}
if (array_key_exists('Content-Type', $headers))
$type = $headers['Content-Type'];
}
if (is_null($type)) {
// Guessing from extension? Isn't that... dangerous?
if (class_exists('Imagick') && file_exists($filename) && is_readable($filename)) {
/**
* Well, this not much better,
* but at least it comes from the data inside the image,
* we won't be tricked by a manipulated extension
*/
$image = new Imagick($filename);
$type = $image->getImageMimeType();
$image->setInterlaceScheme(Imagick::INTERLACE_PLANE);
} else {
$ext = pathinfo($filename, PATHINFO_EXTENSION);
$types = self::supportedTypes();
$type = "image/jpeg";
foreach ($types as $m => $e) {
if ($ext == $e) {
$type = $m;
}
}
}
}
Logger::log('Image: guessType: type='.$type, Logger::DEBUG);
return $type;
} }
/** /**
* @param string $url url * @param string $url url
* @return object * @return array
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @deprecated in version 2019.12 please use Util\Images::getInfoFromURLCached() instead.
*/ */
public static function getInfoFromURL($url) public static function getInfoFromURL($url)
{ {
$data = []; return Images::getInfoFromURLCached($url);
if (empty($url)) {
return $data;
}
$data = Cache::get($url);
if (is_null($data) || !$data || !is_array($data)) {
$img_str = Network::fetchUrl($url, true, 4);
if (!$img_str) {
return false;
}
$filesize = strlen($img_str);
try {
if (function_exists("getimagesizefromstring")) {
$data = @getimagesizefromstring($img_str);
} else {
$tempfile = tempnam(get_temppath(), "cache");
$a = \get_app();
$stamp1 = microtime(true);
file_put_contents($tempfile, $img_str);
$a->getProfiler()->saveTimestamp($stamp1, "file", System::callstack());
$data = getimagesize($tempfile);
unlink($tempfile);
}
} catch (Exception $e) {
return false;
}
if ($data) {
$data["size"] = $filesize;
}
Cache::set($url, $data);
}
return $data;
} }
/** /**
@ -822,50 +723,10 @@ class Image
* @param integer $height height * @param integer $height height
* @param integer $max max * @param integer $max max
* @return array * @return array
* @deprecated in version 2019.12 please use Util\Images::getScalingDimensions() instead.
*/ */
public static function getScalingDimensions($width, $height, $max) public static function getScalingDimensions($width, $height, $max)
{ {
if ((!$width) || (!$height)) { return Images::getScalingDimensions($width, $height, $max);
return false;
}
if ($width > $max && $height > $max) {
// very tall image (greater than 16:9)
// constrain the width - let the height float.
if ((($height * 9) / 16) > $width) {
$dest_width = $max;
$dest_height = intval(($height * $max) / $width);
} elseif ($width > $height) {
// else constrain both dimensions
$dest_width = $max;
$dest_height = intval(($height * $max) / $width);
} else {
$dest_width = intval(($width * $max) / $height);
$dest_height = $max;
}
} else {
if ($width > $max) {
$dest_width = $max;
$dest_height = intval(($height * $max) / $width);
} else {
if ($height > $max) {
// very tall image (greater than 16:9)
// but width is OK - don't do anything
if ((($height * 9) / 16) > $width) {
$dest_width = $width;
$dest_height = $height;
} else {
$dest_width = intval(($width * $max) / $height);
$dest_height = $max;
}
} else {
$dest_width = $width;
$dest_height = $height;
}
}
}
return ["width" => $dest_width, "height" => $dest_height];
} }
} }

View file

@ -6,31 +6,33 @@ namespace Friendica\Protocol\ActivityPub;
use Friendica\BaseObject; use Friendica\BaseObject;
use Friendica\Content\Feature; use Friendica\Content\Feature;
use Friendica\Database\DBA; use Friendica\Content\Text\BBCode;
use Friendica\Content\Text\Plaintext;
use Friendica\Core\Cache;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Core\Logger; use Friendica\Core\Logger;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Protocol\Activity; use Friendica\Protocol\Activity;
use Friendica\Util\HTTPSignature; use Friendica\Util\HTTPSignature;
use Friendica\Core\Protocol; use Friendica\Core\Protocol;
use Friendica\Model\Conversation; use Friendica\Core\System;
use Friendica\Model\Contact; use Friendica\Database\DBA;
use Friendica\Model\APContact; use Friendica\Model\APContact;
use Friendica\Model\Contact;
use Friendica\Model\Conversation;
use Friendica\Model\Item; use Friendica\Model\Item;
use Friendica\Model\Profile;
use Friendica\Model\Term; use Friendica\Model\Term;
use Friendica\Model\User; use Friendica\Model\User;
use Friendica\Protocol\ActivityPub;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Content\Text\BBCode; use Friendica\Util\HTTPSignature;
use Friendica\Content\Text\Plaintext; use Friendica\Util\Images;
use Friendica\Util\XML;
use Friendica\Util\JsonLD; use Friendica\Util\JsonLD;
use Friendica\Util\LDSignature; use Friendica\Util\LDSignature;
use Friendica\Model\Profile;
use Friendica\Object\Image;
use Friendica\Protocol\ActivityPub;
use Friendica\Core\Cache;
use Friendica\Util\Map; use Friendica\Util\Map;
use Friendica\Util\Network; use Friendica\Util\Network;
use Friendica\Util\XML;
require_once 'include/api.php'; require_once 'include/api.php';
require_once 'mod/share.php'; require_once 'mod/share.php';
@ -1049,7 +1051,7 @@ class Transmitter
// Grab all pictures without alternative descriptions and create attachments out of them // Grab all pictures without alternative descriptions and create attachments out of them
if (preg_match_all("/\[img\]([^\[\]]*)\[\/img\]/Usi", $body, $pictures)) { if (preg_match_all("/\[img\]([^\[\]]*)\[\/img\]/Usi", $body, $pictures)) {
foreach ($pictures[1] as $picture) { foreach ($pictures[1] as $picture) {
$imgdata = Image::getInfoFromURL($picture); $imgdata = Images::getInfoFromURLCached($picture);
if ($imgdata) { if ($imgdata) {
$attachments[] = ['type' => 'Document', $attachments[] = ['type' => 'Document',
'mediaType' => $imgdata['mime'], 'mediaType' => $imgdata['mime'],
@ -1062,7 +1064,7 @@ class Transmitter
// Grab all pictures with alternative description and create attachments out of them // Grab all pictures with alternative description and create attachments out of them
if (preg_match_all("/\[img=([^\[\]]*)\]([^\[\]]*)\[\/img\]/Usi", $body, $pictures, PREG_SET_ORDER)) { if (preg_match_all("/\[img=([^\[\]]*)\]([^\[\]]*)\[\/img\]/Usi", $body, $pictures, PREG_SET_ORDER)) {
foreach ($pictures as $picture) { foreach ($pictures as $picture) {
$imgdata = Image::getInfoFromURL($picture[1]); $imgdata = Images::getInfoFromURLCached($picture[1]);
if ($imgdata) { if ($imgdata) {
$attachments[] = ['type' => 'Document', $attachments[] = ['type' => 'Document',
'mediaType' => $imgdata['mime'], 'mediaType' => $imgdata['mime'],

View file

@ -35,6 +35,7 @@ use Friendica\Object\Image;
use Friendica\Protocol\ActivityNamespace; use Friendica\Protocol\ActivityNamespace;
use Friendica\Util\Crypto; use Friendica\Util\Crypto;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Images;
use Friendica\Util\Network; use Friendica\Util\Network;
use Friendica\Util\Strings; use Friendica\Util\Strings;
use Friendica\Util\XML; use Friendica\Util\XML;
@ -504,7 +505,7 @@ class DFRN
$uid $uid
); );
$photos = []; $photos = [];
$ext = Image::supportedTypes(); $ext = Images::supportedTypes();
foreach ($rp as $p) { foreach ($rp as $p) {
$photos[$p['scale']] = System::baseUrl().'/photo/'.$p['resource-id'].'-'.$p['scale'].'.'.$ext[$p['type']]; $photos[$p['scale']] = System::baseUrl().'/photo/'.$p['resource-id'].'-'.$p['scale'].'.'.$ext[$p['type']];

View file

@ -27,6 +27,7 @@ use Friendica\Network\Probe;
use Friendica\Object\Image; use Friendica\Object\Image;
use Friendica\Protocol\ActivityNamespace; use Friendica\Protocol\ActivityNamespace;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Images;
use Friendica\Util\Network; use Friendica\Util\Network;
use Friendica\Util\Proxy as ProxyUtils; use Friendica\Util\Proxy as ProxyUtils;
use Friendica\Util\Strings; use Friendica\Util\Strings;
@ -1389,7 +1390,7 @@ class OStatus
switch ($siteinfo["type"]) { switch ($siteinfo["type"]) {
case 'photo': case 'photo':
if (!empty($siteinfo["image"])) { if (!empty($siteinfo["image"])) {
$imgdata = Image::getInfoFromURL($siteinfo["image"]); $imgdata = Images::getInfoFromURLCached($siteinfo["image"]);
if ($imgdata) { if ($imgdata) {
$attributes = ["rel" => "enclosure", $attributes = ["rel" => "enclosure",
"href" => $siteinfo["image"], "href" => $siteinfo["image"],
@ -1413,7 +1414,7 @@ class OStatus
} }
if (!Config::get('system', 'ostatus_not_attach_preview') && ($siteinfo["type"] != "photo") && isset($siteinfo["image"])) { if (!Config::get('system', 'ostatus_not_attach_preview') && ($siteinfo["type"] != "photo") && isset($siteinfo["image"])) {
$imgdata = Image::getInfoFromURL($siteinfo["image"]); $imgdata = Images::getInfoFromURLCached($siteinfo["image"]);
if ($imgdata) { if ($imgdata) {
$attributes = ["rel" => "enclosure", $attributes = ["rel" => "enclosure",
"href" => $siteinfo["image"], "href" => $siteinfo["image"],

236
src/Util/Images.php Normal file
View file

@ -0,0 +1,236 @@
<?php
namespace Friendica\Util;
use Friendica\BaseObject;
use Friendica\Core\Cache;
use Friendica\Core\Logger;
use Friendica\Core\System;
use Imagick;
/**
* Image utilities
*/
class Images
{
/**
* Maps Mime types to Imagick formats
*
* @return array
*/
public static function getFormatsMap()
{
$m = [
'image/jpeg' => 'JPG',
'image/png' => 'PNG',
'image/gif' => 'GIF'
];
return $m;
}
/**
* Returns supported image mimetypes and corresponding file extensions
*
* @return array
*/
public static function supportedTypes()
{
$types = [
'image/jpeg' => 'jpg'
];
if (class_exists('Imagick')) {
// Imagick::queryFormats won't help us a lot there...
// At least, not yet, other parts of friendica uses this array
$types += [
'image/png' => 'png',
'image/gif' => 'gif'
];
} elseif (imagetypes() & IMG_PNG) {
$types += [
'image/png' => 'png'
];
}
return $types;
}
/**
* Guess image mimetype from filename or from Content-Type header
*
* @param string $filename Image filename
* @param boolean $fromcurl Check Content-Type header from curl request
* @param string $header passed headers to take into account
*
* @return string|null
* @throws \Exception
*/
public static function guessType($filename, $fromcurl = false, $header = '')
{
Logger::info('Image: guessType: ' . $filename . ($fromcurl ? ' from curl headers' : ''));
$type = null;
if ($fromcurl) {
$headers = [];
$h = explode("\n", $header);
foreach ($h as $l) {
$data = array_map("trim", explode(":", trim($l), 2));
if (count($data) > 1) {
list($k, $v) = $data;
$headers[$k] = $v;
}
}
if (array_key_exists('Content-Type', $headers)) {
$type = $headers['Content-Type'];
}
}
if (is_null($type)) {
// Guessing from extension? Isn't that... dangerous?
if (class_exists('Imagick') && file_exists($filename) && is_readable($filename)) {
/**
* Well, this not much better,
* but at least it comes from the data inside the image,
* we won't be tricked by a manipulated extension
*/
$image = new Imagick($filename);
$type = $image->getImageMimeType();
} else {
$ext = pathinfo($filename, PATHINFO_EXTENSION);
$types = self::supportedTypes();
$type = 'image/jpeg';
foreach ($types as $m => $e) {
if ($ext == $e) {
$type = $m;
}
}
}
}
Logger::info('Image: guessType: type=' . $type);
return $type;
}
/**
* @param string $url
* @return array
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
public static function getInfoFromURLCached($url)
{
$data = [];
if (empty($url)) {
return $data;
}
$data = Cache::get($url);
if (empty($data) || !is_array($data)) {
$data = self::getInfoFromURL($url);
Cache::set($url, $data);
}
return $data;
}
/**
* @param string $url
* @return array
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
public static function getInfoFromURL($url)
{
$data = [];
if (empty($url)) {
return $data;
}
$img_str = Network::fetchUrl($url, true, 4);
if (!$img_str) {
return [];
}
$filesize = strlen($img_str);
try {
if (function_exists("getimagesizefromstring")) {
$data = @getimagesizefromstring($img_str);
} else {
$tempfile = tempnam(get_temppath(), "cache");
$stamp1 = microtime(true);
file_put_contents($tempfile, $img_str);
BaseObject::getApp()->getProfiler()->saveTimestamp($stamp1, "file", System::callstack());
$data = getimagesize($tempfile);
unlink($tempfile);
}
} catch (\Exception $e) {
return [];
}
if ($data) {
$data['size'] = $filesize;
}
return $data;
}
/**
* @param integer $width
* @param integer $height
* @param integer $max
* @return array
*/
public static function getScalingDimensions($width, $height, $max)
{
if ((!$width) || (!$height)) {
return ['width' => 0, 'height' => 0];
}
if ($width > $max && $height > $max) {
// very tall image (greater than 16:9)
// constrain the width - let the height float.
if ((($height * 9) / 16) > $width) {
$dest_width = $max;
$dest_height = intval(($height * $max) / $width);
} elseif ($width > $height) {
// else constrain both dimensions
$dest_width = $max;
$dest_height = intval(($height * $max) / $width);
} else {
$dest_width = intval(($width * $max) / $height);
$dest_height = $max;
}
} else {
if ($width > $max) {
$dest_width = $max;
$dest_height = intval(($height * $max) / $width);
} else {
if ($height > $max) {
// very tall image (greater than 16:9)
// but width is OK - don't do anything
if ((($height * 9) / 16) > $width) {
$dest_width = $width;
$dest_height = $height;
} else {
$dest_width = intval(($width * $max) / $height);
$dest_height = $max;
}
} else {
$dest_width = $width;
$dest_height = $height;
}
}
}
return ['width' => $dest_width, 'height' => $dest_height];
}
}

View file

@ -11,7 +11,6 @@ use Friendica\Content\OEmbed;
use Friendica\Core\Hook; use Friendica\Core\Hook;
use Friendica\Core\Logger; use Friendica\Core\Logger;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\Object\Image;
/** /**
* @brief Class with methods for extracting certain content from an url * @brief Class with methods for extracting certain content from an url
@ -348,7 +347,7 @@ class ParseUrl
} }
$src = self::completeUrl($img_tag['src'], $url); $src = self::completeUrl($img_tag['src'], $url);
$photodata = Image::getInfoFromURL($src); $photodata = Images::getInfoFromURLCached($src);
if (($photodata) && ($photodata[0] > 150) && ($photodata[1] > 150)) { if (($photodata) && ($photodata[0] > 150) && ($photodata[1] > 150)) {
if ($photodata[0] > 300) { if ($photodata[0] > 300) {
@ -371,7 +370,7 @@ class ParseUrl
unset($siteinfo['image']); unset($siteinfo['image']);
$photodata = Image::getInfoFromURL($src); $photodata = Images::getInfoFromURLCached($src);
if (($photodata) && ($photodata[0] > 10) && ($photodata[1] > 10)) { if (($photodata) && ($photodata[0] > 10) && ($photodata[1] > 10)) {
$siteinfo['images'][] = ['src' => $src, $siteinfo['images'][] = ['src' => $src,