python+pyqt5实现图片批量缩放工具


Posted in Python onMarch 18, 2019

批量修改图片大小好像用PS也可以,不过我不会,程序猿就用程序来解决。
这段时间学了下Python,很强大,之前一些不知道怎么处理的东西在Python里面都能找到解决方法。

工具界面如下图

python+pyqt5实现图片批量缩放工具

这个工具需要用到第三方库 Pillow 和 Pyqt5,可通过命令行安装。

pip install pillow
pip install pyqt5

代码:

#!-*-coding:utf-8-*-

from PIL import Image

import hashlib, os, sys
from PyQt5.QtGui import QFont, QIcon
from PyQt5.QtWidgets import (QFileDialog, QMessageBox,
  QGridLayout, QLineEdit, QTextEdit, QLabel, QWidget, QToolTip, 
  QPushButton, QApplication, QInputDialog)
from PyQt5.QtCore import QCoreApplication


def makedir(path):
  if not os.path.exists(path):
    os.mkdir(path)


def image_resize(image_path, scale):
  #获得新文件名称
  out_path = os.path.splitext(image_path)[0] + "_after" + os.path.splitext(image_path)[-1]
  with Image.open( image_path ) as im:
    width = int(im.size[0]*scale)
    height = int(im.size[1]*scale)
    #resize 设置新尺寸
    out = im.resize( (width, height) )
    out.save(out_path)

def folder_resize(folder_path, scale):
  dst_files = []
  files = os.listdir( folder_path )
  for file in files:
    ext = os.path.splitext(file)[-1]
    #只支持jpg或png文件
    if ext == ".jpg" or ext == ".png":
      dst_files.append(file)

  #输出路径
  out_folder = os.path.join(folder_path, "after")
  makedir(out_folder)

  for item in dst_files:
    try:
      op = os.path.join( out_folder, item )
      with Image.open( os.path.join(folder_path, item) ) as im:
        width = int(im.size[0]*scale)
        height = int(im.size[1]*scale)
        out = im.resize( (width, height) )
        out.save(op)
    except FileNotFoundError:
      print("file not found " + item)


