mirror of
https://github.com/HaschekSolutions/pictshare.git
synced 2025-11-17 13:38:01 +00:00
big update including Filters and smarter algorithms
This commit is contained in:
22
README.md
Executable file → Normal file
22
README.md
Executable file → Normal file
@@ -4,6 +4,10 @@ PictShare is an multi lingual, open source image hosting service with a simple r
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
The filter update is out!
|
||||||
|
========
|
||||||
|
[Check it out](#filters)
|
||||||
|
|
||||||
## Why would I want to host my own images?
|
## Why would I want to host my own images?
|
||||||
If you own a server (even an home server) you can host your own PictShare instance so you have full control over your content and can delete images hasslefree.
|
If you own a server (even an home server) you can host your own PictShare instance so you have full control over your content and can delete images hasslefree.
|
||||||
|
|
||||||
@@ -30,6 +34,24 @@ Just by editing the URL and adding the size (in width**x**height) the image gets
|
|||||||
|
|
||||||
You can limit the number of resizes per image in the ```index.php``` file
|
You can limit the number of resizes per image in the ```index.php``` file
|
||||||
|
|
||||||
|
## Filters
|
||||||
|
PictShare also supports multiple filters (at once) that you can apply just by changing the URL.
|
||||||
|
Filters that need values are set like this: ```filtername_value```. Eg: ```pixelate_10```
|
||||||
|
|
||||||
|
Original URL: ```https://www.pictshare.net/b260e36b60.jpg```
|
||||||
|
|
||||||
|
| Filter | Paramter | Example URL | Result |
|
||||||
|
| ---------------------------------------------------------------------- |
|
||||||
|
| negative | -none- | https://pictshare.net/negative/b260e36b60.jpg |  |
|
||||||
|
| grayscale | -none- | https://pictshare.net/negative/b260e36b60.jpg |  |
|
||||||
|
| brightness | -255 to 255 | https://pictshare.net/brightness_100/b260e36b60.jpg |  |
|
||||||
|
| edgedetect | -none- | https://pictshare.net/edgedetect/b260e36b60.jpg |  |
|
||||||
|
| smooth | -10 to 2048 | https://pictshare.net/smooth_3/b260e36b60.jpg |  |
|
||||||
|
| contrast | -100 to 100 | https://pictshare.net/contrast_-90/b260e36b60.jpg |  |
|
||||||
|
| pixelate | -100 to 100 | https://pictshare.net/pixelate_10/b260e36b60.jpg |  |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## How does the external-upload-API work?
|
## How does the external-upload-API work?
|
||||||
|
|
||||||
### From URL
|
### From URL
|
||||||
|
|||||||
@@ -734,6 +734,16 @@ class easyphpthumbnail {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getIm()
|
||||||
|
{
|
||||||
|
return $this->im;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getThumb()
|
||||||
|
{
|
||||||
|
return $this->thumb;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class destructor
|
* Class destructor
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -60,4 +60,93 @@ class Image
|
|||||||
|
|
||||||
return '/'.$filename;
|
return '/'.$filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function rotate(&$im,$direction)
|
||||||
|
{
|
||||||
|
switch($direction)
|
||||||
|
{
|
||||||
|
case 'upside': $angle = 180;break;
|
||||||
|
case 'left': $angle = 90;break;
|
||||||
|
case 'right': $angle = -90;break;
|
||||||
|
default: $angle = 0;break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$im = imagerotate($im,$angle,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* From: https://stackoverflow.com/questions/4590441/php-thumbnail-image-resizing-with-proportions
|
||||||
|
*/
|
||||||
|
function resize(&$img,$size)
|
||||||
|
{
|
||||||
|
if(!is_numeric($size))
|
||||||
|
$size = explode('x',$size);
|
||||||
|
|
||||||
|
if(is_array($size))
|
||||||
|
{
|
||||||
|
$maxwidth = $size[0];
|
||||||
|
$maxheight = $size[1];
|
||||||
|
}
|
||||||
|
else if($size)
|
||||||
|
{
|
||||||
|
$maxwidth = $size;
|
||||||
|
$maxheight = $size;
|
||||||
|
}
|
||||||
|
|
||||||
|
$width = imagesx($img);
|
||||||
|
$height = imagesy($img);
|
||||||
|
|
||||||
|
if($maxwidth>$width)$maxwidth = $width;
|
||||||
|
if($maxheight>$height)$maxheight = $height;
|
||||||
|
|
||||||
|
if ($height > $width)
|
||||||
|
{
|
||||||
|
$ratio = $maxheight / $height;
|
||||||
|
$newheight = $maxheight;
|
||||||
|
$newwidth = $width * $ratio;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$ratio = $maxwidth / $width;
|
||||||
|
$newwidth = $maxwidth;
|
||||||
|
$newheight = $height * $ratio;
|
||||||
|
}
|
||||||
|
|
||||||
|
$newimg = imagecreatetruecolor($newwidth,$newheight);
|
||||||
|
|
||||||
|
$palsize = ImageColorsTotal($img);
|
||||||
|
for ($i = 0; $i < $palsize; $i++)
|
||||||
|
{
|
||||||
|
$colors = ImageColorsForIndex($img, $i);
|
||||||
|
ImageColorAllocate($newimg, $colors['red'], $colors['green'], $colors['blue']);
|
||||||
|
}
|
||||||
|
|
||||||
|
imagecopyresized($newimg, $img, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
|
||||||
|
|
||||||
|
$img = $newimg;
|
||||||
|
}
|
||||||
|
|
||||||
|
function filter(&$im,$vars)
|
||||||
|
{
|
||||||
|
|
||||||
|
foreach($vars as $var)
|
||||||
|
{
|
||||||
|
if(strpos($var,'_'))
|
||||||
|
{
|
||||||
|
$a = explode('_',$var);
|
||||||
|
$var = $a[0];
|
||||||
|
$val = $a[1];
|
||||||
|
}
|
||||||
|
switch($var)
|
||||||
|
{
|
||||||
|
case 'negative': imagefilter($im,IMG_FILTER_NEGATE); break;
|
||||||
|
case 'grayscale': imagefilter($im,IMG_FILTER_GRAYSCALE); break;
|
||||||
|
case 'brightness': imagefilter($im,IMG_FILTER_BRIGHTNESS,$val); break;
|
||||||
|
case 'edgedetect': imagefilter($im,IMG_FILTER_EDGEDETECT); break;
|
||||||
|
case 'smooth': imagefilter($im,IMG_FILTER_SMOOTH,$val); break;
|
||||||
|
case 'contrast': imagefilter($im,IMG_FILTER_CONTRAST,$val); break;
|
||||||
|
case 'pixelate': imagefilter($im,IMG_FILTER_PIXELATE,$val); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
189
inc/core.php
189
inc/core.php
@@ -41,6 +41,11 @@ function aasort (&$array, $key)
|
|||||||
$array=$ret;
|
$array=$ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sanatizeString($string)
|
||||||
|
{
|
||||||
|
return preg_replace("/[^a-zA-Z0-9._]+/", "", $string);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function callHook()
|
function callHook()
|
||||||
{
|
{
|
||||||
@@ -48,34 +53,98 @@ function callHook()
|
|||||||
global $default;
|
global $default;
|
||||||
$urlArray = explode("/",$url);
|
$urlArray = explode("/",$url);
|
||||||
|
|
||||||
|
whatToDo($urlArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
function whatToDo($url)
|
||||||
|
{
|
||||||
$pm = new PictshareModel();
|
$pm = new PictshareModel();
|
||||||
|
|
||||||
$u1 = preg_replace("/[^a-zA-Z0-9._]+/", "", $urlArray[0]);
|
foreach($url as $el)
|
||||||
$u2 = preg_replace("/[^a-zA-Z0-9._]+/", "", $urlArray[1]);
|
{
|
||||||
|
$el = sanatizeString($el);
|
||||||
|
$el = strtolower($el);
|
||||||
|
if(!$el) continue;
|
||||||
|
|
||||||
if(isImage($u1)) // render the image
|
if(isImage($el))
|
||||||
renderImage($u1);
|
$data['hash']=$el;
|
||||||
else if($u1=='store' || $u1=='originals') //render also with legacy urls
|
else if(isSize($el))
|
||||||
renderImage($u2);
|
$data['size'] = $el;
|
||||||
else if(isResizedImage($u1,$u2)) // resize and render
|
else if(isRotation($el))
|
||||||
renderResizedImage($u1,$u2);
|
$data['rotate'] = $el;
|
||||||
else if($u1=='thumbs')
|
else if(isFilter($el))
|
||||||
renderLegacyResized($u2);
|
$data['filter'][] = $el;
|
||||||
else if(!$u1)
|
else if($legacy = isLegacyThumbnail($el)) //so old uploads will still work
|
||||||
|
{
|
||||||
|
$data['hash'] = $legacy['hash'];
|
||||||
|
$data['size'] = $legacy['size'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!is_array($data) || !$data['hash'])
|
||||||
{
|
{
|
||||||
if($_POST['submit']==$pm->translate(3))
|
if($_POST['submit']==$pm->translate(3))
|
||||||
$o=$pm->ProcessUploads();
|
$o=$pm->ProcessUploads();
|
||||||
else
|
else
|
||||||
$o.= $pm->renderUploadForm();
|
$o.= $pm->renderUploadForm();
|
||||||
|
|
||||||
|
$vars['content'] = $o;
|
||||||
|
$vars['slogan'] = $pm->translate(2);
|
||||||
|
|
||||||
|
render($vars);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
header("HTTP/1.0 404 Not Found");
|
renderImage($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isLegacyThumbnail($val)
|
||||||
|
{
|
||||||
|
if(strpos($val,'_'))
|
||||||
|
{
|
||||||
|
$a = explode('_',$val);
|
||||||
|
$size = $a[0];
|
||||||
|
$hash = $a[1];
|
||||||
|
if(!isSize($size) || !isImage($hash)) return false;
|
||||||
|
|
||||||
$vars['content'] = $o;
|
return array('hash'=>$hash,'size'=>$size);
|
||||||
$vars['slogan'] = $pm->translate(2);
|
}
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
|
||||||
render($vars);
|
function isFilter($var)
|
||||||
|
{
|
||||||
|
if(strpos($var,'_'))
|
||||||
|
{
|
||||||
|
$a = explode('_',$var);
|
||||||
|
$var = $a[0];
|
||||||
|
$val = $a[1];
|
||||||
|
if(!is_numeric($val)) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($var)
|
||||||
|
{
|
||||||
|
case 'negative':
|
||||||
|
case 'grayscale':
|
||||||
|
case 'brightness':
|
||||||
|
case 'edgedetect':
|
||||||
|
case 'smooth':
|
||||||
|
case 'contrast':
|
||||||
|
case 'pixelate': return true;
|
||||||
|
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isRotation($var)
|
||||||
|
{
|
||||||
|
switch($var)
|
||||||
|
{
|
||||||
|
case 'upside':
|
||||||
|
case 'left':
|
||||||
|
case 'right': return true;
|
||||||
|
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderLegacyResized($path)
|
function renderLegacyResized($path)
|
||||||
@@ -95,15 +164,24 @@ function renderLegacyResized($path)
|
|||||||
renderResizedImage($size,$hash);
|
renderResizedImage($size,$hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderImage($hash,$file=false)
|
function renderImage($data)
|
||||||
{
|
{
|
||||||
|
$hash = $data['hash'];
|
||||||
$pm = new PictshareModel();
|
$pm = new PictshareModel();
|
||||||
if(!$file) $file = DS.$hash;
|
$base_path = ROOT.DS.'upload'.DS.$hash.DS;
|
||||||
$path = ROOT.DS.'upload'.DS.$hash.$file;
|
$path = $base_path.$hash;
|
||||||
$type = $pm->isTypeAllowed($pm->getTypeOfFile($path));
|
$type = $pm->isTypeAllowed($pm->getTypeOfFile($path));
|
||||||
|
$cached = false;
|
||||||
|
|
||||||
if($pm->countResizedImages($hash)>MAX_RESIZED_IMAGES) //if the number of max resized images is reached, just show the real one
|
$cachename = getCacheName($data);
|
||||||
|
$cachepath = $base_path.$cachename;
|
||||||
|
if(file_exists($cachepath))
|
||||||
|
{
|
||||||
|
$path = $cachepath;
|
||||||
|
$cached = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($pm->countResizedImages($hash)>=MAX_RESIZED_IMAGES) //if the number of max resized images is reached, just show the real one
|
||||||
$path = ROOT.DS.'upload'.DS.$hash.DS.$hash;
|
$path = ROOT.DS.'upload'.DS.$hash.DS.$hash;
|
||||||
|
|
||||||
switch($type)
|
switch($type)
|
||||||
@@ -111,16 +189,31 @@ function renderImage($hash,$file=false)
|
|||||||
case 'jpg':
|
case 'jpg':
|
||||||
header ("Content-type: image/jpeg");
|
header ("Content-type: image/jpeg");
|
||||||
$im = imagecreatefromjpeg($path);
|
$im = imagecreatefromjpeg($path);
|
||||||
|
if(!$cached)
|
||||||
|
{
|
||||||
|
changeImage($im,$data);
|
||||||
|
imagejpeg($im,$cachepath,95);
|
||||||
|
}
|
||||||
imagejpeg($im);
|
imagejpeg($im);
|
||||||
break;
|
break;
|
||||||
case 'png':
|
case 'png':
|
||||||
header ("Content-type: image/png");
|
header ("Content-type: image/png");
|
||||||
$im = imagecreatefrompng($path);
|
$im = imagecreatefrompng($path);
|
||||||
|
if(!$cached)
|
||||||
|
{
|
||||||
|
changeImage($im,$data);
|
||||||
|
imagepng($im,$cachepath,1);
|
||||||
|
}
|
||||||
imagepng($im);
|
imagepng($im);
|
||||||
break;
|
break;
|
||||||
case 'gif':
|
case 'gif':
|
||||||
header ("Content-type: image/gif");
|
header ("Content-type: image/gif");
|
||||||
$im = imagecreatefromgif($path);
|
$im = imagecreatefromgif($path);
|
||||||
|
if(!$cached)
|
||||||
|
{
|
||||||
|
changeImage($im,$data);
|
||||||
|
imagegif($im,$cachepath);
|
||||||
|
}
|
||||||
imagegif($im);
|
imagegif($im);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -128,17 +221,48 @@ function renderImage($hash,$file=false)
|
|||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderResizedImage($size,$hash)
|
function changeImage(&$im,$data)
|
||||||
{
|
{
|
||||||
$pm = new PictshareModel();
|
$image = new Image();
|
||||||
$im = new Image();
|
foreach($data as $action=>$val)
|
||||||
|
{
|
||||||
|
|
||||||
if(is_numeric($size))
|
switch($action)
|
||||||
$path = $im->getImage($hash,$size);
|
{
|
||||||
else
|
case 'rotate': $image->rotate($im,$val);break;
|
||||||
$path = $im->getImage($hash,explode('x',$size));
|
case 'size': $image->resize($im,$val);break;
|
||||||
|
case 'filter': $image->filter($im,$val);break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
renderImage($hash,$path);
|
function getCacheName($data)
|
||||||
|
{
|
||||||
|
ksort($data);
|
||||||
|
$name = array();
|
||||||
|
foreach($data as $key=>$val)
|
||||||
|
{
|
||||||
|
if($key!='hash')
|
||||||
|
{
|
||||||
|
if(!is_array($val))
|
||||||
|
$name[] = $key.'_'.$val;
|
||||||
|
else
|
||||||
|
foreach($val as $valdata)
|
||||||
|
$name[] = $valdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode('.',$name).'.'.$data['hash'];
|
||||||
|
}
|
||||||
|
|
||||||
|
function isSize($var)
|
||||||
|
{
|
||||||
|
if(is_numeric($var)) return true;
|
||||||
|
$a = explode('x',$var);
|
||||||
|
if(count($a)!=2 || !is_numeric($a[0]) || !is_numeric($a[1])) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isImage($hash)
|
function isImage($hash)
|
||||||
@@ -148,15 +272,6 @@ function isImage($hash)
|
|||||||
return $pm->hashExists($hash);
|
return $pm->hashExists($hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isResizedImage($resize,$hash)
|
|
||||||
{
|
|
||||||
if(!isImage($hash) || !$resize || !$hash) return false;
|
|
||||||
$a = explode('x',$resize);
|
|
||||||
if(!is_numeric($resize) && count($a)!=2) return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function render($variables=null)
|
function render($variables=null)
|
||||||
{
|
{
|
||||||
if(is_array($variables))
|
if(is_array($variables))
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ class PictshareModel extends Model
|
|||||||
return array('status'=>'ERR','reason'=>'wrong filetype');
|
return array('status'=>'ERR','reason'=>'wrong filetype');
|
||||||
|
|
||||||
if($dup_id)
|
if($dup_id)
|
||||||
return array('status'=>'OK','type'=>$type,'hash'=>$hash,'url'=>DOMAINPATH.$hash);
|
return array('status'=>'OK','type'=>$type,'hash'=>$hash,'url'=>DOMAINPATH.$hash,'domain'=>DOMAINPATH);
|
||||||
|
|
||||||
mkdir(ROOT.DS.'upload'.DS.$hash);
|
mkdir(ROOT.DS.'upload'.DS.$hash);
|
||||||
$file = ROOT.DS.'upload'.DS.$hash.DS.$hash;
|
$file = ROOT.DS.'upload'.DS.$hash.DS.$hash;
|
||||||
@@ -122,7 +122,7 @@ class PictshareModel extends Model
|
|||||||
fclose($fh);
|
fclose($fh);
|
||||||
}
|
}
|
||||||
|
|
||||||
return array('status'=>'OK','type'=>$type,'hash'=>$hash,'url'=>DOMAINPATH.$hash);
|
return array('status'=>'OK','type'=>$type,'hash'=>$hash,'url'=>DOMAINPATH.$hash,'domain'=>DOMAINPATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ProcessUploads()
|
function ProcessUploads()
|
||||||
|
|||||||
@@ -13,12 +13,11 @@
|
|||||||
<link rel="stylesheet" href="/css/normalize.css">
|
<link rel="stylesheet" href="/css/normalize.css">
|
||||||
<link rel="stylesheet" href="/css/pictshare.css">
|
<link rel="stylesheet" href="/css/pictshare.css">
|
||||||
<script src="/js/vendor/modernizr-2.6.2.min.js"></script>
|
<script src="/js/vendor/modernizr-2.6.2.min.js"></script>
|
||||||
<!--<script src="/js/highslide-full.js"></script>-->
|
|
||||||
<script type="text/javascript" src="/js/jquery-2.1.0.min.js"></script>
|
<script type="text/javascript" src="/js/jquery-2.1.0.min.js"></script>
|
||||||
<TITLE>PictShare - Free picture hosting</TITLE>
|
<TITLE>PictShare - Free image hosting</TITLE>
|
||||||
|
|
||||||
<meta name="description" content="Free picture sharing, linking and tracking">
|
<meta name="description" content="Free image sharing, linking and tracking">
|
||||||
<meta name="keywords" content="picture, share, hosting, free">
|
<meta name="keywords" content="image, share, hosting, free">
|
||||||
<meta name="robots" content="index, follow">
|
<meta name="robots" content="index, follow">
|
||||||
<meta name="copyright" content="Haschek Solutions">
|
<meta name="copyright" content="Haschek Solutions">
|
||||||
<meta name="language" content="EN,DE">
|
<meta name="language" content="EN,DE">
|
||||||
|
|||||||
Reference in New Issue
Block a user