Als vervolg op de voorgaande mod voor Photostation 3 nu de aanpassing voor Photostation 4.
In het bestand convert.php (lokatie: /usr/syno/synoman/phpsrc/photo/) wordt het oproepen van de afbeeldingen geregeld.
Op regel negentig van dit bestand wordt gescheiden op welk soort bestand getoond moet worden. Keuze bestaat uit:
0 - Kleine thumbnail
1 - Grote thumbnail
2 - Origineel bestand
3 - Video
4 - 320px thumbnail
5 - 800px thumbnail
6 - mp4_H(oog)
7 - mp4_M(iddel)
8 - mp4_L(aag)
Middels het select case principe wordt hierin onderscheid gemaakt.
Ik heb de procedures bij 1, 2,4 en 5 zo aangepast dat daar waar de variabele $file wordt gevuld ($file = etc.) een aanroep wordt gedaan naar een nieuw toe te voegen functie WATERMARK.
Deze functie zorgt voor het invoegen van een watermerk rechtsonder in de afbeelding.
Hoe toe te passen:
1) Maak een reservekopie van het bestand /usr/syno/synoman/phpsrc/photo/convert.php
2) Pas convert.php als volgt aan:
na regel met 'case '1'' de regel met
$file = SYNOPHOTO_CONVERT_GetThumbPathFromFullPath($dir."/".$name, 1);
wijzigen in
$file = WATERMARK($dir,$name,1,1);
na regel met 'case '2' de regel met
$mime_type = SYNOPHOTO_CONVERT_GetPhotoMimeType($name);
opzoeken en direct daarna een nieuwe regel invoeren:
$file = WATERMARK($dir,$name,0,0);
Vervolgens (nog steeds in 'case 2') de regel met
$mime_type = "application/octet-stream";
opzoeken en hier een nieuwe regel invoeren:
$file = $dir."/".$name;
als laatste in 'case 2' de regel voor
break;
uitcommentariëren (of verwijderen).
Dus zo:
//$file = $dir."/".$name;
Bij 'case 4' de regel
$file = SYNOPHOTO_CONVERT_GetThumbPathFromFullPath($dir."/".$name, 4);
wijzigen in
$file = WATERMARK($dir, $name, 1, 4);
Bij 'case 5' de regel
$file = SYNOPHOTO_CONVERT_GetThumbPathFromFullPath($dir."/".$name, 5);
wijzigen in
$file = WATERMARK($dir, $name, 1, 5);
op de regel voor de php eindtag '?>' de volgende regels invoegen
function WATERMARK($dir, $name, $thumb, $thumbsize)
{
global $filename;
$watermark = imagecreatefrompng('/var/services/photo/copyright.png');
$watermark_width = imagesx($watermark);
$watermark_height = imagesy($watermark);
$image = imagecreatetruecolor($watermark_width, $watermark_height);
if ($thumb == 0) {
$image = imagecreatefromjpeg($dir."/".$name);
$size = getimagesize($dir."/".$name);
} else {
//SYNOPHOTO_CONVERT_GetThumbPathFromFullPath($dir."/".$name, 1);
$image = imagecreatefromjpeg(SYNOPHOTO_CONVERT_GetThumbPathFromFullPath($dir."/".$name, $thumbsize));
$size = getimagesize(SYNOPHOTO_CONVERT_GetThumbPathFromFullPath($dir."/".$name, $thumbsize));
}
$dest_x = $size[0] - $watermark_width - 5;
$dest_y = $size[1] - $watermark_height - 5;
imagecopymerge($image, $watermark, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height, 100); // 50% transparent
$filename = tempnam("/volume1/@tmp", "photostation_tmp_");//"/volume1/@tmp/tmp.jpg";
imagejpeg($image, $filename);
imagedestroy($image);
imagedestroy($watermark);
return $filename;
}
Na de regel
@readfile($file);
invoegen:
unlink($filename);
Het uiteindelijke bestand komt er dan bij mij als volgt uit te zien (ik heb de oude regels als commentaar (//) laten staan...
<?php
session_cache_limiter("must-revalidate");
if(!session_id()) {
session_start();
}
$SYNOPHOTO_ADMIN_PASS = "hlinak3";
SYNOPHOTO_CONVERT_AccessRightCheck();
$SYNOPHOTO_SERVICE_DIR = "/var/services/photo";
$SYNOPHOTO_EADIR = "@eaDir";
$SYNOPHOTO_THUMB_FILE_BIG = "SYNOPHOTO:THUMB_B.jpg";
$SYNOPHOTO_THUMB_FILE_SMALL = "SYNOPHOTO:THUMB_S.jpg";
$SYNOPHOTO_FLV_FILE = "SYNOPHOTO:FILM.flv";
$SYNOPHOTO_FLV_FILE_FAIL = "SYNOPHOTO:FILM.fail";
$SYNOPHOTO_THUMB_FILE_MEDIAN = "SYNOPHOTO:THUMB_M.jpg";
$SYNOPHOTO_THUMB_FILE_LARGE = "SYNOPHOTO:THUMB_L.jpg";
$SYNOPHOTO_MP4_HIGH_FILE = "SYNOPHOTO:FILM_H.mp4";
$SYNOPHOTO_MP4_MEDIUM_FILE = "SYNOPHOTO:FILM_M.mp4";
$SYNOPHOTO_MP4_LOW_FILE = "SYNOPHOTO:FILM_L.mp4";
$SYNOPHOTO_ALLOW_PICT_NAMES_EXT = array(
"jpg",
"jpeg",
"jpe",
"bmp",
"gif",
"png",
// Camera raw files
"arw", "srf", "sr2", // Sony
"dcr", "k25", "kdc", // Kodak
"cr2","crw",// Canon
"nef", // nikon
"mrw", // Minolta
"ptx", "pef",// Pentax
"raf", // Fuji
"3fr", // Hasselblad
"erf", // (Epson)
"mef", // (Mamiya)
"mos", // (Leaf)
"orf", // (Olympus),
"rw2", // (Panasonic)
"dng", // Adobe Digital Negative
"x3f", // Sigma Raw Image
"raw" // Panasonic
);
$SYNOPHOTO_ALLOW_PICT_WITH_THUMB_EXT = array(
"jpg",
"jpeg",
"jpe",
"bmp",
// Camera raw files
"arw", "srf", "sr2", // Sony
"dcr", "k25", "kdc", // Kodak
"cr2","crw",// Canon
"nef", // nikon
"mrw", // Minolta
"ptx", "pef",// Pentax
"raf", // Fuji
"3fr", // Hasselblad
"erf", // (Epson)
"mef", // (Mamiya)
"mos", // (Leaf)
"orf", // (Olympus),
"rw2", // (Panasonic)
"dng", // Adobe Digital Negative
"x3f", // Sigma Raw Image
"raw" // Panasonic
);
// The mimetype of raw image files is not listed here
$SYNOPHOTO_ALLOW_PICT_NAMES_MIME = array(
'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'jpe' => 'image/jpeg',
'bmp' => 'image/bmp',
'gif' => 'image/gif',
'png' => 'image/png'
);
$SYNOPHOTO_VIDEO_MIME = array(
'avi' => 'video/x-msvideo',
'm4v' => 'video/x-m4v',
'mov' => 'video/quicktime',
'mp4' => 'video/mp4',
'mpe' => 'video/mpeg',
'mpeg'=> 'video/mpeg',
'mpg'=> 'video/mpeg',
'qt' => 'video/quicktime',
'asf' => 'video/x-ms-asf',
'wmv' => 'video/x-ms-wmv'
);
if(isset($_GET['currdir']) && isset($_GET['currname'])) {
$dir = $SYNOPHOTO_SERVICE_DIR."/".$_GET['currdir'];
$name = $_GET['currname'];
$is_photo_file = SYNOPHOTO_CONVERT_IsPhotoFile($name);
if(isset($_GET['showorig'])) {
if($is_photo_file) {
if(!SYNOPHOTO_CONVERT_CheckAllowOrig($dir, $name)) {
exit;
}
$mime_type = SYNOPHOTO_CONVERT_GetPhotoMimeType($name);
$file = $dir."/".$name;
} else {
$mime_type = "video/x-flv";
$file = SYNOPHOTO_CONVERT_GetFlvPath($dir, $name);
$name = $name.".flv";
}
} else if(isset($_GET['showthumb'])) {
$file = SYNOPHOTO_CONVERT_GetThumbPathFromFullPath($SYNOPHOTO_SERVICE_DIR."/".$_GET['currdir']."/".$_GET['currname'], 0);
$mime_type = "image/jpeg";
} else {
$file = SYNOPHOTO_CONVERT_GetThumbPathFromFullPath($SYNOPHOTO_SERVICE_DIR."/".$_GET['currdir']."/".$_GET['currname'], 1);
$mime_type = "image/jpeg";
}
} elseif(isset($_GET['dir']) && isset($_GET['name'])) {
$dir = $SYNOPHOTO_SERVICE_DIR."/".@pack('H*', $_GET['dir']);
$name = @pack('H*', $_GET['name']);
$is_photo_file = SYNOPHOTO_CONVERT_IsPhotoFile($name);
// 0:small; 1:big; 2:org; 3:flv; 4:320px thumb; 5:800px thumb; 6:mp4_H; 7:mp4_M; 8:mp4_L
switch ($_GET['type']) {
case '0':
$file = SYNOPHOTO_CONVERT_GetThumbPathFromFullPath($dir."/".$name, 0);
$mime_type = "image/jpeg";
break;
case '1':
//$file = SYNOPHOTO_CONVERT_GetThumbPathFromFullPath($dir."/".$name, 1);
$file = WATERMARK($dir, $name, 1, 1);
$mime_type = "image/jpeg";
break;
case '2':
if(!SYNOPHOTO_CONVERT_CheckAllowOrig($dir, $name)) {
exit;
}
if($is_photo_file) {
$mime_type = SYNOPHOTO_CONVERT_GetPhotoMimeType($name);
$file = WATERMARK($dir, $name, 0, 0);
} else {
$mime_type = SYNOPHOTO_CONVERT_GetVideoMimeType($name);
if(!$mime_type) {
$mime_type = "application/octet-stream";
$file = $dir."/".$name; //Opgelet, nieuw!!!!
}
}
//$file = $dir."/".$name;
break;
case '3':
$mime_type = "video/x-flv";
$file = SYNOPHOTO_CONVERT_GetFlvPath($dir, $name);
$name = $name.".flv";
break;
case '4': // For 320px thumbnail
//$file = SYNOPHOTO_CONVERT_GetThumbPathFromFullPath($dir."/".$name, 4);
$file = WATERMARK($dir, $name, 1, 4);
$mime_type = "image/jpeg";
break;
case '5': // For 800px thumbnail
//$file = SYNOPHOTO_CONVERT_GetThumbPathFromFullPath($dir."/".$name, 5);
$file = WATERMARK($dir, $name, 1, 5);
$mime_type = "image/jpeg";
break;
case '6': // mp4 high quality
$file = SYNOPHOTO_CONVERT_GetMP4Path($dir, $name, "H");
$mime_type = "video/mp4";
break;
case '7': // mp4 medium quality
$file = SYNOPHOTO_CONVERT_GetMP4Path($dir, $name, "M");
$mime_type = "video/mp4";
break;
case '8': // mp4 low quality
$file = SYNOPHOTO_CONVERT_GetMP4Path($dir, $name, "L");
$mime_type = "video/mp4";
break;
default:
exit;
break;
}
}
$signature = SYNOPHOTO_CONVERT_CreateSig($file);
if($signature) {
SYNOPHOTO_CONVERT_CheckSigExit($signature);
@header("Last-Modified: " . $signature[0]);
}
@header("Cache-Control: max-age=".(3600*24*7));
@header("Content-Type: ".$mime_type);
@header("Content-Length: ".filesize($file));
if($is_photo_file) {
@header("Content-Disposition: inline; filename=".addslashes($name));
}
@readfile($file);
unlink($filename);
function SYNOPHOTO_CONVERT_GetPhotoMimeType($path)
{
global $SYNOPHOTO_ALLOW_PICT_NAMES_MIME;
$path = strtolower($path);
$path_parts = pathinfo($path);
$extension = $path_parts['extension'];
if(array_key_exists($extension, $SYNOPHOTO_ALLOW_PICT_NAMES_MIME)) {
return $SYNOPHOTO_ALLOW_PICT_NAMES_MIME[$extension];
}
else {
return "image/x-" . strtolower($extension);
}
}
function SYNOPHOTO_CONVERT_IsPhotoFile($path)
{
global $SYNOPHOTO_ALLOW_PICT_NAMES_EXT;
$path = strtolower($path);
$path_parts = pathinfo($path);
$extension = $path_parts['extension'];
if(in_array($extension, $SYNOPHOTO_ALLOW_PICT_NAMES_EXT)) {
return true;
} else {
return false;
}
}
function SYNOPHOTO_CONVERT_GetVideoMimeType($path)
{
global $SYNOPHOTO_VIDEO_MIME;
$path = strtolower($path);
$path_parts = pathinfo($path);
$extension = $path_parts['extension'];
if(array_key_exists($extension, $SYNOPHOTO_VIDEO_MIME)) {
return $SYNOPHOTO_VIDEO_MIME[$extension];
}
return '';
}
function SYNOPHOTO_CONVERT_IsPhotoFileWithThumb($path)
{
global $SYNOPHOTO_ALLOW_PICT_WITH_THUMB_EXT;
$path = strtolower($path);
$path_parts = pathinfo($path);
$extension = $path_parts['extension'];
if(in_array($extension, $SYNOPHOTO_ALLOW_PICT_WITH_THUMB_EXT)) {
return true;
} else {
return false;
}
}
function SYNOPHOTO_CONVERT_GetFlvPath($dir, $name)
{
global $SYNOPHOTO_EADIR, $SYNOPHOTO_FLV_FILE, $SYNOPHOTO_SERVICE_DIR;
return $dir."/".$SYNOPHOTO_EADIR."/".$name."/".$SYNOPHOTO_FLV_FILE;
}
function SYNOPHOTO_CONVERT_GetMP4Path($dir, $name, $quality_type)
{
global $SYNOPHOTO_EADIR, $SYNOPHOTO_MP4_HIGH_FILE, $SYNOPHOTO_MP4_MEDIUM_FILE, $SYNOPHOTO_MP4_LOW_FILE, $SYNOPHOTO_SERVICE_DIR;
switch ($quality_type) {
case "H":
$mp4_file = $dir."/".$SYNOPHOTO_EADIR."/".$name."/".$SYNOPHOTO_MP4_HIGH_FILE;
break;
case "M":
$mp4_file = $dir."/".$SYNOPHOTO_EADIR."/".$name."/".$SYNOPHOTO_MP4_MEDIUM_FILE;
break;
case "L":
$mp4_file = $dir."/".$SYNOPHOTO_EADIR."/".$name."/".$SYNOPHOTO_MP4_LOW_FILE;
break;
}
return $mp4_file;
}
function SYNOPHOTO_CONVERT_GetFlvFailPath($dir, $name)
{
global $SYNOPHOTO_EADIR, $SYNOPHOTO_FLV_FILE_FAIL, $SYNOPHOTO_SERVICE_DIR;
return $dir."/".$SYNOPHOTO_EADIR."/".$name."/".$SYNOPHOTO_FLV_FILE_FAIL;
}
function SYNOPHOTO_CONVERT_GetThumbPathFromFullPath($path, $type)
{
global $SYNOPHOTO_EADIR;
global $SYNOPHOTO_THUMB_FILE_BIG, $SYNOPHOTO_THUMB_FILE_SMALL,
$SYNOPHOTO_THUMB_FILE_MEDIAN, $SYNOPHOTO_THUMB_FILE_LARGE;
$file_name = basename($path);
$dir = substr($path, 0, strlen($path) - strlen($file_name));
switch ($type) {
case 0:
$thumb_file = $dir.$SYNOPHOTO_EADIR."/".$file_name."/".$SYNOPHOTO_THUMB_FILE_SMALL;
break;
case 1:
$thumb_file = $dir.$SYNOPHOTO_EADIR."/".$file_name."/".$SYNOPHOTO_THUMB_FILE_BIG;
break;
case 4:
$thumb_file = $dir.$SYNOPHOTO_EADIR."/".$file_name."/".$SYNOPHOTO_THUMB_FILE_MEDIAN;
break;
case 5:
$thumb_file = $dir.$SYNOPHOTO_EADIR."/".$file_name."/".$SYNOPHOTO_THUMB_FILE_LARGE;
break;
}
return $thumb_file;
}
function SYNOPHOTO_CONVERT_CreateSig($thumbpath) {
$filest = @stat($thumbpath);
$etag = "";
if($filest != FALSE) {
$lastmod = gmdate('D, d M Y H:i:s', $filest[9]) . ' GMT';
return array($lastmod);
} else {
return FALSE;
}
}
function SYNOPHOTO_CONVERT_CheckSigExit($signature) {
$etag = $signature[0];
$lastmod = $signature[1];
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
$ims = preg_replace('/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE'] );
if($ims == $lastmod) {
@header("HTTP/1.1 304 Not Modified");
exit;
}
}
}
function SYNOPHOTO_CONVERT_AccessRightCheck()
{
global $SYNOPHOTO_ADMIN_PASS;
if(isset($_SESSION['admin_syno_user']) && $_SESSION['admin_syno_user'] == $SYNOPHOTO_ADMIN_PASS) {
return;
}
if(isset($_GET['currdir']) && isset($_GET['currname'])) {
$_GET['dir'] = bin2hex($_GET['currdir']);
$_GET['name'] = bin2hex($_GET['currname']);
}
if(!isset($_GET['dir']) || $_GET['dir'] == "" || !isset($_GET['name']) || $_GET['name'] == "") {
header("Location: /photo/index.php");
exit;
}
$orig_dir = @pack('H*', $_GET['dir']);
$dir = $orig_dir;
if(strstr($orig_dir, "/")) {
$dir = substr($orig_dir, 0, strpos($orig_dir, "/"));
if(strpos($orig_dir, "/", strlen($dir) + 1)) {
$sub_dir = substr($orig_dir, 0, strpos($orig_dir, "/", strlen($dir) + 1));
} else {
$sub_dir = $orig_dir;
}
} else {
$sub_dir = "";
}
if(!isset($_SESSION['accessible_album'])) {
SYNOPHOTO_CONVERT_GetAccessibleAlbums();
}
if(!$_SESSION['accessible_album'][$dir] ||
($sub_dir != "" && !$_SESSION['accessible_subdir'][$sub_dir])) {
echo "<script>";
echo "parent.location = "/photo/login.php?url=".bin2hex($_SERVER['PHP_SELF']."?".$_SERVER['QUERY_STRING'])."";";
echo "</script>";
exit;
}
}
function SYNOPHOTO_CONVERT_GetAccessibleAlbums()
{
$_SESSION['accessible_album'] = null;
$_SESSION['accessible_subdir'] = null;
if (isset($_SESSION['admin_syno_user'])) {
$query = "Select * from photo_share order by sharename asc";
} elseif (isset($_SESSION['reg_syno_user'])) {
$query = "Select * from photo_share where shareid in (select shareid from photo_access_right where userid = ".$_SESSION['reg_syno_userid'].") or public = true order by sharename asc";
} else {
$query = "Select * from photo_share where public = true order by sharename asc";
}
$username = "admin";
$dbname = "photo";
$conn_string = "dbname=".$dbname." user=".$username;
if (!isset($GLOBALS['dbconn_photo']) || $GLOBALS['dbconn_photo'] == null) {
$GLOBALS['dbconn_photo'] = pg_connect($conn_string) or die("Failed to connect");
}
$db_result = pg_query($GLOBALS['dbconn_photo'], $query);
while($row = pg_fetch_row($db_result)) {
if($row[8] == 't') {
$_SESSION['accessible_subdir'][$row[1]] = 1;
} else {
$_SESSION['accessible_album'][$row[1]] = 1;
}
}
}
function SYNOPHOTO_CONVERT_CheckAllowOrig($dir, $name)
{
if(SYNOPHOTO_CONVERT_IsPhotoFile($name)) {
if(!SYNOPHOTO_CONVERT_IsPhotoFileWithThumb($name)) {
return TRUE;
}
} else {
$file = SYNOPHOTO_CONVERT_GetFlvFailPath($dir, $name);
// User can download video when this video can not be converted to flv.
if(@file_exists($file)) {
return TRUE;
}
$is_video = TRUE;
}
$username = "admin";
$dbname = "photo";
$conn_string = "dbname=".$dbname." user=".$username;
if (!isset($GLOBALS['dbconn_photo']) || $GLOBALS['dbconn_photo'] == null) {
$GLOBALS['dbconn_photo'] = pg_connect($conn_string) or die("Failed to connect");
}
$result = FALSE;
$config_name = "allow_orig";
if($is_video) {
$config_name = "allow_video_download";
}
$query = "Select config_value from photo_config where module_name = 'photo' and config_key = '".$config_name."'";
$db_result = pg_query($GLOBALS['dbconn_photo'], $query);
if($row = pg_fetch_row($db_result)) {
if($row[0] == 'on') {
$result = TRUE;
}
}
return $result;
}
function WATERMARK($dir, $name, $thumb, $thumbsize)
{
global $filename;
$watermark = imagecreatefrompng('/var/services/web/copyright.png');
$watermark_width = imagesx($watermark);
$watermark_height = imagesy($watermark);
$image = imagecreatetruecolor($watermark_width, $watermark_height);
if ($thumb == 0) {
$image = imagecreatefromjpeg($dir."/".$name);
$size = getimagesize($dir."/".$name);
} else {
$image = imagecreatefromjpeg(SYNOPHOTO_CONVERT_GetThumbPathFromFullPath($dir."/".$name, $thumbsize));
$size = getimagesize(SYNOPHOTO_CONVERT_GetThumbPathFromFullPath($dir."/".$name, $thumbsize));
}
$dest_x = $size[0] - $watermark_width - 5;
$dest_y = $size[1] - $watermark_height - 5;
imagecopymerge($image, $watermark, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height, 100); // 50% transparent
$filename = tempnam("/volume1/@tmp", "photostation_tmp_");//"/volume1/@tmp/tmp.jpg";
imagejpeg($image, $filename);
imagedestroy($image);
imagedestroy($watermark);
return $filename;
}
?>
Wat er hier gebeurt is dat een ander plaatje, nl. /var/services/web/copyright.png in de rechteronderhoek van een nieuw tijdelijk plaatje (/volume1/@tmp/photostation_tmp_
xxx.jpg - Bedankt Freeze!) op basis van de originele (thumbnail)afbeelding wordt geplakt. Overigens is /var/services/web hetzelfde als /volume1/web . Je kan natuurlijk een andere lokatie kiezen: pas dan het script overeenkomstig aan!
Het plaatje in kwestie is een simpel png bestandje: zwarte tekst op een transparante achtergrond.
De tijdelijke afbeelding wordt na verzending naar de bezoeker automatisch verwijderd.
!BELANGRIJK OM TE WETEN!
- Het watermerk wordt alleen toegevoegd aan de afbeeldingen die via Photostation naar een bezoeker worden verzonden. Dit betekent dus dat de originele bestanden en thumbnails ONGEWIJZIGD blijven!
- Het watermerk wordt niet toegevoegd aan de hele kleine thumbnails in de overzichten. Leek mij niet zinvol. Ook video's worden niet meegenomen.
- Getest op DSM 2.3-1157 onder IE7 en Firefox 3
- Wijzigingen op eigen risico. Maak backups!
- Code met dank aan Brock Ferguson (
http://articles.sitepoint.com/article/w ... images-php)
- Gooi de cache van je browser leeg, anders kan het zijn dat het net lijkt of er niets gewijzigd is.
- Herstelactie voor als het misgaat: plaats de in stap 1 gemaakte backup terug
Veel plezier er mee!
Wizjos