Hướng dẫn dùng exif data trong PHP

answer

63

Tài liệu cho imagerotate đề cập đến một loại khác cho tham số đầu tiên mà bạn sử dụng:

Tài nguyên hình ảnh, được trả về bởi một trong các hàm tạo hình ảnh, chẳng hạn như imageecreatetruecolor [].

Đây là một ví dụ nhỏ để sử dụng chức năng này:

function resample[$jpgFile, $thumbFile, $width, $orientation] {
    // Get new dimensions
    list[$width_orig, $height_orig] = getimagesize[$jpgFile];
    $height = [int] [[$width / $width_orig] * $height_orig];
    // Resample
    $image_p = imagecreatetruecolor[$width, $height];
    $image   = imagecreatefromjpeg[$jpgFile];
    imagecopyresampled[$image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig];
    // Fix Orientation
    switch[$orientation] {
        case 3:
            $image_p = imagerotate[$image_p, 180, 0];
            break;
        case 6:
            $image_p = imagerotate[$image_p, -90, 0];
            break;
        case 8:
            $image_p = imagerotate[$image_p, 90, 0];
            break;
    }
    // Output
    imagejpeg[$image_p, $thumbFile, 90];
}

63 hữu ích 1 bình luận chia sẻ

answer

76

Dựa trên mã của Daniel, tôi đã viết một hàm đơn giản là xoay một hình ảnh nếu cần thiết mà không cần lấy mẫu lại.

GD

