纯PIL

import cv2
from PIL import Image


def auto_fix_image_rotation(img_path):
    """
    检测图片的Windows旋转元数据,若有旋转则旋转后覆盖原图,无旋转则不操作
    :param img_path: 图片文件路径(支持JPG/PNG等常见格式)
    :return: bool - True表示图片有旋转并已修复,False表示无旋转/无需修复,None表示处理失败
    """
    rotation_angle = 0  # 旋转角度

    img_pil = Image.open(img_path)
    exif_data = img_pil._getexif()

    if exif_data and 274 in exif_data:
        orientation = exif_data[274]
        angle_map = {
            1: 0,  # 正常(无需旋转)
            2: 0,  # 水平翻转(暂不处理)
            3: 180,  # 旋转180°
            4: 180,  # 垂直翻转+180°(按180°处理)
            5: 90,  # 顺时针90°+水平翻转(按90°处理)
            6: 90,  # 顺时针90°(最常见)
            7: 270,  # 逆时针90°+水平翻转(按270°处理)
            8: 270  # 逆时针90°
        }
        rotation_angle = angle_map.get(orientation, 0)

    if rotation_angle == 0:
        print(f"图片无旋转,无需处理 → {img_path}")
        return False

    img_cv2 = cv2.imread(img_path)
    if rotation_angle == 90:
        rotated_img = cv2.rotate(img_cv2, cv2.ROTATE_90_CLOCKWISE)

    elif rotation_angle == 180:
        rotated_img = cv2.rotate(img_cv2, cv2.ROTATE_180)

    else:  # 270°
        rotated_img = cv2.rotate(img_cv2, cv2.ROTATE_90_COUNTERCLOCKWISE)

    cv2.imwrite(img_path, rotated_img)
    print(f'图片旋转{rotation_angle}°,保存{img_path}成功')


# ===================== 测试示例 =====================
if __name__ == "__main__":
    test_img_path = r'C:\Users\1\Desktop\123.jpg'
    auto_fix_image_rotation(test_img_path)

更稳定的旋转方式

import cv2
import piexif # piexif==1.1.3

class AutoImageRotation(object):
    '''图片伪旋转问题'''

    def __init__(self, image_path, save_path=None):
        self.image_path = image_path # 待处理的图片路径
        self.save_path = save_path # 保存路径 不传则覆盖原图

    def get_exif(self) -> int:
        '''查询图片exif信息并返回旋转角度'''
        exif_dict = piexif.load(self.image_path)
        orientation = exif_dict["0th"].get(piexif.ImageIFD.Orientation, 1)
        angle_map = {
            1: 0,  # 正常(无需旋转)
            2: 0,  # 水平翻转(暂不处理)
            3: 180,  # 旋转180°
            4: 180,  # 垂直翻转+180°(按180°处理)
            5: 90,  # 顺时针90°+水平翻转(按90°处理)
            6: 90,  # 顺时针90°(最常见)
            7: 270,  # 逆时针90°+水平翻转(按270°处理)
            8: 270  # 逆时针90°
        }
        rotation_angle = angle_map.get(orientation, 0)
        return rotation_angle

    def start(self):
        '''开始检测并自动旋转'''
        rotation_angle = self.get_exif() # 提取旋转角度
        if rotation_angle == 0: # 图片无旋转
            return False

        image = cv2.imread(self.image_path)
        if rotation_angle == 90:
            image = cv2.rotate(image, cv2.ROTATE_90_CLOCKWISE)

        elif rotation_angle == 180:
            image = cv2.rotate(image, cv2.ROTATE_180)

        else:  # 270°
            image = cv2.rotate(image, cv2.ROTATE_90_COUNTERCLOCKWISE)

        if self.save_path:  # 保存路径是否为空
            cv2.imwrite(self.save_path, image)
            print(f'图片旋转:【{rotation_angle}】°,保存->【{self.save_path}】')
        else:
            cv2.imwrite(self.image_path, image)
            print(f'图片旋转:【{rotation_angle}】°,保存->【{self.image_path}】')

    def __call__(self, *args, **kwargs):
        self.start()


if __name__ == "__main__":
    test_img_path = r'C:\Users\1\Desktop\12.jpg'
    a = AutoImageRotation(test_img_path)
    a.start()
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