mirror of
https://github.com/friendica/friendica
synced 2025-04-22 07:50:11 +00:00
Image handling reworked, new image formats added (#13900)
* Image handling reworked, new image formats added * Updated messages.po * The dot is now part of the file extension * Added WebP in install documentation * Handle unhandled mime types * Fixed animated picture detected
This commit is contained in:
parent
1ea8a4042d
commit
14e5b06029
31 changed files with 541 additions and 386 deletions
|
@ -95,7 +95,7 @@ class Instance extends BaseApi
|
|||
|
||||
return new InstanceV2Entity\Configuration(
|
||||
$statuses_config,
|
||||
new InstanceV2Entity\MediaAttachmentsConfig(array_keys(Images::supportedTypes()), $image_size_limit, $image_matrix_limit),
|
||||
new InstanceV2Entity\MediaAttachmentsConfig(Images::supportedMimeTypes(), $image_size_limit, $image_matrix_limit),
|
||||
new InstanceV2Entity\Polls(),
|
||||
new InstanceV2Entity\Accounts(),
|
||||
);
|
||||
|
|
|
@ -131,7 +131,7 @@ class InstanceV2 extends BaseApi
|
|||
|
||||
return new InstanceEntity\Configuration(
|
||||
$statuses_config,
|
||||
new InstanceEntity\MediaAttachmentsConfig(array_keys(Images::supportedTypes()), $image_size_limit, $image_matrix_limit),
|
||||
new InstanceEntity\MediaAttachmentsConfig(Images::supportedMimeTypes(), $image_size_limit, $image_matrix_limit),
|
||||
new InstanceEntity\Polls(),
|
||||
new InstanceEntity\Accounts(),
|
||||
);
|
||||
|
|
|
@ -403,11 +403,10 @@ class Statuses extends BaseApi
|
|||
|
||||
Photo::setPermissionForResource($media[0]['resource-id'], $item['uid'], $item['allow_cid'], $item['allow_gid'], $item['deny_cid'], $item['deny_gid']);
|
||||
|
||||
$phototypes = Images::supportedTypes();
|
||||
$ext = $phototypes[$media[0]['type']];
|
||||
$ext = Images::getExtensionByMimeType($media[0]['type']);
|
||||
|
||||
$attachment = ['type' => Post\Media::IMAGE, 'mimetype' => $media[0]['type'],
|
||||
'url' => DI::baseUrl() . '/photo/' . $media[0]['resource-id'] . '-' . $media[0]['scale'] . '.' . $ext,
|
||||
'url' => DI::baseUrl() . '/photo/' . $media[0]['resource-id'] . '-' . $media[0]['scale'] . $ext,
|
||||
'size' => $media[0]['datasize'],
|
||||
'name' => $media[0]['filename'] ?: $media[0]['resource-id'],
|
||||
'description' => $media[0]['desc'] ?? '',
|
||||
|
@ -415,7 +414,7 @@ class Statuses extends BaseApi
|
|||
'height' => $media[0]['height']];
|
||||
|
||||
if (count($media) > 1) {
|
||||
$attachment['preview'] = DI::baseUrl() . '/photo/' . $media[1]['resource-id'] . '-' . $media[1]['scale'] . '.' . $ext;
|
||||
$attachment['preview'] = DI::baseUrl() . '/photo/' . $media[1]['resource-id'] . '-' . $media[1]['scale'] . $ext;
|
||||
$attachment['preview-width'] = $media[1]['width'];
|
||||
$attachment['preview-height'] = $media[1]['height'];
|
||||
}
|
||||
|
|
|
@ -155,13 +155,12 @@ class Update extends BaseApi
|
|||
|
||||
Photo::setPermissionForResource($media[0]['resource-id'], $uid, $item['allow_cid'], $item['allow_gid'], $item['deny_cid'], $item['deny_gid']);
|
||||
|
||||
$phototypes = Images::supportedTypes();
|
||||
$ext = $phototypes[$media[0]['type']];
|
||||
$ext = Images::getExtensionByMimeType($media[0]['type']);
|
||||
|
||||
$attachment = [
|
||||
'type' => Post\Media::IMAGE,
|
||||
'mimetype' => $media[0]['type'],
|
||||
'url' => DI::baseUrl() . '/photo/' . $media[0]['resource-id'] . '-' . $media[0]['scale'] . '.' . $ext,
|
||||
'url' => DI::baseUrl() . '/photo/' . $media[0]['resource-id'] . '-' . $media[0]['scale'] . $ext,
|
||||
'size' => $media[0]['datasize'],
|
||||
'name' => $media[0]['filename'] ?: $media[0]['resource-id'],
|
||||
'description' => $media[0]['desc'] ?? '',
|
||||
|
@ -170,7 +169,7 @@ class Update extends BaseApi
|
|||
];
|
||||
|
||||
if (count($media) > 1) {
|
||||
$attachment['preview'] = DI::baseUrl() . '/photo/' . $media[1]['resource-id'] . '-' . $media[1]['scale'] . '.' . $ext;
|
||||
$attachment['preview'] = DI::baseUrl() . '/photo/' . $media[1]['resource-id'] . '-' . $media[1]['scale'] . $ext;
|
||||
$attachment['preview-width'] = $media[1]['width'];
|
||||
$attachment['preview-height'] = $media[1]['height'];
|
||||
}
|
||||
|
|
|
@ -99,8 +99,7 @@ class Browser extends BaseModule
|
|||
|
||||
protected function map_files(array $record): array
|
||||
{
|
||||
$types = Images::supportedTypes();
|
||||
$ext = $types[$record['type']];
|
||||
$ext = Images::getExtensionByMimeType($record['type']);
|
||||
$filename_e = $record['filename'];
|
||||
|
||||
// Take the largest picture that is smaller or equal 640 pixels
|
||||
|
@ -118,7 +117,7 @@ class Browser extends BaseModule
|
|||
return [
|
||||
sprintf('%s/photos/%s/image/%s', $this->baseUrl, $this->app->getLoggedInUserNickname(), $record['resource-id']),
|
||||
$filename_e,
|
||||
sprintf('%s/photo/%s-%s.%s', $this->baseUrl, $record['resource-id'], $scale, $ext),
|
||||
sprintf('%s/photo/%s-%s%s', $this->baseUrl, $record['resource-id'], $scale, $ext),
|
||||
$record['desc'],
|
||||
];
|
||||
}
|
||||
|
|
|
@ -135,8 +135,6 @@ class Upload extends \Friendica\BaseModule
|
|||
$this->return(401, $this->t('Invalid request.'), true);
|
||||
}
|
||||
|
||||
$filetype = Images::getMimeTypeBySource($src, $filename, $filetype);
|
||||
|
||||
$this->logger->info('File upload:', [
|
||||
'src' => $src,
|
||||
'filename' => $filename,
|
||||
|
@ -145,7 +143,7 @@ class Upload extends \Friendica\BaseModule
|
|||
]);
|
||||
|
||||
$imagedata = @file_get_contents($src);
|
||||
$image = new Image($imagedata, $filetype);
|
||||
$image = new Image($imagedata, $filetype, $filename);
|
||||
|
||||
if (!$image->isValid()) {
|
||||
@unlink($src);
|
||||
|
|
|
@ -167,14 +167,16 @@ class Photo extends BaseApi
|
|||
$stamp = microtime(true);
|
||||
|
||||
if (empty($request['blur']) || empty($photo['blurhash'])) {
|
||||
$imgdata = MPhoto::getImageDataForPhoto($photo);
|
||||
$imgdata = MPhoto::getImageDataForPhoto($photo);
|
||||
$mimetype = $photo['type'];
|
||||
}
|
||||
if (empty($imgdata) && empty($photo['blurhash'])) {
|
||||
throw new HTTPException\NotFoundException();
|
||||
} elseif (empty($imgdata) && !empty($photo['blurhash'])) {
|
||||
$image = New Image('', 'image/png');
|
||||
$image = New Image('', image_type_to_mime_type(IMAGETYPE_WEBP));
|
||||
$image->getFromBlurHash($photo['blurhash'], $photo['width'], $photo['height']);
|
||||
$imgdata = $image->asString();
|
||||
$imgdata = $image->asString();
|
||||
$mimetype = $image->getType();
|
||||
}
|
||||
|
||||
// The mimetype for an external or system resource can only be known reliably after it had been fetched
|
||||
|
@ -199,20 +201,23 @@ class Photo extends BaseApi
|
|||
}
|
||||
|
||||
if (!empty($request['static'])) {
|
||||
$img = new Image($imgdata, $photo['type']);
|
||||
$img = new Image($imgdata, $photo['type'], $photo['filename']);
|
||||
$img->toStatic();
|
||||
$imgdata = $img->asString();
|
||||
$imgdata = $img->asString();
|
||||
$mimetype = $img->getType();
|
||||
}
|
||||
|
||||
// if customsize is set and image is not a gif, resize it
|
||||
if ($photo['type'] !== 'image/gif' && $customsize > 0 && $customsize <= Proxy::PIXEL_THUMB && $square_resize) {
|
||||
$img = new Image($imgdata, $photo['type']);
|
||||
if ($photo['type'] !== image_type_to_mime_type(IMAGETYPE_GIF) && $customsize > 0 && $customsize <= Proxy::PIXEL_THUMB && $square_resize) {
|
||||
$img = new Image($imgdata, $photo['type'], $photo['filename']);
|
||||
$img->scaleToSquare($customsize);
|
||||
$imgdata = $img->asString();
|
||||
} elseif ($photo['type'] !== 'image/gif' && $customsize > 0) {
|
||||
$img = new Image($imgdata, $photo['type']);
|
||||
$imgdata = $img->asString();
|
||||
$mimetype = $img->getType();
|
||||
} elseif ($photo['type'] !== image_type_to_mime_type(IMAGETYPE_GIF) && $customsize > 0) {
|
||||
$img = new Image($imgdata, $photo['type'], $photo['filename']);
|
||||
$img->scaleDown($customsize);
|
||||
$imgdata = $img->asString();
|
||||
$imgdata = $img->asString();
|
||||
$mimetype = $img->getType();
|
||||
}
|
||||
|
||||
if (function_exists('header_remove')) {
|
||||
|
@ -220,7 +225,7 @@ class Photo extends BaseApi
|
|||
header_remove('pragma');
|
||||
}
|
||||
|
||||
header('Content-type: ' . $photo['type']);
|
||||
header('Content-type: ' . $mimetype);
|
||||
|
||||
$stamp = microtime(true);
|
||||
if (!$cacheable) {
|
||||
|
@ -391,7 +396,7 @@ class Photo extends BaseApi
|
|||
}
|
||||
}
|
||||
if (empty($mimetext) && !empty($contact['blurhash'])) {
|
||||
$image = New Image('', 'image/png');
|
||||
$image = New Image('', image_type_to_mime_type(IMAGETYPE_WEBP));
|
||||
$image->getFromBlurHash($contact['blurhash'], $customsize, $customsize);
|
||||
return MPhoto::createPhotoForImageData($image->asString());
|
||||
} elseif (empty($mimetext)) {
|
||||
|
|
|
@ -184,8 +184,6 @@ class Photos extends \Friendica\Module\BaseProfile
|
|||
return;
|
||||
}
|
||||
|
||||
$type = Images::getMimeTypeBySource($src, $filename, $type);
|
||||
|
||||
$this->logger->info('photos: upload: received file: ' . $filename . ' as ' . $src . ' ('. $type . ') ' . $filesize . ' bytes');
|
||||
|
||||
$maximagesize = Strings::getBytesFromShorthand($this->config->get('system', 'maximagesize'));
|
||||
|
@ -210,7 +208,7 @@ class Photos extends \Friendica\Module\BaseProfile
|
|||
|
||||
$imagedata = @file_get_contents($src);
|
||||
|
||||
$image = new Image($imagedata, $type);
|
||||
$image = new Image($imagedata, $type, $filename);
|
||||
|
||||
if (!$image->isValid()) {
|
||||
$this->logger->notice('unable to process image');
|
||||
|
@ -341,14 +339,12 @@ class Photos extends \Friendica\Module\BaseProfile
|
|||
$pager->getItemsPerPage()
|
||||
));
|
||||
|
||||
$phototypes = Images::supportedTypes();
|
||||
|
||||
$photos = array_map(function ($photo) use ($phototypes) {
|
||||
$photos = array_map(function ($photo){
|
||||
return [
|
||||
'id' => $photo['id'],
|
||||
'link' => 'photos/' . $this->owner['nickname'] . '/image/' . $photo['resource-id'],
|
||||
'title' => $this->t('View Photo'),
|
||||
'src' => 'photo/' . $photo['resource-id'] . '-' . ((($photo['scale']) == 6) ? 4 : $photo['scale']) . '.' . $phototypes[$photo['type']],
|
||||
'src' => 'photo/' . $photo['resource-id'] . '-' . ((($photo['scale']) == 6) ? 4 : $photo['scale']) . Images::getExtensionByMimeType($photo['type']),
|
||||
'alt' => $photo['filename'],
|
||||
'album' => [
|
||||
'link' => 'photos/' . $this->owner['nickname'] . '/album/' . bin2hex($photo['album']),
|
||||
|
|
|
@ -99,17 +99,15 @@ class Proxy extends BaseModule
|
|||
|
||||
Logger::debug('Got picture', ['Content-Type' => $fetchResult->getHeader('Content-Type'), 'uid' => DI::userSession()->getLocalUserId(), 'image' => $request['url']]);
|
||||
|
||||
$mime = Images::getMimeTypeByData($img_str);
|
||||
|
||||
$image = new Image($img_str, $mime);
|
||||
$image = new Image($img_str, $fetchResult->getContentType(), $request['url']);
|
||||
if (!$image->isValid()) {
|
||||
Logger::notice('The image is invalid', ['image' => $request['url'], 'mime' => $mime]);
|
||||
Logger::notice('The image is invalid', ['image' => $request['url'], 'mime' => $fetchResult->getContentType()]);
|
||||
self::responseError();
|
||||
// stop.
|
||||
}
|
||||
|
||||
// reduce quality - if it isn't a GIF
|
||||
if ($image->getType() != 'image/gif') {
|
||||
if ($image->getImageType() != IMAGETYPE_GIF) {
|
||||
$image->scaleDown($request['size']);
|
||||
}
|
||||
|
||||
|
|
|
@ -213,7 +213,7 @@ class Crop extends BaseSettings
|
|||
|
||||
DI::page()['htmlhead'] .= Renderer::replaceMacros(Renderer::getMarkupTemplate('settings/profile/photo/crop_head.tpl'), []);
|
||||
|
||||
$filename = $imagecrop['resource-id'] . '-' . $imagecrop['scale'] . '.' . $imagecrop['ext'];
|
||||
$filename = $imagecrop['resource-id'] . '-' . $imagecrop['scale'] . $imagecrop['ext'];
|
||||
$tpl = Renderer::getMarkupTemplate('settings/profile/photo/crop.tpl');
|
||||
$o = Renderer::replaceMacros($tpl, [
|
||||
'$filename' => $filename,
|
||||
|
|
|
@ -52,8 +52,6 @@ class Index extends BaseSettings
|
|||
$filesize = intval($_FILES['userfile']['size']);
|
||||
$filetype = $_FILES['userfile']['type'];
|
||||
|
||||
$filetype = Images::getMimeTypeBySource($src, $filename, $filetype);
|
||||
|
||||
$maximagesize = Strings::getBytesFromShorthand(DI::config()->get('system', 'maximagesize', 0));
|
||||
|
||||
if ($maximagesize && $filesize > $maximagesize) {
|
||||
|
@ -63,7 +61,7 @@ class Index extends BaseSettings
|
|||
}
|
||||
|
||||
$imagedata = @file_get_contents($src);
|
||||
$Image = new Image($imagedata, $filetype);
|
||||
$Image = new Image($imagedata, $filetype, $filename);
|
||||
|
||||
if (!$Image->isValid()) {
|
||||
DI::sysmsg()->addNotice(DI::l10n()->t('Unable to process image.'));
|
||||
|
|
|
@ -392,7 +392,7 @@ class Import extends \Friendica\BaseModule
|
|||
$photo['data'] = hex2bin($photo['data']);
|
||||
|
||||
$r = Photo::store(
|
||||
new Image($photo['data'], $photo['type']),
|
||||
new Image($photo['data'], $photo['type'], $photo['filename']),
|
||||
$photo['uid'], $photo['contact-id'], //0
|
||||
$photo['resource-id'], $photo['filename'], $photo['album'], $photo['scale'], $photo['profile'], //1
|
||||
$photo['allow_cid'], $photo['allow_gid'], $photo['deny_cid'], $photo['deny_gid']
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue