【问题标题】:PHP image cropping rotates imagePHP图像裁剪旋转图像
【发布时间】:2015-02-18 10:34:14
【问题描述】:

我正在创建一个允许人们上传照片的移动应用程序,但是我在使用 Image Manipulator Class 调整图像大小时遇到​​了问题,您可以在此处找到 https://gist.github.com/philBrown/880506

我的问题是,当我将手机保持在纵向模式下拍照时,图像会向右旋转 90 度。当我在横向模式下拍照时,一切都很好。

这是我的裁剪 PHP 代码:

$manipulator = new ImageManipulator($_FILES['Filedata']['tmp_name']);
$width  = $manipulator->getWidth();
$height = $manipulator->getHeight();
$centreX = round($width / 2);
$centreY = round($height / 2);

// our dimensions will be 600x450
$x1 = $centreX - 300; // 600 / 2
$y1 = $centreY - 225; // 450 / 2

$x2 = $centreX + 300; // 600 / 2
$y2 = $centreY + 225; // 450 / 2

// center cropping to 600x450
$newImage = $manipulator->crop($x1, $y1, $x2, $y2);

// rotate 90 degrees to the right
$imageResource = $newImage->getResource();
$angle = '90'; // in degrees
$fileName = "../file_upload_img/43/" . $random_file_name . $_FILES["Filedata"]["name"];
$rotatedImage = imagerotate($imageResource, $angle);
imagejpeg($rotatedImage, $fileName, 95);

// saving file to uploads folder
$manipulator->save("../file_upload_img/43/" . $random_file_name . $_FILES["Filedata"]["name"]);

如何确保以纵向模式拍摄的照片在裁剪时不会旋转?

编辑*

upload.php 代码:

require_once(__DIR__ . '/../includes/ImageManipulator.php');
require_once(__DIR__ . '/../init/db/conn.php');

ob_start();
echo "<pre>";
print_r($_FILES);
print_r($_GET);
print_r($_POST);

echo "</pre>";

print_r("file type: " . $_FILES["Filedata"]["type"]);

$allowedExts = array("gif", "jpeg", "jpg", "png");
$temp = explode(".", $_FILES["Filedata"]["name"]);
$extension = end($temp);
if ((($_FILES["Filedata"]["type"] == "image/gif")
    || ($_FILES["Filedata"]["type"] == "image/jpeg")
    || ($_FILES["Filedata"]["type"] == "image/jpg")
    || ($_FILES["Filedata"]["type"] == "image/pjpeg")
    || ($_FILES["Filedata"]["type"] == "image/x-png")
    || ($_FILES["Filedata"]["type"] == "image/png"))
    && ($_FILES["Filedata"]["size"] < 9999999999)
    && in_array($extension, $allowedExts)) {
        if ($_FILES["Filedata"]["error"] > 0) {
            echo "Return Code: " . $_FILES["Filedata"]["error"] . "<br>";
        }
        else {
            echo "Upload: " . $_FILES["Filedata"]["name"] . "<br>";
            echo "Type: " . $_FILES["Filedata"]["type"] . "<br>";
            echo "Size: " . ($_FILES["Filedata"]["size"] / 1024) . " kB<br>";
            echo "Temp file: " . $_FILES["Filedata"]["tmp_name"] . "<br>";

        if (file_exists("../file_upload_img/" . $_FILES["Filedata"]["name"])) {
            echo $_FILES["Filedata"]["name"] . " already exists. ";
        }
        else {
            $random_file_name = sha1(uniqid($_FILES["Filedata"]["name"]));

            /*
            * ROTATE, CROP AND RESIZE
            */
            // 4:3 Ratio version
            $manipulator = new ImageManipulator($_FILES['Filedata']['tmp_name']);

            // Resize image to 600px wide and 450px high
            $manipulator = $manipulator->resample(600, 450);    

            // saving file to uploads folder
            $manipulator->save("../file_upload_img/43/" . $random_file_name . $_FILES["Filedata"]["name"]);

            $width  = $manipulator->getWidth();
            $height = $manipulator->getHeight();
            $centreX = round($width / 2);
            $centreY = round($height / 2);
            // our dimensions will be 600x450
            $x1 = $centreX - 300; // 600 / 2
            $y1 = $centreY - 225; // 450 / 2

            $x2 = $centreX + 300; // 600 / 2
            $y2 = $centreY + 225; // 450 / 2

            // center cropping to 200x130
            $newImage = $manipulator->crop($x1, $y1, $x2, $y2);

            // rotate 90 degrees to the right
            $imageResource = $newImage->getResource();
            $angle = '90'; // in degrees
            $fileName = "../file_upload_img/43/" . $random_file_name . $_FILES["Filedata"]["name"];
            $rotatedImage = imagerotate($imageResource, $angle);
            imagejpeg($rotatedImage, $fileName, 95);

            // saving file to uploads folder
            $manipulator->save("../file_upload_img/43/" . $random_file_name . $_FILES["Filedata"]["name"]);

            // 640:120 Ratio version
            $manipulator_640 = new ImageManipulator($_FILES['Filedata']['tmp_name']);

            // Resize image to 640px wide and 120px high
            $manipulator_640 = $manipulator_640->resample(640, 120);    

            // saving file to uploads folder
            $manipulator_640->save("../file_upload_img/header/" . $random_file_name . $_FILES["Filedata"]["name"]);

            $width_640  = $manipulator_640->getWidth();
            $height_640 = $manipulator_640->getHeight();
            $centreX_640 = round($width_640 / 2);
            $centreY_640 = round($height_640 / 2);
            // our dimensions will be 640x120
            $x1_640 = $centreX_640 - 320; // 640 / 2
            $y1_640 = $centreY_640 - 60; // 120 / 2

            $x2_640 = $centreX_640 + 320; // 640 / 2
            $y2_640 = $centreY_640 + 60; // 120 / 2

            // center cropping to 640x120
            $newImage_640 = $manipulator_640->crop($x1_640, $y1_640, $x2_640, $y2_640);
            // saving file to uploads folder
            $manipulator_640->save("../file_upload_img/header/" . $random_file_name . $_FILES["Filedata"]["name"]);
            /*
            *****************
            */
        }
    }
}
else {
    echo "Invalid file";
}