class MainBody(QWidget):
  def __init__(self):
    super(MainBody, self).__init__()
    self.init()

    self.m_scale = 1.0
    self.m_width = 0
    self.m_height = 0

  def init(self):
    grid = QGridLayout()
    self.setLayout(grid)
    grid.setSpacing(10)

    self.m_tedit = QTextEdit()
    self.m_tedit.setToolTip( u'可以拖拽文件到这里来' )
    grid.addWidget(self.m_tedit, 1, 0, 4, 3)

    self.m_scale_set_btn = QPushButton( u"设置缩放值" )
    self.m_scale_set_btn.clicked.connect( self.set_scale_func )
    grid.addWidget( self.m_scale_set_btn, 1, 3 )
    self.m_scale_label = QLabel( "1.0" )
    grid.addWidget( self.m_scale_label, 2, 3 )

    self.m_height_set_btn = QPushButton( u"设置高度" )
    self.m_height_set_btn.clicked.connect( self.set_height_func )
    grid.addWidget( self.m_height_set_btn, 3, 3 )
    self.m_height_label = QLabel( "0" )
    grid.addWidget( self.m_height_label, 4, 3 )

    self.m_width_set_btn = QPushButton( u"设置宽度" )
    self.m_width_set_btn.clicked.connect( self.set_width_func )
    grid.addWidget( self.m_width_set_btn, 5, 3 )
    self.m_width_label = QLabel( "0" )
    grid.addWidget( self.m_width_label, 6, 3 )

    self.m_file_btn = QPushButton(u'选择文件')
    self.m_file_btn.clicked.connect( self.file_func )

    self.m_folder_btn = QPushButton(u'选择文件夹')
    self.m_folder_btn.clicked.connect( self.folder_func )

    self.m_generate_btn = QPushButton(u'处理')
    self.m_generate_btn.clicked.connect( self.generate_func )

    self.m_clear_btn = QPushButton(u'清空')
    self.m_clear_btn.clicked.connect( self.clear_func )

    grid.addWidget(self.m_file_btn, 5, 0)
    grid.addWidget(self.m_folder_btn, 5, 1)
    grid.addWidget(self.m_generate_btn, 6, 0)
    grid.addWidget(self.m_clear_btn, 6, 1)

    self.setGeometry(300,300,300,200)
    self.setWindowTitle(u"批量图片缩放")
    self.setWindowIcon(QIcon('icon.png'))
    self.show()

  #按照输入的缩放值进行缩放
  def set_scale_func(self):
    text, ok = QInputDialog.getText( self, 'Input Scale', u'输入缩放值' )
    if ok:
      try:
        scale = float( text )
      except ValueError:
        QMessageBox.warning( self, u"设置缩放值", u"输入错误" )
      else:
        self.m_scale = scale
        self.refresh_setting(0)

  #根据高度的缩放比例等比例缩放
  def set_height_func(self):
    text, ok = QInputDialog.getText( self, 'Input Height', u'输入高度' )
    if ok:
      try:
        height = int( text )
      except ValueError:
        QMessageBox.warning( self, u"设置高度", u"输入错误" )
      else:
        self.m_height = height
        self.refresh_setting(2)

  #根据宽度的缩放比例等比例缩放
  def set_width_func(self):
    text, ok = QInputDialog.getText( self, 'Input Width', u'输入宽度' )
    if ok:
      try:
        width = int( text )
      except ValueError:
        QMessageBox.warning( self, u"设置宽度", u"输入错误" )
      else:
        self.m_width = width
        self.refresh_setting(1)

  def file_func(self):
    filename, ok = QFileDialog.getOpenFileName(self, "Open File", "C:/Users/Administrator/Desktop", "JPG (*.jpg);;PNG (*.png)")
    if ok:        
      self.m_tedit.setText( filename )

      size = self.get_image_size( filename )
      s,w,h = self.get_current_setting()
      self.m_width = int(size[0]*s)
      self.m_height = int(size[1]*s)
      self.m_height_label.setText( str( self.m_height ) )
      self.m_width_label.setText( str( self.m_width ) )

  def folder_func(self):
    filename = QFileDialog.getExistingDirectory(self, "Open File", "C:/Users/Administrator/Desktop")
    self.m_tedit.setText( filename )


  def generate_func(self):
    path = self.get_image_path()
    if path == None or path == "":
      QMessageBox.warning( self, u"Error", u"未选择文件" )
      return
    elif os.path.exists(path) == False:
      QMessageBox.warning( self, u"Error", u"文件不存在" )
      return

    if os.path.isdir(path):
      folder_resize( path, self.m_scale )
    elif os.path.isfile(path):
      image_resize( path, self.m_scale )


  def clear_func(self):
    self.m_tedit.clear()
    self.m_width = 0
    self.m_height = 0
    self.m_width_label.setText("0")
    self.m_height_label.setText("0")

  def get_image_size(self, image_path):
    with Image.open(image_path) as im:
      return im.size

  def get_image_path(self):
    path = self.m_tedit.toPlainText()
    if path.startswith( 'file:///' ):
      path = path[8:]
    return path

  def get_current_setting(self):
    return self.m_scale, self.m_width, self.m_height

  def refresh_setting(self, kind):
    s, w, h = self.get_current_setting()
    p = self.get_image_path()
    if kind == 0:
      if p == None or p == "" or os.path.exists(p) == False or os.path.isdir(p) == True:
        w = 0
        h = 0
      else:
        size = self.get_image_size(p)
        w = size[0]*s
        h = size[1]*s

    elif kind == 1:
      if p == None or p == "" or os.path.exists(p) == False:
        QMessageBox.warning( self, u"Warning", u"请先选择文件" )
        return
      elif os.path.isdir(p) == True:
        QMessageBox.warning( self, u"Warning", u"文件夹不能设置宽度" )
        return

      size = self.get_image_size(p)
      w = int(w)
      s = w*1.0/size[0]
      h = int((w/size[0])*size[1])

    elif kind == 2:
      if p == None or p == "" or os.path.exists(p) == False:
        QMessageBox.warning( self, u"Warning", u"请先选择文件" )        
        return
      elif os.path.isdir(p) == True:
        QMessageBox.warning( self, u"Warning", u"文件夹不能设置高度" )
        return

      size = self.get_image_size(p)
      h = int(h)
      s = h*1.0/size[1]
      w = int((h/size[1])*size[0])

    self.m_width = int(w)
    self.m_height = int(h)
    self.m_scale = float(s)
    self.m_width_label.setText(str(self.m_width))
    self.m_height_label.setText(str(self.m_height))
    self.m_scale_label.setText(str(self.m_scale))



