Skip to content
This repository has been archived by the owner on Nov 25, 2020. It is now read-only.

Commit

Permalink
Add image rotation using exif information
Browse files Browse the repository at this point in the history
  • Loading branch information
TheLexus committed Oct 1, 2013
1 parent d018d38 commit 731848d
Show file tree
Hide file tree
Showing 6 changed files with 235 additions and 22 deletions.
120 changes: 113 additions & 7 deletions core/src/plugins/editor.diaporama/PThumb.lib.php
Expand Up @@ -29,7 +29,7 @@
* @package PThumb
*/
class PThumb{
/**#@+
/**#@
* PThumb Configuration Section
*/

Expand Down Expand Up @@ -124,14 +124,17 @@ class PThumb{
var $file_ext = array();

var $thumb_quality = 3;

var $exif_rotation = true;

/**#@-*/
/**
* The class constructor.
* @access public
*/
function PThumb($quality){
function PThumb($quality,$exifrotation){
$this->thumb_quality = $quality;
$this->exif_rotation = $exifrotation;
$this -> error_array["fatal"] = array();
$this -> error_array["warning"] = array();
if (!function_exists("gd_info")){
Expand Down Expand Up @@ -344,9 +347,12 @@ function print_thumbnail($image,$width,$height,$return_img = false, $display_inl
$transformed = $image;
$hash = sha1($image_data);
}

//Check if a version exists
$cache_file = $this -> cache_dir.sha1($transformed).".".$width.".".$height.".".$hash.".".$this->file_ext[$format];
if ($this -> exif_rotation)
$cache_file = $this -> cache_dir.sha1($transformed).".".$width.".".$height.".rotated.".$hash.".".$this->file_ext[$format];
else
$cache_file = $this -> cache_dir.sha1($transformed).".".$width.".".$height.".".$hash.".".$this->file_ext[$format];

if (file_exists($cache_file)){
if ($return_img == false){
//AJXP_Logger::debug("Using Cache");
Expand Down Expand Up @@ -381,7 +387,12 @@ function print_thumbnail($image,$width,$height,$return_img = false, $display_inl
$handle = @opendir($this -> cache_dir);
if ($handle !== FALSE) {
while (false !== ($file = readdir($handle))) {
if (preg_match("/^".preg_quote(sha1($transformed))."\.[0-9]+\.[0-9]+\.([0-9a-z]{40})\.(.+?)$/i",$file,$matches)) {
if ($this -> exif_rotation)
$rotated = "\.rotated";
else
$rotated = "";

if (preg_match("/^".preg_quote(sha1($transformed))."\.[0-9]+\.[0-9]+".$rotated."\.([0-9a-z]{40})\.(.+?)$/i",$file,$matches)) {
//Hash is in [1]
//Check to see if the file data is the same. If it is, then don't delete it.
if ($matches[1] != $hash){
Expand Down Expand Up @@ -411,6 +422,15 @@ function print_thumbnail($image,$width,$height,$return_img = false, $display_inl
return $this -> set_error("Method print_thumbnail: Unsupported Image '$image' type");
}

//Exif Orientation patch
$orientation = $this -> exiforientation($image, true);
if ($this -> rotationsupported($orientation) and $orientation>4)
{
$width2 = $width;
$width = $height;
$height = $width2;
}

//Now lets resize it
//First lets create a new image handler which will be the thumbnailed image
$thumbnail = imagecreatetruecolor($width,$height);
Expand All @@ -436,6 +456,45 @@ function print_thumbnail($image,$width,$height,$return_img = false, $display_inl
if (!$this->fastimagecopyresampled($thumbnail,$handle,0,0,0,0,$width,$height,ImageSX($handle),ImageSY($handle), $this->thumb_quality)){
return $this -> set_error("Method print_thumbnail: Failed resizing image '$image'.");
}

// Rotate if JPEG and Exif Information is available
$orientation = $this -> exiforientation($image, true);
if ($this -> rotationsupported($orientation))
{
switch($orientation)
{
case 2: // mirror horizontal
@imageflip($thumbnail, IMG_FLIP_HORIZONTAL);
break;

case 3: // rotate 180
$thumbnail = @imagerotate($thumbnail, 180, imagecolorallocate($thumbnail, 255, 255, 255));
break;

case 4: // mirror vertical
@imageflip($thumbnail, IMG_FLIP_VERTICAL);
break;

case 5: // mirror horizontal, 90 rotate left
@imageflip($thumbnail, IMG_FLIP_HORIZONTAL);
$thumbnail = @imagerotate($thumbnail, 90, imagecolorallocate($thumbnail, 255, 255, 255));
break;

case 6: // 90 rotate right
$thumbnail = @imagerotate($thumbnail, -90, imagecolorallocate($thumbnail, 255, 255, 255));
break;

case 7: // mirror horizontal, 90 rotate right
@imageflip($thumbnail, IMG_FLIP_HORIZONTAL);
$thumbnail = @imagerotate($thumbnail, -90, imagecolorallocate($thumbnail, 255, 255, 255));
break;

case 8: // 90 rotate left
$thumbnail = @imagerotate($thumbnail, 90, imagecolorallocate($thumbnail, 255, 255, 255));
break;
}
}

//Cache it
if ($this -> is_cacheable()){
switch ($format){
Expand Down Expand Up @@ -694,7 +753,7 @@ function scale_thumbnail($image,$magnitude,$return = false){
*/

function fit_thumbnail($image,$max_width = -1, $max_height = -1,$behaviour = 1 ,$return = false){

print_r("fit_thumbnail");

This comment has been minimized.

Copy link
@donglegiti

donglegiti Dec 3, 2014

what? Do you forget remove debug code?

$array = @$this -> retrieve_image_data($image);
if (!$array){
return $this -> set_error("Method scale_thumbnail: Unable to retrieve Image '$image' Size.");
Expand Down Expand Up @@ -779,6 +838,16 @@ function fit_thumbnail($image,$max_width = -1, $max_height = -1,$behaviour = 1 ,
$width = $owidth;
$height = $oheight;
}

//if ($format == 2){
$orientation = $this -> exiforientation($image, true);
if ($this -> rotationsupported($orientation) and $orientation>4)
{
$width2 = $width;
$width = $height;
$height = $width2;
}

if ($return == false){
return $this -> print_thumbnail($image,$width,$height);
}
Expand Down Expand Up @@ -1014,7 +1083,44 @@ function fastimagecopyresampled (&$dst_image, $src_image, $dst_x, $dst_y, $src_x
imagecopyresampled ($dst_image, $temp, $dst_x, $dst_y, 0, 0, $dst_w, $dst_h, $dst_w * $quality, $dst_h * $quality);
imagedestroy ($temp);
} else imagecopyresampled ($dst_image, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);

return true;
}

function exiforientation($image, $fetch)
{
if (!$this -> exif_rotation)
return;

if ($fetch)
{
$image_data = $this -> retrieve_remote_file($image,true, false, 1);
$exif = @exif_read_data("data://image/jpeg;base64,".@base64_encode($image_data),'IFD0');
} else
{
$exif = @exif_read_data($image);
}
if ($exif!=FALSE)
{
return $exif['Orientation'];
}
}

function rotationsupported($exif_orientation)
{
if (!$exif_orientation)
return FALSE;

if (!$this -> exif_rotation)
return FALSE;

if (function_exists("imageflip"))
return TRUE;

if ($exif_orientation!=2 and $exif_orientation!=4 and $exif_orientation!=5 and $exif_orientation!=7)
return TRUE;

return FALSE;
}
}
?>
?>
39 changes: 31 additions & 8 deletions core/src/plugins/editor.diaporama/class.Diaporama.js
Expand Up @@ -326,23 +326,47 @@ Class.create("Diaporama", AbstractEditor, {
},

resizeImage : function(morph){
var node = this.nodes.get(this.currentFile);
if(this.autoFit && morph){
this.computeFitToScreenFactor();
}
var nPercent = this.getZoomValue();
this.zoomInput.value = nPercent + ' %';
var height = parseInt(nPercent*this.crtHeight / 100);
var width = parseInt(nPercent*this.crtWidth / 100);

// apply rotation
this.imgBorder.removeClassName("ort-rotate-1");
this.imgBorder.removeClassName("ort-rotate-2");
this.imgBorder.removeClassName("ort-rotate-3");
this.imgBorder.removeClassName("ort-rotate-4");
this.imgBorder.removeClassName("ort-rotate-5");
this.imgBorder.removeClassName("ort-rotate-6");
this.imgBorder.removeClassName("ort-rotate-7");
this.imgBorder.removeClassName("ort-rotate-8");
var ort = node.getMetadata().get("ort");
if (ort)
this.imgBorder.addClassName("ort-rotate-"+ort);

// Center vertically
var marginTop=0;
var marginLeft=0;
this.containerDim = $(this.imgContainer).getDimensions();
if (height < this.containerDim.height){
marginTop = parseInt((this.containerDim.height - height) / 2);
}
if (width < this.containerDim.width){
marginLeft = parseInt((this.containerDim.width - width) / 2);
}

if (ort>4)
{
tmp=height;
height=width;
width=tmp;
}

if (height < this.containerDim.height){
marginTop = parseInt((this.containerDim.height - height) / 2);
}
if (width < this.containerDim.width){
marginLeft = parseInt((this.containerDim.width - width) / 2);
}

if(morph && this.imgBorder.visible()){
new Effect.Morph(this.imgBorder,{
style:{height:height+'px', width:width+'px',marginTop:marginTop+'px',marginLeft:marginLeft+'px'},
Expand Down Expand Up @@ -397,7 +421,6 @@ Class.create("Diaporama", AbstractEditor, {
nav.centerY = (nav.bottom-nav.top)/2;
nav.containerWidth = this.imgContainer.getWidth();
nav.containerHeight = this.imgContainer.getHeight();

var navigatorImg = overlay.next("img");
var offset = navigatorImg.positionedOffset();
var targetDim = navigatorImg.getDimensions();
Expand Down Expand Up @@ -741,4 +764,4 @@ Class.create("Diaporama", AbstractEditor, {
return source;
}

});
});
28 changes: 23 additions & 5 deletions core/src/plugins/editor.diaporama/class.ImagePreviewer.php
Expand Up @@ -50,7 +50,6 @@ public function switchAction($action, $httpVars, $filesVars){
if($action == "preview_data_proxy"){
$file = AJXP_Utils::decodeSecureMagic($httpVars["file"]);
if(!file_exists($destStreamURL.$file)) return;

if(isSet($httpVars["get_thumb"]) && $this->getFilteredOption("GENERATE_THUMBNAIL", $repository->getId())){
$dimension = 200;
if(isSet($httpVars["dimension"]) && is_numeric($httpVars["dimension"])) $dimension = $httpVars["dimension"];
Expand Down Expand Up @@ -116,7 +115,8 @@ public function removeThumbnail($oldFile, $newFile = null, $copy = false){
public function generateThumbnail($masterFile, $targetFile){
$size = $this->currentDimension;
require_once(AJXP_INSTALL_PATH."/plugins/editor.diaporama/PThumb.lib.php");
$pThumb = new PThumb($this->getFilteredOption("THUMBNAIL_QUALITY"));

$pThumb = new PThumb($this->getFilteredOption("THUMBNAIL_QUALITY"),$this->getFilteredOption("EXIF_ROTATION"));
if(!$pThumb->isError()){
$pThumb->remote_wrapper = $this->streamData["classname"];
//AJXP_Logger::debug("Will fit thumbnail");
Expand Down Expand Up @@ -160,16 +160,34 @@ public function extractImageMetadata(&$ajxpNode){
$setRemote = true;
}
}
if($isImage)

if($isImage)
{
if($setRemote){
$ajxpNode->image_type = "N/A";
$ajxpNode->image_width = "N/A";
$ajxpNode->image_height = "N/A";
$ajxpNode->readable_dimension = "";
}else{
$realFile = $ajxpNode->getRealFile();
require_once(AJXP_INSTALL_PATH."/plugins/editor.diaporama/PThumb.lib.php");
$pThumb = new PThumb($this->getFilteredOption["THUMBNAIL_QUALITY"],$this->getFilteredOption("EXIF_ROTATION"));
$realFile = $ajxpNode->getRealFile();

list($width, $height, $type, $attr) = @getimagesize($realFile);

$orientation = $pThumb->exiforientation($realFile, false);
if ($pThumb->rotationsupported($orientation))
{
$ajxpNode->ort = $orientation;

if ($orientation>4)
{
$tmp=$height;
$height=$width;
$width=$tmp;
}
}

$ajxpNode->image_type = image_type_to_mime_type($type);
$ajxpNode->image_width = $width;
$ajxpNode->image_height = $height;
Expand All @@ -186,4 +204,4 @@ protected function handleMime($filename){
}

}
?>
?>
4 changes: 3 additions & 1 deletion core/src/plugins/editor.diaporama/i18n/conf/en.php
Expand Up @@ -29,5 +29,7 @@
"Generate thumbnails or not" => "Generate thumbnails or not",
"Quality" => "Quality",
"Thumbs quality" => "Thumbs quality",
"Exif Rotation" => "Exif Rotation",
"Rotate image using exif rotation" => "Rotate image using exif rotation"
);
?>
?>
4 changes: 3 additions & 1 deletion core/src/plugins/editor.diaporama/manifest.xml
Expand Up @@ -5,12 +5,14 @@
<global_param name="META_EXTRACTION_THRESHOLD" type="string" label="CONF_MESSAGE[Size Threshold]" description="CONF_MESSAGE[Threshold]" default="50000"/>
<global_param name="GENERATE_THUMBNAIL" type="boolean" label="CONF_MESSAGE[Thumbnails]" description="CONF_MESSAGE[Generate thumbnails or not]" default="true"/>
<global_param name="THUMBNAIL_QUALITY" type="integer" label="CONF_MESSAGE[Quality]" description="CONF_MESSAGE[Thumbs quality]" default="2"/>
<global_param name="EXIF_ROTATION" type="boolean" label="CONF_MESSAGE[Exif Rotation]" description="CONF_MESSAGE[Rotate image using exif rotation]" default="true"/>
</server_settings>
<class_definition filename="plugins/editor.diaporama/class.ImagePreviewer.php" classname="ImagePreviewer"/>
<client_settings>
<resources>
<js file="plugins/editor.diaporama/class.Diaporama.js" className="Diaporama"/>
<i18n namespace="diaporama" path="plugins/editor.diaporama/i18n"/>
<css file="plugins/editor.diaporama/rotator.css"/>
</resources>
</client_settings>
<clientForm id="diaporama_box"><![CDATA[
Expand Down Expand Up @@ -113,4 +115,4 @@
</component_config>
</client_configs>
</registry_contributions>
</editor>
</editor>

0 comments on commit 731848d

Please sign in to comment.