thibaud-rohmer / PhotoShow

A free web gallery in PHP with drag-n-drop support
http://www.photoshow-gallery.com
505 stars 152 forks source link

does not apply exif rotation information #286

Open Caliandroid opened 9 years ago

Caliandroid commented 9 years ago

I've remarked that the uploaded pictures aren't displayed according to their exif roation information. This would be a great feature.

As alternative a manuel rotation feature would be also handy.

skarjalainen commented 9 years ago

+1 for this. It would be great if gallery would display image in correct orientation automatically. Anybody interested in lossless rotating tool while preserving all exif data (ofcourse reset the orientation flag) google JHEAD (jhead -autorot *.jpg).

Otherwise very promising software. Fast and easy to setup.

Anarky commented 9 years ago

I think this is a duplicate of #239.

I tried to see where it is possible to fix it; the problem doesn't come from PhotoShow, but our browser. When displaying an image through an img tag or with the background-image CSS property, almost no browsers will read its EXIF rotation. Mozilla worked on that with a new CSS property, image-orientation [1]. It is available since Firefox 26, but this is the only browser to support it.

Moreover, it would need some changes in PhotoShow, because image-orientation applies only to img tag, while PhotoShow uses background-image.

[1] https://developer.mozilla.org/en-US/docs/Web/CSS/image-orientation

Edit: it seems the thumbnail (and the _small picture when needed) doesn't save or use the EXIF rotation at their creation; it might be broken since 475f67a, but the browser won't display it correctly if the rotation is made with the EXIF data. I don't know what should be the correct behaviour:

  1. create the thumbnail/_small image by reducing the original image, then copy the EXIF rotation value (the browser will not display it correctly)
  2. or read the EXIF rotation value then create the thumbnail/_small image accordingly (might be misleading if the _small image isn't needed and only the thumbnail has the right orientation). From what I understand (calling the Rotate() function of phpthumb), it seems we want to do the first option, which is currently broken.
Swiiney commented 8 years ago

Hi, Do you have any update about the correct display of the pictures? I really like you Gallery site but with this problem I am not sur I am going to use it...

Thanks Regards

Swiiney commented 8 years ago

Hi, I had a look at your code and with few modification I got the correct orientation for the pictures. I only changed come lines in src/classes/provider.php.

Line 89 :

private static function autorotate_jpeg ($filename)
    {
        $raw_image = imagecreatefromjpeg($filename);
        $degrees = Provider::get_orientation_degrees ($filename);
        if($degrees < 0){           //SBO
            $degrees=360+$degrees;  //SBO
        }                           //SBO
        if($degrees > 0){
            $rotated_image = imagerotate($raw_image, $degrees, 0);
            if($rotated_image == NULL){
                return $raw_image;
            }
        }else{
            $rotated_image = $raw_image;
        }

        return $rotated_image;
    }

Line 247 :

            if (File::Type($file) == 'Image' && Provider::get_orientation_degrees($file) != 0) {
                $thumb->SourceImageToGD();
                $thumb->ra = 180 + Provider::get_orientation_degrees($file); //SBO
                $thumb->Rotate();
            }

Line 297 :

            if (File::Type($file) == 'Image' && Provider::get_orientation_degrees($file) != 0) {
                $thumb->SourceImageToGD();
                $thumb->ra = 180+Provider::get_orientation_degrees($file); //SBO
                $thumb->Rotate();
            }

Line 383 : reactivated your commented lines

            if(File::Type($path)=="Image"){
                header('Content-type: image/jpeg');
                try {
                    imagejpeg(Provider::autorotate_jpeg ($path));   
                }catch(Exception $e){
                    error_log('ERROR/Provider.php: cannot rotate '.$path.': '.$e);
                    readfile($path);
                }
            }else{

Maybe I missed something but it seems to be working...

Stephane

benoitb85 commented 8 years ago

Thanks Swiiney, I made your modifications in my install and I get the behavior I expected :) Will this be implemented in the main branch of PhotoShow or will this be rejected and require a fork ?

CyberShadow commented 8 years ago

Thanks Swiiney! Your patch is almost right, however instead of 180+ the correct code is 360- for correct rotation of portrait photos. Also the hunk at line 383 doesn't seem necessary, since generated thumbnails will never have EXIF information, and browsers auto-rotate images when they're opened directly.

I submitted the patch as a PR: https://github.com/thibaud-rohmer/PhotoShow/pull/312

saarloosw commented 7 years ago

I got this to work using phpthumb class, this will use the exif data as well and no need to deal whether or not to use SourceImageToGD(); phpthumb will do this for you. The catch I encountered was that it only worked when you set $thumbs->DieOnErrors = true; BUG in the phpthumbs library???

Setting: $thumbs->ar = true; will do the job and the files are cached the correct way.

        /// Create thumbnail
        $thumb = new phpthumb();
                    //Strange after setting DieOnErrors, phpthump started to auto rotate the images
        $thumb->DieOnErrors = true; 
        if (!empty(Settings::$imagemagick_path)) {
            $thumb->config_imagemagick_path = Settings::$imagemagick_path;
        }

        $thumb->setSourceData( file_get_contents( $file ) ); 
                    // Is this the correct place to call the calculation or is this realy needed?
        $thumb->CalculateThumbnailDimensions(); 
        $thumb->w = Settings::$thumbs_size;
        $thumb->h = Settings::$thumbs_size;
        $thumb->zc = Settings::$thumbs_size;
        $thumb->q = Settings::$quality_mini;
                    //auto rotate will use exif data
        $thumb->ar = "x"; 
                    // Add additional checks if the thumbnail generation works, else log an error
        if( !$thumb->GenerateThumbnail() ) {
            error_log("Failed to generate thumbnail");
        } else {
            if($thumb->RenderToFile($path)) {
                chmod($path,0775);
            } else {
                error_log( "File not saved" . $path );
            }
        }
    }
westframe commented 7 years ago

When I rotate images in OSX Preview, then upload them, the rotation does not copy to PhotoShow unfortunately. Any solutions for this?