if __name__ == "__main__":
  app = QApplication(sys.argv)
  mb = MainBody()
  sys.exit( app.exec_() )

整个工具比较简陋,能用就好。有什么不正确的地方请指出。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python3基础之基本数据类型概述
Aug 13 Python
python使用calendar输出指定年份全年日历的方法
Apr 04 Python
快速了解python leveldb
Jan 18 Python
flask中使用蓝图将路由分开写在不同文件实例解析
Jan 19 Python
python如何把嵌套列表转变成普通列表
Mar 20 Python
python实现Virginia无密钥解密
Mar 20 Python
使用python分析统计自己微信朋友的信息
Jul 19 Python
给Python学习者的文件读写指南(含基础与进阶)
Jan 29 Python
python 按钮点击关闭窗口的实现
Mar 04 Python
python实现opencv+scoket网络实时图传
Mar 20 Python
Python中and和or如何使用
May 28 Python
基于logstash实现日志文件同步elasticsearch
Aug 06 Python
Python实现从SQL型数据库读写dataframe型数据的方法【基于pandas】
Mar 18 #Python
PyQt5实现简易计算器
May 30 #Python
Python实现简单层次聚类算法以及可视化
Mar 18 #Python
PyQt5实现简单数据标注工具
Mar 18 #Python
Python简单I/O操作示例
Mar 18 #Python
python实现简单图片物体标注工具
Mar 18 #Python
Python面向对象程序设计之类的定义与继承简单示例
Mar 18 #Python
You might like
浏览器关闭后,能继续执行的php函数(ignore_user_abort)
2012/08/01 PHP
PHP实现定时执行任务的方法
2014/10/05 PHP
php检测数组长度函数sizeof与count用法
2014/11/17 PHP
php实现SAE上使用storage上传与下载文件的方法
2015/06/29 PHP
PHP静态成员变量
2017/02/14 PHP
Yii框架布局文件的动态切换操作示例
2019/11/11 PHP
Laravel 框架控制器 Controller原理与用法实例分析
2020/04/14 PHP
js实现单击图片放大图片的方法
2015/02/17 Javascript
javascript密码强度校验代码(两种方法)
2015/08/10 Javascript
jQuery拖动元素并对元素进行重新排序
2015/12/30 Javascript
微信小程序  自定义创建详细介绍
2016/10/27 Javascript
JavaScript中的this/call/apply/bind的使用及区别
2020/03/06 Javascript
JavaScript onclick事件使用方法详解
2020/05/15 Javascript
js实现表格数据搜索
2020/08/09 Javascript
vue3.0 上手体验
2020/09/21 Javascript
[05:53]敌法师的金色冠名ID"BurNIng",是传说,是荣耀
2020/07/11 DOTA
Python爬取qq music中的音乐url及批量下载
2017/03/23 Python
python3实现抓取网页资源的 N 种方法
2017/05/02 Python
Python冲顶大会 快来答题!
2018/01/17 Python
利用nohup来开启python文件的方法
2019/01/14 Python
Django通过dwebsocket实现websocket的例子
2019/11/15 Python
如何基于Python实现自动扫雷
2020/01/06 Python
PyCharm汉化安装及永久激活详细教程(靠谱)
2020/01/16 Python
什么是python类属性
2020/06/10 Python
解决Pymongo insert时会自动添加_id的问题
2020/12/05 Python
手工制作的意大利太阳镜和光学元件:Illesteva
2019/01/19 全球购物
《桂林山水》教学反思
2014/02/08 职场文书
开学典礼决心书
2014/03/11 职场文书
副总经理岗位职责
2014/03/16 职场文书
购房意向书
2014/04/01 职场文书
模范教师事迹材料
2014/12/16 职场文书
会计工作能力自我评价
2015/03/05 职场文书
个人落户申请书怎么写?
2019/06/28 职场文书
springboot如何初始化执行sql语句
2021/06/22 Java/Android
Opencv实现二维直方图的计算及绘制
2021/07/21 Python
浅谈JavaScript浅拷贝和深拷贝
2021/11/07 Javascript