Files
pictshare/content-controllers/image/image.controller.php
2018-12-27 09:21:12 +01:00

227 lines
7.8 KiB
PHP

<?php
/**
* @Todo:
* - Resizing
* - Filters
* - Conversion gif to mp4
* - Conversion jpg,png to webp
*/
class ImageController implements ContentController
{
//returns all extensions registered by this type of content
public function getRegisteredExtensions(){return array('png','bmp','gif','jpg','jpeg','x-png','webp');}
public function handleUpload($tmpfile,$hash=false)
{
$type = exif_imagetype($tmpfile); //http://www.php.net/manual/en/function.exif-imagetype.php
switch($type)
{
case 1: $ext = 'gif';break; //gif
case 3: $ext = 'png';break; // png
case 6: $ext = 'bmp';break; // bmp
case 17: $ext = 'ico';break; // ico
case 18: $ext = 'webp';break; // webp
case 2: //we clean up exif data of JPGs so GPS and other data is removed
$res = imagecreatefromjpeg($tmpfile);
imagejpeg($res, $tmpfile, (defined('JPEG_COMPRESSION')?JPEG_COMPRESSION:90));
$ext = 'jpg';
break;
default:
return array('status'=>'err','reason'=>'Not a valid image');
}
if($hash===false)
{
$hash = getNewHash($ext,6);
}
else
{
if(!endswith($hash,'.'.$ext))
$hash.='.'.$ext;
if(isExistingHash($hash))
return array('status'=>'err','hash'=>$hash,'reason'=>'Custom hash already exists');
}
storeFile($tmpfile,$hash,true);
return array('status'=>'ok','hash'=>$hash,'url'=>URL.$hash);
}
public function handleHash($hash,$url)
{
$path = ROOT.DS.'data'.DS.$hash.DS.$hash;
$type = getExtensionOfFilename($hash);
//get all our sub files where all the good functions lie
include_once(dirname(__FILE__).DS.'resize.php');
include_once(dirname(__FILE__).DS.'filters.php');
include_once(dirname(__FILE__).DS.'conversion.php');
//don't do this if it's a gif because PHP can't handle animated gifs
if($type!='gif')
{
foreach($url as $u)
{
if(isSize($u))
$modifiers['size'] = $u;
else if(isRotation($u))
$modifiers['rotation'] = $u;
}
if(in_array('webp',$url) && $type!='webp')
$modifiers['webp'] = true;
if(in_array('forcesize',$url) && $modifiers['size'])
$modifiers['forcesize'] = true;
}
else //gif
{
if(in_array('mp4',$url))
$modifiers['mp4']=true;
}
if($modifiers)
{
//why in gods name would you use http build query here???
//well we want a unique filename for every modied image
//so if we take all parameters in key=>value form and hash it
//we get one nice little hash for every eventuality
$modhash = md5(http_build_query($modifiers,'',','));
$newpath = ROOT.DS.'data'.DS.$hash.DS.$modhash.'_'.$hash;
$im = $this->getObjOfImage($path);
if(!file_exists($newpath))
{
foreach($modifiers as $mod => $val)
{
switch($mod)
{
case 'size':
($modifiers['forcesize']?forceResize($im,$val):resize($im,$val));
break;
case 'rotation':
rotate($im,$val);
break;
case 'webp':
$type = 'webp';
break;
case 'mp4':
$mp4path = ROOT.DS.'data'.DS.$hash.DS.$hash.'mp4';
if(!file_exists($mp4path))
$this->gifToMP4($path,$mp4path);
$path = $mp4path;
if(in_array('raw',$url))
(new VideoController())->serveMP4($path,$hash);
else if(in_array('preview',$url))
{
$preview = $path.'_preview.jpg';
if(!file_exists($preview))
{
(new VideoController())->saveFirstFrameOfMP4($path,$preview);
}
header ("Content-type: image/jpeg");
readfile($preview);
}
else if(in_array('download',$url))
{
if (file_exists($path)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($path).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($path));
readfile($path);
exit;
}
}
else
{
$data = array('url'=>implode('/',$url),'hash'=>$hash,'filesize'=>renderSize(filesize($path)));
renderTemplate('video',$data);
}
break;
}
}
$this->saveObjOfImage($im,$newpath,$type);
}
$path = $newpath;
}
switch($type)
{
case 'jpeg':
case 'jpg':
header ("Content-type: image/jpeg");
readfile($path);
break;
case 'png':
header ("Content-type: image/png");
readfile($path);
break;
case 'gif':
header ("Content-type: image/gif");
readfile($path);
break;
case 'webp':
header ("Content-type: image/webp");
readfile($path);
break;
}
}
function getObjOfImage($path)
{
return imagecreatefromstring(file_get_contents($path));
}
function gifToMP4($gifpath,$target)
{
$bin = escapeshellcmd(FFMPEG_BINARY);
$file = escapeshellarg($gifpath);
if(!file_exists($target)) //simple caching.. have to think of something better
{
$cmd = "$bin -f gif -y -i $file -vcodec libx264 -an -profile:v baseline -level 3.0 -pix_fmt yuv420p -vf \"scale=trunc(iw/2)*2:trunc(ih/2)*2\" -f mp4 $target";
system($cmd);
}
return $target;
}
function saveObjOfImage($im,$path,$type)
{
switch($type)
{
case 'jpeg':
case 'jpg':
imagejpeg($im,$path,(defined('JPEG_COMPRESSION')?JPEG_COMPRESSION:90));
break;
case 'png':
imagepng($im,$path,(defined('PNG_COMPRESSION')?PNG_COMPRESSION:6));
break;
case 'webp':
imagewebp($im,$path,(defined('WEBP_COMPRESSION')?WEBP_COMPRESSION:80));
break;
}
return $im;
}
}