• Python实现图片长宽比例缩放和填充


    图片的大小(KB)也可以更改, 但是某些格式不太好操作, 我自己没发现啥比较好的办法,  所以暂时是放弃这一部分

    PNG格式和JPG格式的区别应该就是图层吧, 导致对PNG更改大小(KB) 做不到我想要的效果, 这些我不是很专业, 所以也不太清楚

      1 '''
      2  : 一个缩略图程序, 不需要的部分可以去掉
      3  : 主要实现了尺寸(长宽)和大小(KB)的缩小
      4 '''
      5 import cv2
      6 import os.path
      7 from PIL import Image
      8 from psd_tools import PSDImage
      9 
     10 
     11 class ChangeSize:
     12 
     13     def __init__(self, out_width, out_height, start_path, output_path, limit_size=100):
     14         '''
     15         :param start_path:  输入图片地址
     16         :param limit_size:  输出图片大小(KB)
     17         :param out_   输出图片宽度
     18         :param out_height:  输出图片高度
     19         '''
     20         self.out_width = out_width
     21         self.out_height = out_height
     22         self.limit_size = limit_size
     23         self.start_path = start_path
     24         self.output_path = output_path
     25         print("start_path: ", self.start_path)
     26         print("output_path: ", self.output_path)
     27 
     28     def get_image(self):
     29         self.suffix = self.start_path.rsplit("\", 1)[-1].rsplit(".", 1)[-1]
     30 
     31         if self.suffix == "exr":                                # 如果是exr, 单独处理
     32             self.tmp_path = mk_tmp_dir()                        # 创建临时文件夹
     33             self.temp_exr = self.tmp_path + "/temp_exr.hdr"     # 先转换成hdr
     34             img_read = cv2.imread(self.start_path, cv2.IMREAD_UNCHANGED)
     35             cv2.imwrite(self.temp_exr, img_read)
     36             return self.get_temp_obj()
     37         elif self.suffix == "psd":
     38             self.tmp_path = mk_tmp_dir()
     39             self.temp_psd = self.tmp_path + "/temp_psd.png"
     40             psd = PSDImage.open(self.start_path)
     41             psd.compose().save(self.temp_psd)
     42             return self.get_temp_obj()
     43         else:                                                   # 其他格式图片正常处理
     44             img_read = cv2.imread(self.start_path)
     45             if img_read is None:
     46                 print("---Read Img Failed---")
     47             else:
     48                 print("缩略图程序读取图片成功")
     49                 return img_read
     50 
     51     def get_temp_obj(self):
     52         '''
     53         用于需要转换格式的中转函数. exr, psd 等图片不能直接转换格式, 需要中转格式
     54         :return: cv2 img Object
     55         '''
     56         if self.suffix == "exr":
     57             img_read = cv2.imread(self.temp_exr)
     58             return img_read
     59         # if self.suffix == "psd":
     60         #     img_read = cv2.imread(self.temp_psd)
     61         #     return img_read
     62 
     63     def get_resize_img(self, img):
     64         '''
     65         在这里转换尺寸, 保留原来尺寸比
     66         :param img: cv2.img_Object
     67         '''
     68         size = img.shape
     69         h, w = size[0], size[1]
     70         print(w, h)
     71 
     72         if h == w:
     73             longest = h
     74             scale = longest / float(self.out_height)
     75             new_h, new_w = int(h / scale), int(w / scale)
     76             print(new_w, new_h)
     77             resize_img = self.fill_blank(img=img, new_w=new_w, new_h=new_h)
     78             return resize_img
     79         elif w > h:
     80             longest = w
     81             scale = longest / float(self.out_width)
     82             new_h, new_w = int(h / scale), int(w / scale)
     83             if new_h > self.out_height:
     84                 longest1 = h
     85                 scale1 = longest1 / float(self.out_height)
     86                 new_h_1, new_w_1 = int(h / scale1), int(w / scale1)
     87                 resize_img = self.fill_blank(img=img, new_w=new_w_1, new_h=new_h_1)
     88                 return resize_img
     89             resize_img = self.fill_blank(img=img, new_w=new_w, new_h=new_h)     # 填充空白部分为黑色
     90             return resize_img
     91 
     92         elif h > w:
     93             longest = h
     94             scale = longest / float(self.out_height)
     95             new_h, new_w = int(h / scale), int(w / scale)
     96             print(new_w, new_h)
     97             if new_w > self.out_
     98                 longest1 = w
     99                 scale1 = longest1 / float(self.out_width)
    100                 new_h_1, new_w_1 = int(h / scale1), int(w / scale1)
    101                 resize_img = self.fill_blank(img=img, new_w=new_w_1, new_h=new_h_1)
    102                 return resize_img
    103             resize_img = self.fill_blank(img=img, new_w=new_w, new_h=new_h)
    104             return resize_img
    105         else:
    106             print("---未知错误---")
    107 
    108     def fill_blank(self, img, new_w, new_h):
    109         '''
    110         :param img:     拿到cv2.imread() 返回的对象
    111         :param new_w:   未补空白的时的宽度
    112         :param new_h:   未补空白的时的高度
    113         :return:        返回补空白后的对象(该对象用来写入)
    114         '''
    115         resize_img1 = cv2.resize(img, (new_w, new_h))
    116         if new_w % 2 != 0 and new_h % 2 == 0:
    117             top, bottom, left, right = (self.out_height - new_h) / 2, (self.out_height - new_h) / 2, (
    118                     self.out_width - new_w) / 2 + 1, (self.out_width - new_w) / 2
    119         elif new_h % 2 != 0 and new_w % 2 == 0:
    120             top, bottom, left, right = (self.out_height - new_h) / 2 + 1, (self.out_height - new_h) / 2, (
    121                     self.out_width - new_w) / 2, (self.out_width - new_w) / 2
    122         elif new_h % 2 == 0 and new_w % 2 == 0:
    123             top, bottom, left, right = (self.out_height - new_h) / 2, (self.out_height - new_h) / 2, (self.out_width - new_w) / 2, (
    124                     self.out_width - new_w) / 2
    125         else:
    126             top, bottom, left, right = (self.out_height - new_h) / 2 + 1, (self.out_height - new_h) / 2, (
    127                     self.out_width - new_w) / 2 + 1, (self.out_width - new_w) / 2
    128         resize_img = cv2.copyMakeBorder(resize_img1, int(top), int(bottom), int(left), int(right), cv2.BORDER_CONSTANT,
    129                                         value=[0, 0, 0])
    130         # 从图像边界向上,下,左,右扩的像素数目
    131         # cv2.imwrite("img_out/finally_w.jpg", pad_img)
    132         return resize_img
    133 
    134     def limit_size(self, quality=80, step=5):
    135         """
    136         图片尺寸压缩到指定大小(KB), 注意, 有些图片格式压缩不了. 此方法暂时废弃
    137         :param step: 每次调整的压缩比率
    138         :param quality: 初始压缩比率
    139         :return: 压缩文件地址,压缩文件大小
    140         """
    141         file_size = os.path.getsize(self.tmp_file) / 1024
    142         print("size: ", file_size, "limit_size: ", self.limit_size)
    143         im = Image.open(self.tmp_file)
    144         if file_size < self.limit_size:
    145             im.save(self.output_file)
    146             return
    147         while file_size > self.limit_size:
    148             im.save(self.output_file, quality=quality)
    149             if quality - step < 0:
    150                 break
    151             quality -= step
    152         o_size = os.path.getsize(self.output_file) / 1024
    153         return o_size
    154 
    155     def main(self):
    156         img_obj = self.get_image()
    157         img_obj1 = self.get_resize_img(img_obj)
    158         cv2.imwrite(output, img_obj1)
    159         # cv2.imwrite(output, img_read, [cv2.IMWRITE_PNG_COMPRESSION, 1])
    160         print("---缩略图程序完成---")
    161 
    162 
    163 def rm_tmp_dir(start_path=None):
    164     '''
    165     移除临时文件夹
    166     '''
    167     savePath = current_path = os.getcwd()
    168     tmp_path = savePath + "/tmp"
    169     try:
    170         import shutil
    171         if os.path.exists(tmp_path):  # 如果文件存在
    172             print("临时文件夹存在, 开始删除")
    173             shutil.rmtree(tmp_path, ignore_errors=True)
    174         else:
    175             print('no such file:%s' % tmp_path)  # 则返回文件不存在
    176     except Exception as rm_tmpdir_error:
    177         print(rm_tmpdir_error)
    178 
    179 
    180 def mk_tmp_dir():
    181     current_path = os.getcwd()
    182     tmp_path = os.path.join(current_path, "tmp")
    183     if not os.path.exists(tmp_path):
    184         os.mkdir(tmp_path)
    185     return tmp_path
    186 
    187 
    188 if __name__ == "__main__":
    189     path = r"C:UsersAdministratorDesktopupdateenjinecgrender	img (8).jpg"
    190     output = os.path.join(os.getcwd(), "output.png")
    191     handle = ChangeSize(480, 320, path, output)
    192     handle.main()
  • 相关阅读:
    Lock wait timeout exceeded; try restarting transaction linux设置mysql innodb_lock_wait_timeout
    用NaviCat创建存储过程批量添加测试数据
    mysql存储过程语法及实例
    mysql中迅速插入百万条测试数据的方法
    mysql学习之通过文件创建数据库以及添加数据
    有用的网站集合
    VMware Workstation虚拟磁盘文件备份或移植
    CoreData修改了数据模型报错 The model used to open the store is incompatible with the one used to create the store
    iOS中自定义UITableViewCell的用法
    golang make()的第三个参数
  • 原文地址:https://www.cnblogs.com/MasonHu/p/13930230.html
Copyright © 2020-2023  润新知