function image_fix_orientation[&$image, $filename] {
    $exif = exif_read_data[$filename];

    if [!empty[$exif['Orientation']]] {
        switch [$exif['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;
        }
    }
}

Phiên bản một dòng [GD]

function image_fix_orientation[&$image, $filename] {
    $image = imagerotate[$image, array_values[[0, 0, 0, 180, 0, 0, -90, 0, 90]][@exif_read_data[$filename]['Orientation'] ?: 0], 0];
}

ImageMagick

function image_fix_orientation[$image] {
    if [method_exists[$image, 'getImageProperty']] {
        $orientation = $image->getImageProperty['exif:Orientation'];
    } else {
        $filename = $image->getImageFilename[];

        if [empty[$filename]] {
            $filename = 'data://image/jpeg;base64,' . base64_encode[$image->getImageBlob[]];
        }

        $exif = exif_read_data[$filename];
        $orientation = isset[$exif['Orientation']] ? $exif['Orientation'] : null;
    }

    if [!empty[$orientation]] {
        switch [$orientation] {
            case 3:
                $image->rotateImage['#000000', 180];
                break;

            case 6:
                $image->rotateImage['#000000', 90];
                break;

            case 8:
                $image->rotateImage['#000000', -90];
                break;
        }
    }
}

76 hữu ích 5 bình luận chia sẻ

answer

43

Chức năng đơn giản hơn cho những người tải lên hình ảnh, nó chỉ tự động xoay vòng nếu cần.

function image_fix_orientation[$filename] {
    $exif = exif_read_data[$filename];
    if [!empty[$exif['Orientation']]] {
        $image = imagecreatefromjpeg[$filename];
        switch [$exif['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, $filename, 90];
    }
}

43 hữu ích 4 bình luận chia sẻ

answer

13

Tại sao không ai xem xét các trường hợp được nhân đôi 2,4,5,7? Còn 4 trường hợp nữa ở đất định hướng exif:

Đây là một giải pháp hoàn chỉnh lấy tên tệp:

function __image_orientate[$source, $quality = 90, $destination = null]
{
    if [$destination === null] {
        $destination = $source;
    }
    $info = getimagesize[$source];
    if [$info['mime'] === 'image/jpeg'] {
        $exif = exif_read_data[$source];
        if [!empty[$exif['Orientation']] && in_array[$exif['Orientation'], [2, 3, 4, 5, 6, 7, 8]]] {
            $image = imagecreatefromjpeg[$source];
            if [in_array[$exif['Orientation'], [3, 4]]] {
                $image = imagerotate[$image, 180, 0];
            }
            if [in_array[$exif['Orientation'], [5, 6]]] {
                $image = imagerotate[$image, -90, 0];
            }
            if [in_array[$exif['Orientation'], [7, 8]]] {
                $image = imagerotate[$image, 90, 0];
            }
            if [in_array[$exif['Orientation'], [2, 5, 7, 4]]] {
                imageflip[$image, IMG_FLIP_HORIZONTAL];
            }
            imagejpeg[$image, $destination, $quality];
        }
    }
    return true;
}

13 hữu ích 1 bình luận chia sẻ

answer

7

Chỉ trong trường hợp ai đó bắt gặp điều này. Từ những gì tôi có thể đưa ra một số câu lệnh switch ở trên là sai.

Dựa trên thông tin ở đây , nó phải là:

switch [$exif['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;
} 

7 hữu ích 0 bình luận chia sẻ

answer

6

Có lẽ điều đáng nói là nếu bạn đang sử dụng ImageMagick từ dòng lệnh, bạn có thể sử dụng tùy chọn -auto-orient sẽ tự động xoay hình ảnh dựa trên dữ liệu định hướng EXIF ​​hiện có.

convert -auto-orient /tmp/uploadedImage.jpg /save/to/path/image.jpg

Xin lưu ý: Nếu dữ liệu EXIF ​​bị loại bỏ trước quá trình, nó sẽ không hoạt động như mô tả.

6 hữu ích 0 bình luận chia sẻ

answer

2

Ở đây tôi sẽ giải thích toàn bộ vấn đề, tôi sử dụng Laravel và sử dụng Gói can thiệp hình ảnh.

Trước hết, tôi lấy hình ảnh của mình và gửi nó đến một chức năng khác của tôi để thay đổi kích thước và một số chức năng khác, nếu chúng tôi không cần điều này, bạn có thể bỏ qua ...

Lấy tệp bằng một phương thức trong bộ điều khiển của tôi,

 public  function getImageFile[Request $request]{
    $image = $request->image;
    $this->imageUpload[$image];
}

Bây giờ, tôi gửi nó để thay đổi kích thước và lấy tên hình ảnh và phần mở rộng ...

public function  imageUpload[$file]{
    ini_set['memory_limit', '-1'];
    $directory = 'uploads/';
    $name = str_replace[[" ", "."], "_", $file->getClientOriginalName[]] . "_";
    $file_name = $name . time[] . rand[1111, 9999] . '.' . $file->getClientOriginalExtension[];
    //path set
    $img_url = $directory.$file_name;
    list[$width, $height] = getimagesize[$file];
    $h = [$height/$width]*600;
    Image::make[$file]->resize[600, $h]->save[public_path[$img_url]];
    $this->image_fix_orientation[$file,$img_url];
    return $img_url;
}

Bây giờ tôi gọi chức năng định hướng hình ảnh của mình,

 public function image_fix_orientation[$file,$img_url ] {
    $data = Image::make[$file]->exif[];
    if [!empty[$data['Orientation']]] {
        $image = imagecreatefromjpeg[$file];
        switch [$data['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, $img_url, 90];
    }

}

Và đó là tất cả...

2 hữu ích 0 bình luận chia sẻ

answer

2

Đây là hàm PHP 7 của tôi được lấy cảm hứng từ @ user462990:

/**
 * @param string $filePath
 *
 * @return resource|null
 */
function rotateImageByExifOrientation[string $filePath]
{
    $result = null;

    $exif = exif_read_data[$filePath];
    if [!empty[$exif['Orientation']]] {
        $image = imagecreatefromjpeg[$filePath];
        if [is_resource[$image]] {
            switch [$exif['Orientation']] {
                case 3:
                    $result = imagerotate[$image, 180, 0];
                    break;

                case 6:
                    $result = imagerotate[$image, -90, 0];
                    break;

                case 8:
                    $result = imagerotate[$image, 90, 0];
                    break;
            }
        }
    }

    return $result;
}

sử dụng:

    $rotatedFile = rotateImageByExifOrientation[$absoluteFilePath];
    if [is_resource[$rotatedFile]] {
        imagejpeg[$rotatedFile, $absoluteFilePath, 100];
    }

2 hữu ích 0 bình luận chia sẻ

answer

1

Tôi không thích kết hợp với một bộ giá trị định hướng khác, nhưng theo kinh nghiệm của tôi khi sử dụng bất kỳ giá trị nào được liệt kê ở trên, tôi luôn kết thúc với hình ảnh lộn ngược khi tải lên ảnh chụp hướng dọc trực tiếp từ iPhone. Đây là tuyên bố chuyển đổi mà tôi đã kết thúc.

switch [$exif['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;
    }

1 hữu ích 0 bình luận chia sẻ

answer

1

jhead -autorot jpegfile.jpg

Cũng là một cách hữu ích để tiếp cận điều này.

jhead là một chương trình tiêu chuẩn trong Linux [sử dụng 'sudo apt-get install jhead' để cài đặt], tùy chọn này xem xét hướng và xoay hình ảnh một cách chính xác và không mất mát chỉ khi nó yêu cầu. Sau đó, nó cũng cập nhật dữ liệu EXIF ​​một cách chính xác.

Bằng cách này, bạn có thể xử lý một jpeg [hoặc nhiều jpeg trong một thư mục] theo cách một chiều đơn giản để khắc phục các sự cố xoay vòng vĩnh viễn.

Ví dụ: jhead -autorot * .jpg sẽ sửa toàn bộ thư mục ảnh jpeg theo cách OP yêu cầu trong câu hỏi ban đầu.

Mặc dù nó không phải là PHP về mặt kỹ thuật, tôi đã đọc luồng này và sau đó sử dụng đề xuất jhead của tôi thay thế, được gọi từ lệnh gọi hệ thống PHP [] để đạt được kết quả mà tôi đã đạt được sau đó trùng hợp với OP: để xoay hình ảnh nên bất kỳ phần mềm nào [như 'fbi 'trong Raspbian] có thể hiển thị chúng một cách chính xác.

Vì vậy, tôi nghĩ những người khác có thể được lợi khi biết jhead giải quyết vấn đề này dễ dàng như thế nào và chỉ đăng thông tin ở đây với mục đích cung cấp thông tin - bởi vì chưa ai đề cập đến nó trước đây.

1 hữu ích 1 bình luận chia sẻ

answer

1

Tôi cũng đã sử dụng orientate[]Can thiệp biểu mẫu và nó hoạt động hoàn hảo.

    $image_resize = Image::make[$request->file['photo']];
    $image_resize->resize[1600, null,function [$constraint]
    {
        $constraint->aspectRatio[];
    }];
    $filename = $this->checkFilename[];

    $image_resize->orientate[]->save[$this->photo_path.$filename,80];

1 hữu ích 0 bình luận chia sẻ

answer

-1

Hình ảnh Can thiệp có một phương pháp orientate[].

$img = Image::make['foo.jpg']->orientate[];

-1 hữu ích 0 bình luận chia sẻ

Chủ Đề