Fix thumbnail orientation and add Copy Exif function
This commit is contained in:
@@ -174,7 +174,7 @@ class ToolBox
|
||||
return $iCount > 1;
|
||||
}
|
||||
|
||||
public static function createThumbnail($sInPath, $iMaxWidth, $iMaxHeight=0, $sOutPath='', $bDeleteIn=false, $asImageExts=array('jpg', 'jpeg', 'gif', 'png'), $bCrop=false)
|
||||
public static function createThumbnail($sInPath, $iMaxWidth, $iMaxHeight=0, $sOutPath='', $bDeleteIn=false, $asImageExts=array('jpg', 'jpeg', 'gif', 'png'), $bCrop=false, $bCopyExif=false)
|
||||
{
|
||||
$asResult = array('error'=>'');
|
||||
|
||||
@@ -194,7 +194,24 @@ class ToolBox
|
||||
elseif($iMaxWidth==0 && $iMaxHeight==0) $asResult['error'] = 'At least one dimension must be resized (width and/or height)';
|
||||
else
|
||||
{
|
||||
//Recalculate max width/height in case of rotated picture
|
||||
$sRotate = 0;
|
||||
$asExif = @exif_read_data($sInPath);
|
||||
if($asExif && array_key_exists('Orientation', $asExif)) {
|
||||
switch($asExif['Orientation'])
|
||||
{
|
||||
case 3: $sRotate = 180; break; //Flip over
|
||||
case 6: $sRotate = -90; break; //Clockwise
|
||||
case 8: $sRotate = 90; break; //Trigo
|
||||
}
|
||||
}
|
||||
|
||||
list($iWidth, $iHeight) = getimagesize($sInPath);
|
||||
if(abs($sRotate) == 90) {
|
||||
$iTempWidth = $iWidth;
|
||||
$iWidth = $iHeight;
|
||||
$iHeight = $iTempWidth;
|
||||
}
|
||||
|
||||
//Limit on only 1 parameter
|
||||
if($iMaxWidth==0) $iMaxWidth = $iWidth * $iMaxHeight / $iHeight;
|
||||
@@ -257,6 +274,9 @@ class ToolBox
|
||||
//create image from source
|
||||
$oSource = call_user_func('imagecreatefrom'.$sImageExt, $sInPath);
|
||||
|
||||
//Fix rotation
|
||||
if($sRotate) $oSource = imagerotate($oSource, $sRotate, 0);
|
||||
|
||||
//Resize
|
||||
$oThumb = imagecreatetruecolor($iThumbWidth, $iThumbHeight);
|
||||
imagecopyresampled($oThumb, $oSource, $iPosLeft, $iPosTop, 0, 0, $iResizedWidth, $iResizedHeight, $iWidth, $iHeight);
|
||||
@@ -267,6 +287,7 @@ class ToolBox
|
||||
{
|
||||
$asResult['error'] = 'Unable to create thumbnail : '.$sOutPath;
|
||||
}
|
||||
imagedestroy($oThumb);
|
||||
}
|
||||
}
|
||||
elseif($sInPath != $sOutPath)
|
||||
@@ -280,11 +301,75 @@ class ToolBox
|
||||
$asResult['out'] = $sOutPath;
|
||||
}
|
||||
|
||||
if($bCopyExif && $asResult['error'] == '') self::copyExif($sInPath, $sOutPath);
|
||||
if($bDeleteIn && $asResult['error'] == '' && $sInPath != $sOutPath) unlink($sInPath);
|
||||
|
||||
return $asResult;
|
||||
}
|
||||
|
||||
public function copyExif($srcfile, $destfile) {
|
||||
// Function transfers EXIF (APP1) and IPTC (APP13) from $srcfile and adds it to $destfile
|
||||
// JPEG file has format 0xFFD8 + [APP0] + [APP1] + ... [APP15] + <image data> where [APPi] are optional
|
||||
// Segment APPi (where i=0x0 to 0xF) has format 0xFFEi + 0xMM + 0xLL + <data> (where 0xMM is
|
||||
// most significant 8 bits of (strlen(<data>) + 2) and 0xLL is the least significant 8 bits
|
||||
// of (strlen(<data>) + 2)
|
||||
|
||||
if (file_exists($srcfile) && file_exists($destfile)) {
|
||||
$srcsize = @getimagesize($srcfile, $imageinfo);
|
||||
// Prepare EXIF data bytes from source file
|
||||
$exifdata = (is_array($imageinfo) && key_exists("APP1", $imageinfo)) ? $imageinfo['APP1'] : null;
|
||||
if ($exifdata) {
|
||||
$exiflength = strlen($exifdata) + 2;
|
||||
if ($exiflength > 0xFFFF) return false;
|
||||
// Construct EXIF segment
|
||||
$exifdata = chr(0xFF) . chr(0xE1) . chr(($exiflength >> 8) & 0xFF) . chr($exiflength & 0xFF) . $exifdata;
|
||||
}
|
||||
// Prepare IPTC data bytes from source file
|
||||
$iptcdata = (is_array($imageinfo) && key_exists("APP13", $imageinfo)) ? $imageinfo['APP13'] : null;
|
||||
if ($iptcdata) {
|
||||
$iptclength = strlen($iptcdata) + 2;
|
||||
if ($iptclength > 0xFFFF) return false;
|
||||
// Construct IPTC segment
|
||||
$iptcdata = chr(0xFF) . chr(0xED) . chr(($iptclength >> 8) & 0xFF) . chr($iptclength & 0xFF) . $iptcdata;
|
||||
}
|
||||
$destfilecontent = @file_get_contents($destfile);
|
||||
if (!$destfilecontent) return false;
|
||||
if (strlen($destfilecontent) > 0) {
|
||||
$destfilecontent = substr($destfilecontent, 2);
|
||||
$portiontoadd = chr(0xFF) . chr(0xD8); // Variable accumulates new & original IPTC application segments
|
||||
$exifadded = !$exifdata;
|
||||
$iptcadded = !$iptcdata;
|
||||
|
||||
while ((substr($destfilecontent, 0, 2) & 0xFFF0) === 0xFFE0) {
|
||||
$segmentlen = (substr($destfilecontent, 2, 2) & 0xFFFF);
|
||||
$iptcsegmentnumber = (substr($destfilecontent, 1, 1) & 0x0F); // Last 4 bits of second byte is IPTC segment #
|
||||
if ($segmentlen <= 2) return false;
|
||||
$thisexistingsegment = substr($destfilecontent, 0, $segmentlen + 2);
|
||||
if ((1 <= $iptcsegmentnumber) && (!$exifadded)) {
|
||||
$portiontoadd .= $exifdata;
|
||||
$exifadded = true;
|
||||
if (1 === $iptcsegmentnumber) $thisexistingsegment = '';
|
||||
}
|
||||
if ((13 <= $iptcsegmentnumber) && (!$iptcadded)) {
|
||||
$portiontoadd .= $iptcdata;
|
||||
$iptcadded = true;
|
||||
if (13 === $iptcsegmentnumber) $thisexistingsegment = '';
|
||||
}
|
||||
$portiontoadd .= $thisexistingsegment;
|
||||
$destfilecontent = substr($destfilecontent, $segmentlen + 2);
|
||||
}
|
||||
if (!$exifadded) $portiontoadd .= $exifdata; // Add EXIF data if not added already
|
||||
if (!$iptcadded) $portiontoadd .= $iptcdata; // Add IPTC data if not added already
|
||||
$outputfile = fopen($destfile, 'w');
|
||||
if ($outputfile) return fwrite($outputfile, $portiontoadd . $destfilecontent); else return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function utf8_compliant($sText)
|
||||
{
|
||||
if(strlen($sText) == 0) return true;
|
||||
|
||||
Reference in New Issue
Block a user