$data=ob_get_clean();

编辑 2

我已将用户@matewka 的代码添加到我的PHP 中。我用包含的旋转代码编辑了我的 PHP。代码根本不旋转图像。

【问题讨论】:

  • 我猜你的手机正在旋转纵向方向拍摄的图像的预览不是图像本身。许多其他设备也可能能够做到这一点。因此,您总是在查看正确旋转的图像,但是当您将其推送到 ImageManipulator 时,它不会注意图像是否已旋转,因为此信息保存在元数据中的某个位置。您需要寻找一些表明图像是否旋转的元数据。这是我的猜测。
  • 嗯,上传的图片是在我的服务器上旋转的,所以它确实会旋转图片本身。
  • 你怎么知道它是旋转的?你如何预览它?
  • 我的手机拍摄了图像,看起来很正常。你知道用手机在人像模式下拍照是什么感觉吗?这就是我所看到的。但是当我看服务器上的照片时(我刚才拍的照片是直接上传到服务器并裁剪的),已经被裁剪了,而且还向左旋转了90度。所以预览看起来还可以,但是服务器上的照片是旋转的。
  • @matewka 我刚刚意识到手机本身在我拍摄后已经旋转了图像。如何旋转手机最近拍摄的图像,使其看起来正常?

标签: php


【解决方案1】:

关于您最近的评论:

我刚拍完才发现手机本身已经旋转​​了图片。 如何旋转手机最近拍摄的图像,使其看起来正常?

要在 PHP 中旋转图像,您可以使用 imagerotate 函数。因此,在您裁剪图像并将其保存到 $newImage 变量之后,立即进行这些操作:

$imageResource = $newImage->getResource();
$angle = '90'; // in degrees
$fileName = "../file_upload_img/43/" . $random_file_name . $_FILES["Filedata"]["name"];
$rotatedImage = imagerotate($imageResource, $angle);
imagejpeg($rotatedImage, $fileName, 95);

【讨论】:

  • 谢谢,但我必须在裁剪之前旋转图像,而不是在裁剪之后。我将图像裁剪为 600X450 的大小。如果我在裁剪后裁剪和旋转,尺寸将变为 450X600。那么如何在裁剪和旋转之前修改您的代码以旋转?
  • @user3608176,有什么区别?假设您的原始图像是 1200X900。如果旋转它,它将变为 900X1200。然后你裁剪它,你得到 450X600 - 与其他方式相同。这两个操作是可转换的。无论您以什么顺序执行它们,结果都将始终相同。
  • 哦,我明白了。抱歉 :) 谢谢,我马上试试看是否有效。
【解决方案2】:

使用exif_read_data修复图像方向

function orientation($path){
    $image = imagecreatefromjpeg($path);
    $exif = exif_read_data($path);
    $orientation = $exif['COMPUTED']['Orientation'];
    switch ($orientation) {
        case 3:
            $image = imagerotate($image, 180, 0);
            break;
        case 6:
            $image = imagerotate($image, -90, 0);
            break;
        case 8:
            $image = imagerotate($image, 90, 0);
            break;
    }
    imagejpeg($image, $path);
}

可能会检测到 4 个可能的方向[Here]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-09
    • 1970-01-01
    • 2015-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-14
    • 2013-04-05
    相关资源
    最近更新 更多