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 相关文章推荐
常用python数据类型转换函数总结
Mar 11 Python
Python中的yield浅析
Jun 16 Python
Python采集腾讯新闻实例
Jul 10 Python
python基础入门学习笔记(Python环境搭建)
Jan 13 Python
Pyhton中单行和多行注释的使用方法及规范
Oct 11 Python
Python中的支持向量机SVM的使用(附实例代码)
Jun 26 Python
Python中 CSV格式清洗与转换的实例代码
Aug 29 Python
python小项目之五子棋游戏
Dec 26 Python
PyQt5 控件字体样式等设置的实现
May 13 Python
简单的Python人脸识别系统
Jul 14 Python
python安装第三方库如xlrd的方法
Oct 31 Python
如何用python绘制雷达图
Apr 24 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不用正则验证真假身份证
2013/11/06 PHP
php使用正则表达式提取字符串中尖括号、小括号、中括号、大括号中的字符串
2020/04/05 PHP
php中 $$str 中 "$$" 的详解
2015/07/06 PHP
php实现将二维关联数组转换成字符串的方法详解
2017/07/31 PHP
解决windows上php xdebug 无法调试的问题
2020/02/19 PHP
理解JavaScript中的事件
2006/09/23 Javascript
弹出广告特效(一个IP只弹出一次)的代码
2007/07/27 Javascript
Web开发之JavaScript
2012/03/29 Javascript
JS子父窗口互相操作取值赋值的方法介绍
2013/05/11 Javascript
jquery ready(fn)事件使用介绍
2013/08/21 Javascript
不同编码的页面表单数据乱码问题解决方法
2015/02/15 Javascript
jQuery获得document和window对象宽度和高度的方法
2015/03/25 Javascript
JS/Jquery判断对象为空的方法
2015/06/11 Javascript
Javascript显示和隐藏ul列表的方法
2015/07/15 Javascript
老生常谈JavaScript 函数表达式
2016/09/01 Javascript
详解在vue-cli中引用jQuery、bootstrap以及使用sass、less编写css
2017/11/08 jQuery
微信小程序车牌号码模拟键盘输入功能的实现代码
2018/11/11 Javascript
JS实现移动端双指缩放和旋转方法
2019/12/13 Javascript
JavaScript将数组转换为链表的方法
2020/02/16 Javascript
[05:09]第二届DOTA2亚洲邀请赛决赛日比赛集锦:iG 3:0 OG夺冠
2017/04/05 DOTA
python得到windows自启动列表的方法
2018/10/14 Python
Python3 串口接收与发送16进制数据包的实例
2019/06/12 Python
eBay法国购物网站:eBay.fr
2017/10/21 全球购物
马来西亚综合购物网站:Lazada马来西亚
2018/06/05 全球购物
意大利奢侈品零售商:ilDuomo Novara
2019/09/11 全球购物
意大利在线眼镜精品店:Ottica Lipari
2019/11/11 全球购物
村优秀党员事迹材料
2014/01/15 职场文书
优秀实习生感言
2014/03/01 职场文书
党员学习群众路线教育实践活动对照检查材料
2014/09/23 职场文书
承租经营合作者协议书
2014/10/01 职场文书
秦兵马俑导游词
2015/02/02 职场文书
幼儿园小班开学寄语(2016秋季)
2015/12/03 职场文书
2019通用版劳动合同范本!
2019/07/11 职场文书
tensorboard 可视化之localhost:6006不显示的解决方案
2021/05/22 Python
MySQL数据库索引的最左匹配原则
2021/11/20 MySQL
原生JS实现分页
2022/04/19 Javascript