我需要一个 PHP 脚本来使用 iPad 在服务器上旋转我上传的图像。我对图像和 exif 数据的方向有疑问。我尝试了 10 种解决方案,但没有解决方案。当“按钮”在右侧时,上传的图像是好的,但是如果我旋转 iPad,那么我的图像会旋转,我无法正常显示它们..有什么帮助吗?
问问题
2347 次
1 回答
6
给你,我决定玩一玩,因为我有 30 分钟的空闲时间来杀人
https://github.com/leesherwood/Orientation-Fix-PHP
只需将文件路径传递给fix_orientation
函数,它应该可以工作(检查代码和函数注释,您可能想要编辑它最终如何保存图像,例如名称或其他)
对于那些只想要代码或 github 死掉的人,这里是你的主函数文件
<?php
/*
* PHP Orientation Fix (GD) v1.0.0
* https://github.com/leesherwood/Orientation-Fix-PHP
*
* Copyright 2013, "leesherwood" Lee Sherwood
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
*
* AKA: I couldn't care less what you do with it,
* im just a nice guy and i want to share.
* But it would be nice if you left me a little credit :)
*
* If you use this, then let me know at: i-played-with-your-git@secure4sure.org
*/
/**
* The main function that does the actual job
*
* Pass a string representing the image path and filename such as /var/www/images/image.jpg
* And it will change the name of the image to include "orig." (for the sake of not deleting your image if something goes wrong)
* and then create a new image with the same filename, with the orientation fixed
* The return bool is not informative and should only be used to to tell your script that there is a proper orientated image available (or not)
* If you want to know why it failed (theres many reason) then you need to make the return values for informative, or use exceptions.
*
* @param string the path to the file including the file iteself (absolute path would be advised)
* @return bool true if successful, false if not
*/
function fix_orientation($fileandpath) {
// Does the file exist to start with?
if(!file_exists($fileandpath))
return false;
// Get all the exif data from the file
$exif = read_exif_data($fileandpath, 'IFD0');
// If we dont get any exif data at all, then we may as well stop now
if(!$exif || !is_array($exif))
return false;
// I hate case juggling, so we're using loweercase throughout just in case
$exif = array_change_key_case($exif, CASE_LOWER);
// If theres no orientation key, then we can give up, the camera hasn't told us the
// orientation of itself when taking the image, and i'm not writing a script to guess at it!
if(!array_key_exists('orientation', $exif))
return false;
// Gets the GD image resource for loaded image
$img_res = get_image_resource($fileandpath);
// If it failed to load a resource, give up
if(is_null($img_res))
return false;
// The meat of the script really, the orientation is supplied as an integer,
// so we just rotate/flip it back to the correct orientation based on what we
// are told it currently is
switch($exif['orientation']) {
// Standard/Normal Orientation (no need to do anything, we'll return true as in theory, it was successful)
case 1: return true; break;
// Correct orientation, but flipped on the horizontal axis (might do it at some point in the future)
case 2:
$final_img = imageflip($img_res, IMG_FLIP_HORIZONTAL);
break;
// Upside-Down
case 3:
$final_img = imageflip($img_res, IMG_FLIP_VERTICAL);
break;
// Upside-Down & Flipped along horizontal axis
case 4:
$final_img = imageflip($img_res, IMG_FLIP_BOTH);
break;
// Turned 90 deg to the left and flipped
case 5:
$final_img = imagerotate($img_res, -90, 0);
$final_img = imageflip($img_res, IMG_FLIP_HORIZONTAL);
break;
// Turned 90 deg to the left
case 6:
$final_img = imagerotate($img_res, -90, 0);
break;
// Turned 90 deg to the right and flipped
case 7:
$final_img = imagerotate($img_res, 90, 0);
$final_img = imageflip($img_res,IMG_FLIP_HORIZONTAL);
break;
// Turned 90 deg to the right
case 8:
$final_img = imagerotate($img_res, 90, 0);
break;
}
// If theres no final image resource to output for whatever reason, give up
if(!isset($final_img))
return false;
//-- rename original (very ugly, could probably be rewritten, but i can't be arsed at this stage)
$parts = explode("/", $fileandpath);
$oldname = array_pop($parts);
$path = implode('/', $parts);
$oldname_parts = explode(".", $oldname);
$ext = array_pop($oldname_parts);
$newname = implode('.', $oldname_parts).'.orig.'.$ext;
rename($fileandpath, $path.'/'.$newname);
// Save it and the return the result (true or false)
$done = save_image_resource($final_img,$fileandpath);
return $done;
}
/**
* Simple function which takes the filepath, grabs the extension and returns the GD resource for it
* Not fool-proof nor the best, but it does the job for now
*/
function get_image_resource($file) {
$img = null;
$p = explode(".", strtolower($file));
$ext = array_pop($p);
switch($ext) {
case "png":
$img = imagecreatefrompng($file);
break;
case "jpg":
case "jpeg":
$img = imagecreatefromjpeg($file);
break;
case "gif":
$img = imagecreatefromgif($file);
break;
}
return $img;
}
/**
* Saves the final image resource to the given location
* As above it works out the extension and bases its output command on that, not fool proof, but works nonetheless
*/
function save_image_resource($resource, $location) {
$success = false;
$p = explode(".", strtolower($location));
$ext = array_pop($p);
switch($ext) {
case "png":
$success = imagepng($resource,$location);
break;
case "jpg":
case "jpeg":
$success = imagejpeg($resource,$location);
break;
case "gif":
$success = imagegif($resource,$location);
break;
}
return $success;
}
/**
* My Dev environment is not the latest on this machine. which is lucky as i never bothered to check if imageflip needed a specific version
* ( been using imagerotate for ages and assumed imageflip would surely be included to )
* But as it turns out, you need a fairly recent version of PHP for imageflip, so i cobbled together a quick replacement function for those that don't have it
*/
if(!function_exists('imageflip')) {
// These are the same constants so this script should be upgrade safe, the values are different no doubt, but that won't hurt!
define("IMG_FLIP_HORIZONTAL", 1);
define("IMG_FLIP_VERTICAL", 2);
define("IMG_FLIP_BOTH", 3);
/**
* Simple function that takes a gd image resource and the flip mode, and uses rotate 180 instead to do the same thing... Simples!
*/
function imageflip($resource, $mode) {
if($mode == IMG_FLIP_VERTICAL || $mode == IMG_FLIP_BOTH)
$resource = imagerotate($resource, 180, 0);
if($mode == IMG_FLIP_HORIZONTAL || $mode == IMG_FLIP_BOTH)
$resource = imagerotate($resource, 90, 0);
return $resource;
}
}
?>
于 2013-04-10T21:09:04.920 回答