搜索

Python 教学

基本介绍

Python 学习导读 使用 Google Colab 使用 Anaconda 使用 Python 虚拟环境 Python 范例集锦

数据型别

变数 variable 变数 ( 全域、区域 ) 数字 number 文字与字串 string 文字与字串 ( 常用方法 ) 文字与字串 ( 格式化 ) 串列 list 串列 ( 常用方法 ) 元组/数组 tuple 字典 dictionary 集合 set

语法观念

缩排和注解 运算子 operator 逻辑判断 ( if、elif、else ) 逻辑判断 ( and 和 or ) 重复循环 ( for、while ) 例外处理 ( try、except ) 生成式 comprehension 对象类别 class 对象继承 inheritance 导入模组 import

函数操作

函数 function 匿名函数 lambda 递回 recursion 产生器 generator 装饰器 decorator 闭包 closure

内建函数&方法

输入与输出 数学计算 字串操作与转换 迭代对象转换 迭代对象操作 文件读写 ( open ) eval() 与 exec()

标准函数库&模组

随机数 random 数学 math 数学统计函数 statistics 时间与日期 datetime 时间处理 time 日历 calendar 使用正规表达式 re 文件操作 os 查找匹配文件 glob 压缩文件 zipfile 高阶文件操作 shutil 高效迭代器 itertools 容器数据型态 collections CSV 文件操作 JSON 文件操作 threading 多执行绪处理 concurrent.futures

网络爬虫

Python 网络爬虫导读 关于网络爬虫 破解反爬虫的方法 Requests 函数库 Beautiful Soup 函数库 Selenium 函数库 爬取 PTT 文章标题 自动下载 PTT 正妹图片 同时下载多张图片 同时下载多张宝可梦图片 爬取 CCTV 即时图像 爬取统一发票号码对奖 爬取空气质量指标 ( AQI ) 爬取气象预报 爬取现在天气 LINE Notify 雷达回波图 LINE Notify 即时地震信息 爬取台湾银行牌告汇率 爬取 Yahoo 股市即时股价 爬取 LINE TODAY 留言 批次下载 Pinterest 图片 登录 Mobile01 截图下载 Twitter 自动上传图文

网页服务与应用

Flask 函数库 使用 ngrok 服务 Google Cloud Functions 串接 Gmail 寄送电子邮件 读取 Google 试算表 写入 Google 试算表 上传 Google 云端硬盘 发送 LINE Notify 通知 使用 Dialogflow Dialogflow + Webhook 服务器串接 Dialogflow 串接 Firebase 数据库 (1) 串接 Firebase 数据库 (2) 串接 Firebase 数据库 (3) 使用 OpenAI ChatGPT ChatGPT + Firebase

LINE BOT 教学

LINE BOT 教学导读 ( 免程序 ) 建立 LINE 官方账号 ( 免程序 ) 主动推播消息 ( 免程序 ) 自动回复消息 ( 免程序 ) 建立图文选单 ( 免程序 ) 基本消息类型 建立 LINE Channel 设定 Colab 开发环境 建立并串接 Webhook 解析 LINE 的消息 自动回复消息 主动推播消息 建立图文选单 切换图文选单 发送样板消息 发送 Flex Message 使用 Requests 传送消息 使用 LINE URL Scheme 储存用户的图片或影片 串接 Email 传送图片或影片 串接 Google 云端硬盘 气象机器人 (1) 气象机器人 (2) 气象机器人 (3) 气象机器人 (4) 串接 Dialogflow (1) 串接 Dialogflow (2) 串接 Dialogflow (3) 串接 Dialogflow (4) 串接 OpenAI ChatGPT (1) 串接 OpenAI ChatGPT (2) 串接 OpenAI ChatGPT (3)

OpenCV 教学

OpenCV 教学导读 OpenCV 函数库 打开并显示图片 写入并储存图片 读取并播放影片 写入并储存影片 取得图像信息 旋转/翻转/改变尺寸 图像的几何变形 图像的色彩转换 绘制各种形状 图像加入文字 剪裁图像 调整对比和亮度 负片效果 图像模糊化 图像的叠加与相减 二值化黑白图像 图像的侵蚀与膨胀 图像边缘侦测 魔术棒填充颜色 图像遮罩 边缘羽化效果 马赛克效果 子母画面影片 万花筒影片效果 多画面延迟播放影片 搞笑全景影片合成效果 凸透镜效果 ( 鱼眼效果 ) 倒数计时自动拍照效果 线性渐层填色 合成半透明图片 将指定的颜色变透明 处理 gif 动画 影片转透明 gif 动画 辨识 QRCode 和 BarCode 扫描 QRCode 切换效果 侦测鼠标事件 鼠标选取自动马赛克 即时在影片中绘图 侦测键盘行为 加入滑杆 ( Trackbar ) 拍照上传 Google 云端硬盘

AI 图像辨识教学

AI 图像辨识教学导读 OpenCV 人脸侦测 OpenCV 人脸马赛克 OpenCV 五官侦测 OpenCV 汽车侦测 OpenCV 行人侦测 OpenCV 辨识不同人脸 OpenCV 单对象追踪 OpenCV 多对象追踪 OpenCV 抓取特定颜色 OpenCV 追踪并标记颜色 情绪辨识与年龄侦测 辨识微笑,拍照储存 使用 Mediapipe ( 新 ) Mediapipe 人脸侦测 ( 新 ) Mediapipe 人脸特征点侦测 ( 新 ) Mediapipe 手掌侦测 ( 新 ) 使用 Mediapipe ( 旧 ) Mediapipe 人脸侦测 ( 旧 ) Mediapipe 人脸网格 ( 旧 ) Mediapipe 手掌侦测 ( 旧 ) Mediapipe 姿势侦测 Mediapipe 全身侦测 Mediapipe 物体侦测 Mediapipe 人物去背 Mediapipe 手势辨识 辨识比中指,自动马赛克 用手指在影片中画图 手指擦除镜子雾气效果 即时合成搞笑橘子脸 Jupyter 安装 Tensorflow 使用 Teachable Machine 辨识剪刀、石头、布 辨识是否戴口罩 辨识手写数字

NumPy 教学

NumPy 教学导读 NumPy 函数库 数据型态 建立数组 读取数组 迭代数组 数组项目赋值 修改数组形状 修改数组项目 填充数组 分割数组 合并数组 数组排序 广播 搜索数组项目 算数计算 数学函数 随机数 字串操作处理

matplotlib 图表

matplotlib 教学导读 matplotlib 函数库 Figure 和 Axes Figure 参数设定 建立多个子图表 设定图表标签 设定座标轴位置 设定座标轴刻度文字 数据文字标记 加入颜色对照表 使用极座标系统 使用 3D 图表 图表显示中文 下载储存图表 显示图片 制作图表动画 ( 图表 ) 折线图 ( 图表 ) 散布图 ( 图表 ) 长条图 ( 图表 ) 圆饼图 ( 图表 ) 甜甜圈图 ( 图表 ) 等高线图 ( 图表 ) 阶梯折线图 ( 图表 ) 堆叠折线图 ( 图表 ) 堆叠长条图 ( 图表 ) 极座标长条图 ( 图表 ) 极座标散布图 ( 图表 ) 3D 柱状长条图 ( 图表 ) 3D 散布图

Tkinter 界面设计

建立 Tkinter 视窗 Label 标签 Button 按钮 Radiobutton 单选按钮 Checkbutton 复选按钮 Entry 单行输入框 Text 多行输入框 Listbox 列表选择框 OptionMenu 下拉选单 Scale 数值调整滑杆 Spinbox 数值调整元件 Frame 框架 LabelFrame 标签框架 Scrollbar 滚动条 Canvas 画布 Menu 选单 Messagebox 消息提示框 Photoimage 显示图片 ttk.Progressbar 进度条 ttk.Combobox 下拉选单 Pack 基本版面布局 Grid 格状版面布局 Place 位置版面布局 范例 - Label 制作时钟 范例 - 点击按钮开文件 范例 - 打开多个文件 范例 - 打开并压缩文件 范例 - 打开并显示图片 范例 - 调整图片亮度对比 范例 - 简单计算机 范例 - 发送 LINE Notify

PyQt5 界面设计

PyQt5 函数库 使用 Qt designer 建立 PyQt5 视窗 QLabel 标签 QPushButton 按钮 QRadioButton 单选按钮 QCheckBox 复选按钮 QGraphicsView 显示图片 QLineEdit 单行输入框 QTextEdit 多行输入框 QListWidget 列表选择框 QComboBox 下拉选单 QSpinBox 数值调整元件 QTimeEdit 时间调整元件 QDateEdit 日期调整元件 QSlider 数值调整滑杆 QProgressBar 进度条 QFileDialog 选择文件视窗 QMessageBox 对话视窗 QInputDialog 输入视窗 QMenuBar 视窗选单 QTimer 定时器 QThread 多执行绪 QtCore.pyqtSignal 信号传递 QtMultimedia 播放声音 QPainter 绘图 QPainter 绘图 ( QPen ) QPainter 绘图 ( 储存图片 ) QSS 样式设定 QWebEngineView 网页显示 Layout 布局 ( 垂直水平 ) Layout 布局 ( Grid 网格 ) Layout 布局 ( Form 表单 ) 侦测鼠标事件 侦测键盘与快速键组合 侦测与控制视窗 视窗中打开新视窗 显示图片的三种方法 显示 Matplotlib 图表 显示 Pillow 图片 显示 OpenCV 图片和影片 范例 - 世界时钟 范例 - 简单计算机 范例 - 储存文件为压缩档 范例 - 发送 LINE Notify 范例 - 电脑摄影机 范例 - 摄影机拍照录影 范例 - 简单录音机 范例 - 小画家 范例 - 打开图片转档储存 范例 - 调整图片亮度对比

PyQt6 界面设计

PyQt6 函数库 PyQt6 和 PyQt5 的差异 建立 PyQt6 视窗 QLabel 标签 QPushButton 按钮 QRadioButton 单选按钮 QCheckBox 复选按钮 QGraphicsView 显示图片 QLineEdit 单行输入框 QTextEdit 多行输入框 QListWidget 列表选择框 QComboBox 下拉选单 QSpinBox 数值调整元件 QTimeEdit 时间调整元件 QDateEdit 日期调整元件 QSlider 数值调整滑杆 QProgressBar 进度条 QFileDialog 选择文件视窗 QMessageBox 对话视窗 QInputDialog 输入视窗 QMenuBar 视窗选单 QTimer 定时器 QThread 多执行绪 QtCore.pyqtSignal 信号传递 QtMultimedia 播放声音 QPainter 绘图 QPainter 绘图 ( QPen ) QPainter 绘图 ( 储存图片 ) QSS 样式设定 QWebEngineView 网页显示 Layout 布局 ( 垂直水平 ) Layout 布局 ( Grid 网格 ) Layout 布局 ( Form 表单 ) 侦测鼠标事件 侦测键盘与快速键组合 侦测与控制视窗 视窗中打开新视窗 显示图片的三种方法 显示 Matplotlib 图表 显示 Pillow 图片 显示 OpenCV 图片和影片 范例 - 世界时钟 范例 - 简单计算机 范例 - 储存文件为压缩档 范例 - 发送 LINE Notify 范例 - 电脑摄影机 范例 - 摄影机拍照录影 范例 - 简单录音机 范例 - 小画家 范例 - 打开图片转档储存 范例 - 调整图片亮度对比

影音处理范例

批次图片转档 批次调整图片尺寸 调整图片亮度和对比 裁切与旋转图片 拼接多张图片 图片加上 logo 浮水印 图片加上文字浮水印 图片马赛克效果 图片模糊化 图片锐利化 读取与修改图片 Exif 图片转文字 ( OCR ) 读取声音信息、输出声音 声音剪辑与串接 声音音量调整 声音混合与反转 改变声音速度 播放声音 麦克风录音 合成音符声音 显示声波图形 影片转档 取出影片声音或加入声音 影片剪辑与合并 影片混合与排列显示 改变影片尺寸、旋转翻转 调整影片速度、倒转影片 调整影片亮度/对比/颜色 影片转 gif 动画 影片中加入文字 影片自动加上字幕 影片截图、图片转影片

实际应用范例

下载 Youtube 影片 下载 Youtube 清单影片 定时自动屏幕截图 LINE Notify 传送屏幕截图 建立 MJPEG 即时图像串流 批次重新命名文件 产生 QRCode 产生 BarCode 读取 PDF 内容 PDF 拆分/合并/插入/删除 读取 EXCEL 内容 写入数据到 EXCEL CSV 写入 EXCEL 读取电脑信息 侦测电脑屏幕分辨率 查询电脑对内对外 IP 查询网站 IP、ping IP 制作 MacOS app

基础范例

电费试算 摄氏/华氏转换 厘米/英寸换算 判断平年与闰年 找出不重复字元 找出中间的字元 去除中英文夹杂的空白 大乐透电脑选号 下载进度条 星号金字塔 数字金字塔 猜数字 ( 猜大猜小 ) 猜数字 ( 几 A 几 B ) 简单时钟 ( 世界时间 ) 计算 BMI 数值 计算年纪 ( 岁、月、天 ) 产生身份证字号 ( 随机 ) 检查身份证字号 统一发票对奖 罗马数字转换

数学范例

两个数字的四则运算 计算多个数字的总和 费波那契数列 九九乘法表 质因数分解 快速找出质数 最小公倍数 ( 多个数字 ) 最大公因数 ( 多个数字 )

ZeroJudge 解答

关于 ZeroJudge a001: 哈啰 a002: 简易加法 a003: 两光法师占卜术 a004: 文文的求婚 a005: Eva 的回家作业 a006: 一元二次方程序 a009: 解码器 a010: 因数分解 a013: 罗马数字 a015: 矩阵的翻转 a017: 五则运算 a020: 身份证检验 a021: 大数运算 a022: 回文 a024: 最大公因数(GCD) a034: 二进位制转换 a038: 数字翻转 a040: 阿姆斯壮数 a042: 平面圆形切割 a044: 空间切割 a053: Sagit's 计分程序 a054: 电话客服中心 a058: MOD3 a059: 完全平方和 a065: 提款卡密码 a095: 麦哲伦的阴谋 a104: 排序 a147: Print it all a148: You Cannot Pass?! a149: 乘乘乐 a215: 明明爱数数 a216: 数数爱明明 a224: 明明爱明明 a225: 明明爱排列 a244: 新手训练~for+if a248: 新手训练~数组应用 a263: 日期差几天 a271: 彩色萝卜 a291: nAnB problem a410: 解方程 a414: 比特运算之进位篇 a417: 螺旋矩阵 a524: 手机之谜 a528: 大数排序 a647: 投资专家 a693: 吞食天地 a738: 最大公约数 a746: 画蛇添足 a799: 正值国 a915: 二维点排序 b265: Conformity b294: 经济大恐荒 b367: 翻转世界 b374: 求众数 b511: 换铜板 b558: 求数列第 n 项 e267: Group Reverse d073: 分组报告 d294: 算算算 Easy d485: 我爱偶数 d827: 买铅笔

范例 - 调整图片亮度对比

这篇教学会综合 PyQt6 的“打开并显示图片”、“图片转档储存”以及“在视窗中打开视窗”等文章范例,实际制作点一个可以打开图片,并且透过滑杆调整图片亮度对比、饱和度与锐利度,完成后后储存图片为 JPG 或 PNG 的应用。

快速导览:

  • 由于这个范例会使用“两个视窗”,所以会使用“class”方法进行实作。
  • 因为 Google Colab 不支援 PyQt6,所以请使用本机环境 ( 参考:使用 Python 虚拟环境 ) 或使用 Anaconda Jupyter 进行实作 ( 参考:使用 Anaconda )。

安装 Pillow

输入下列指令安装 Pillow,根据个人环境使用 pip 或 pip3,如果使用 Anaconda Jupyter,已经内建 Pillow 函数库。

pip install Pillow

界面设计

这个范例的界面设计,需要在画面左侧放入显示图片的“画布”,画面右侧放入对应的“按钮”以及调整“滑杆”,参考 QLabel 标签、QPushButton 按钮 和 QSlider 数值调整滑杆 三篇范例教学,将对应的元件放入画面中。

  • 函数库需要 QtGui、QtCore 和 PIL。
  • 下方程序码先注解 connect 会需要用到的函数 ( 先聚焦在界面设计 ),避免执行时发生错误。
from PyQt6 import QtWidgets
from PyQt6.QtGui import *
from PyQt6.QtCore import *
import sys
from PIL import Image, ImageQt, ImageEnhance

class MyWidget(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('oxxo.studio')
        self.resize(540, 360)
        self.setUpdatesEnabled(True)
        self.img = False    # 建立一個變數儲存圖片
        self.ui()
        self.adjustUi()

    # 主要按鈕和文字標籤
    def ui(self):
        self.canvas = QPixmap(360,360)         # 建立畫布元件
        self.canvas.fill(QColor('#ffffff'))    # 預設填滿白色
        self.label = QtWidgets.QLabel(self)    # 建立 QLabel 元件,作為顯示圖片使用
        self.label.setGeometry(0, 0, 360, 360) # 設定位置和尺寸
        self.label.setPixmap(self.canvas)      # 放入畫布元件

        self.mbox = QtWidgets.QMessageBox(self)        # 建立對話視窗元件

        self.btn_open = QtWidgets.QPushButton(self)    # 開啟圖片按鈕
        self.btn_open.setText('開啟圖片')
        self.btn_open.setGeometry(400, 10, 100, 30)
        # self.btn_open.clicked.connect(self.newFile)

        self.btn_save = QtWidgets.QPushButton(self)    # 另存圖片按鈕
        self.btn_save.setText('另存圖片')
        self.btn_save.setGeometry(400, 40, 100, 30)
        # self.btn_save.clicked.connect(self.saveFile)

        self.btn_reset = QtWidgets.QPushButton(self)    # 重設數值按鈕
        self.btn_reset.setText('重設數值')
        self.btn_reset.setGeometry(400, 290, 100, 30)
        # self.btn_reset.clicked.connect(self.resetVal)

        self.btn_close = QtWidgets.QPushButton(self)    # 關閉視窗按鈕
        self.btn_close.setText('關閉')
        self.btn_close.setGeometry(400, 320, 100, 30)
        # self.btn_close.clicked.connect(self.closeFile)

    # 調整數值拉霸
    def adjustUi(self):
        self.label_adj_1 = QtWidgets.QLabel(self)       # 調整亮度說明文字
        self.label_adj_1.setGeometry(400, 80, 100, 30)
        self.label_adj_1.setText('調整亮度')
        self.label_adj_1.setAlignment(Qt.AlignmentFlag.AlignCenter)

        self.label_val_1 = QtWidgets.QLabel(self)       # 調整亮度數值
        self.label_val_1.setGeometry(500, 100, 40, 30)
        self.label_val_1.setText('0')
        self.label_val_1.setAlignment(Qt.AlignmentFlag.AlignCenter)

        self.slider_1 = QtWidgets.QSlider(self)         # 調整亮度滑桿
        self.slider_1.setOrientation(Qt.Orientation.Horizontal)
        self.slider_1.setGeometry(400,100,100,30)
        self.slider_1.setRange(-100, 100)
        self.slider_1.setValue(0)
        # self.slider_1.valueChanged.connect(self.showImage)

        self.label_adj_2 = QtWidgets.QLabel(self)       # 調整對比說明文字
        self.label_adj_2.setGeometry(400, 130, 100, 30)
        self.label_adj_2.setText('調整對比')
        self.label_adj_2.setAlignment(Qt.AlignmentFlag.AlignCenter)

        self.label_val_2 = QtWidgets.QLabel(self)       # 調整對比數值
        self.label_val_2.setGeometry(500, 150, 40, 30)
        self.label_val_2.setText('0')
        self.label_val_2.setAlignment(Qt.AlignmentFlag.AlignCenter)

        self.slider_2 = QtWidgets.QSlider(self)         # 調整對比滑桿
        self.slider_2.setOrientation(Qt.Orientation.Horizontal)
        self.slider_2.setGeometry(400,150,100,30)
        self.slider_2.setRange(-100, 100)
        self.slider_2.setValue(0)
        # self.slider_2.valueChanged.connect(self.showImage)

        self.label_adj_3 = QtWidgets.QLabel(self)       # 調整飽和度說明文字
        self.label_adj_3.setGeometry(400, 180, 100, 30)
        self.label_adj_3.setText('調整飽和度')
        self.label_adj_3.setAlignment(Qt.AlignmentFlag.AlignCenter)

        self.label_val_3 = QtWidgets.QLabel(self)       # 調整飽和度數值
        self.label_val_3.setGeometry(500, 200, 40, 30)
        self.label_val_3.setText('0')
        self.label_val_3.setAlignment(Qt.AlignmentFlag.AlignCenter)

        self.slider_3 = QtWidgets.QSlider(self)         # 調整飽和度滑桿
        self.slider_3.setOrientation(Qt.Orientation.Horizontal)
        self.slider_3.setGeometry(400,200,100,30)
        self.slider_3.setRange(-100, 100)
        self.slider_3.setValue(0)
        # self.slider_3.valueChanged.connect(self.showImage)

        self.label_adj_4 = QtWidgets.QLabel(self)       # 調整銳利度說明文字
        self.label_adj_4.setGeometry(400, 230, 100, 30)
        self.label_adj_4.setText('調整銳利度')
        self.label_adj_4.setAlignment(Qt.AlignmentFlag.AlignCenter)

        self.label_val_4 = QtWidgets.QLabel(self)       # 調整銳利度數值
        self.label_val_4.setGeometry(500, 250, 40, 30)
        self.label_val_4.setText('0')
        # self.label_val_4.setAlignment(Qt.AlignmentFlag.AlignCenter)

        self.slider_4 = QtWidgets.QSlider(self)         # 調整銳利度滑桿
        self.slider_4.setOrientation(Qt.Orientation.Horizontal)
        self.slider_4.setGeometry(400,250,100,30)
        self.slider_4.setRange(-100, 100)
        self.slider_4.setValue(0)
        # self.slider_4.valueChanged.connect(self.showImage)

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    Form = MyWidget()
    Form.show()
    sys.exit(app.exec())

PyQt6 教学 - 调整图片亮度对比、饱和度、锐利度 - 界面设计

打开图片

在 class MyWidget 里加入 newFile 和 closeFile 两个新方法 ( 函数 ),对应到点击打开图片和关闭的按钮,当用户点击关闭按钮时 ( 解除 connect 注解 ),会弹出对话视窗询问是否关闭,当点击打开图片时 ( 解除 connect 注解 ),会弹出选择文件的视窗,选择文件后,会透过 Pillow 的 Image 方法打开图片,再借由 ImageQt.toqimage 转换成 Qpixmap 的格式显示在画布中。

# 開新圖片
def newFile(self):
    global output      # 建立一個全域變數,在不同視窗之間傳遞圖片資訊
    filePath , filetype = QtWidgets.QFileDialog.getOpenFileName(filter='IMAGE(*.jpg *.png *.gif)')
    if filePath:
        # 如果選擇檔案,彈出視窗詢問是否開啟
        ret = self.mbox.question(self, 'question', '確定開新檔案?')
        # 如果確定開啟
        if ret == self.mbox.StandardButton.Yes:
            self.img = Image.open(filePath)                 # 使用 Pillow Image 開啟
            output = self.img                               # 紀錄圖片資訊
            qimg = ImageQt.toqimage(self.img)               # 轉換成 Qpixmap 格式
            self.canvas = QPixmap(360,360).fromImage(qimg)  # 顯示在畫布中
            self.label.setPixmap(self.canvas)               # 重設畫布內容
            self.update()                                   # 更新視窗
        else:
            return

# 關閉
def closeFile(self):
    ret = self.mbox.question(self, 'question', '確定關閉視窗?')
    if ret == self.mbox.StandardButton.Yes:
        app.quit()            # 如果點擊 yes,關閉視窗
    else:
        return

PyQt6 教学 - 调整图片亮度对比、饱和度、锐利度 - 打开图片

调整图片亮度对比、饱和度、锐利度

接着在 class MyWidget 里加入 resetVal 和 showImage 两个新方法 ( 函数 ),resetVal 对应到重设按钮 ( 解除 connect 注解 ),showImage 拖拉调整滑杆时的程序,当中透过 ImageEnhance.Brightness 调整亮度,ImageEnhance.Contrast 调整对比,ImageEnhance.Color 调整饱和度,ImageEnhance.Sharpnes 调整锐利度。

参考:Pillow 调整图片亮度、对比、饱和度和锐利度

# 重設
def resetVal(self):
    self.slider_1.setValue(0)        # 滑桿預設值 0
    self.slider_2.setValue(0)        # 滑桿預設值 0
    self.slider_3.setValue(0)        # 滑桿預設值 0
    self.slider_4.setValue(0)        # 滑桿預設值 0
    self.label_val_1.setText('0')    # 滑桿數值顯示 0
    self.label_val_2.setText('0')    # 滑桿數值顯示 0
    self.label_val_3.setText('0')    # 滑桿數值顯示 0
    self.label_val_4.setText('0')    # 滑桿數值顯示 0
    qimg = ImageQt.toqimage(self.img)               # 圖片顯示 self.img 內容
    self.canvas = QPixmap(360,360).fromImage(qimg)  # 更新畫布內容
    self.label.setPixmap(self.canvas)               # 重設畫布
    self.update()                                   # 更新視窗

# 調整並顯示圖片
def showImage(self):
    global output
    # 如果已經開啟圖片
    if self.img != False:
        val1 = self.slider_1.value()         # 取得滑桿數值
        val2 = self.slider_2.value()         # 取得滑桿數值
        val3 = self.slider_3.value()         # 取得滑桿數值
        val4 = self.slider_4.value()         # 取得滑桿數值
        self.label_val_1.setText(str(val1))  # 顯示滑桿數值
        self.label_val_2.setText(str(val2))  # 顯示滑桿數值
        self.label_val_3.setText(str(val3))  # 顯示滑桿數值
        self.label_val_4.setText(str(val4))  # 顯示滑桿數值
        output = self.img.copy()                        # 複製 img 圖片 ( 避免更動原始圖片 )
        brightness = ImageEnhance.Brightness(output)    # 調整亮度
        output = brightness.enhance(1+int(val1)/100)    # 讀取滑桿數值並轉換成調整的數值
        contrast = ImageEnhance.Contrast(output)        # 調整對比
        output = contrast.enhance(1+int(val2)/100)      # 讀取滑桿數值並轉換成調整的數值
        color = ImageEnhance.Color(output)              # 調整飽和度
        output = color.enhance(1+int(val3)/100)         # 讀取滑桿數值並轉換成調整的數值
        sharpness = ImageEnhance.Sharpness(output)      # 調整銳利度
        output = sharpness.enhance(1+int(val4)/10)      # 讀取滑桿數值並轉換成調整的數值

        qimg = ImageQt.toqimage(output)                 # 圖片顯示 self.img 內容
        self.canvas = QPixmap(360,360).fromImage(qimg)  # 更新畫布內容
        self.label.setPixmap(self.canvas)               # 重設畫布
        self.update()                                   # 更新視窗

PyQt6 教学 - 调整图片亮度对比、饱和度、锐利度 - 打开图片

开新视窗,设定另存图片格式

在 class MyWidget 里加入 saveFile 新方法 ( 函数 ),对应到点击另存图片按钮,当用户点击另存图片按钮时 ( 解除 connect 注解 ),会打开新的视窗。

def saveFile(self):
    self.nw = saveWindow()      # 連接新視窗
    self.nw.show()              # 顯示新視窗

在程序中新增另外一个名为 saveWindow 的 class 负责新视窗的显示,当中使用的程序为“打开图片转档储存 ( 可调整质量与尺寸 )”的范例程序,打开新视窗后,可以选择储存的格式和尺寸,按下确认后弹出对话视窗,选择 yes 就会另存图片。

class saveWindow(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('選擇存檔格式')    # 新視窗標題
        self.resize(300, 180)                # 新視窗尺寸
        self.ui()

    def ui(self):
        self.label_size = QtWidgets.QLabel(self)     # 顯示尺寸縮放比例說明文字
        self.label_size.setGeometry(15, 10, 80, 30)
        self.label_size.setText('尺寸改變')

        self.imgsize =100                            # 預設圖片尺寸縮放比例

        self.box_size = QtWidgets.QSpinBox(self)     # 尺寸縮放調整元件
        self.box_size.setGeometry(15, 40, 60, 30)
        self.box_size.setRange(0,200)
        self.box_size.setValue(self.imgsize)
        self.box_size.valueChanged.connect(self.changeSize) # 串連調整函式

        self.label_format = QtWidgets.QLabel(self)   # 存檔格式說明文字
        self.label_format.setGeometry(100, 10, 100, 30)
        self.label_format.setText('儲存格式')

        self.format = 'JPG'                          # 預設格式

        self.box_format  = QtWidgets.QComboBox(self) # 下拉選單元件
        self.box_format.addItems(['JPG','PNG'])      # 兩個選項
        self.box_format.setGeometry(90,40,100,30)
        self.box_format.currentIndexChanged.connect(self.changeFormat) # 串連改變時的程式

        self.label_jpg = QtWidgets.QLabel(self)      # 壓縮品質說明文字
        self.label_jpg.setGeometry(100, 70, 100, 30)
        self.label_jpg.setText('JPG 壓縮品質')

        self.val = 75                                # 預設 JPG 壓縮品質

        self.label_jpg_val = QtWidgets.QLabel(self)  # 壓縮品質數值
        self.label_jpg_val.setGeometry(190, 100, 100, 30)
        self.label_jpg_val.setText(str(self.val))

        self.slider = QtWidgets.QSlider(self)        # 壓縮品質調整滑桿
        self.slider.setOrientation(Qt.Orientation.Horizontal)                # 水平顯示
        self.slider.setGeometry(100,100,80,30)
        self.slider.setRange(0, 100)                 # 數值範圍
        self.slider.setValue(self.val)               # 預設值
        self.slider.valueChanged.connect(self.changeVal)  # 串連改變時的函式

        self.btn_ok = QtWidgets.QPushButton(self)    # 確定儲存按鈕
        self.btn_ok.setText('確定儲存')
        self.btn_ok.setGeometry(200, 10, 90, 30)
        self.btn_ok.clicked.connect(self.saveImage)  # 串連儲存函式

        self.btn_cancel = QtWidgets.QPushButton(self)  # 取消儲存按鈕
        self.btn_cancel.setText('取消')
        self.btn_cancel.setGeometry(200, 40, 90, 30)
        self.btn_cancel.clicked.connect(self.closeWindow)  # 串連關閉視窗函式

    # 改變尺寸
    def changeSize(self):
        self.imgsize = self.box_size.value()         # 取得改變的數值

    # 改變格式
    def changeFormat(self):
        self.format = self.box_format.currentText()  # 顯示目前格式
        if self.format == 'JPG':
            self.label_jpg.setDisabled(False)        # 如果是 JPG,啟用 JPG 壓縮品質調整相關元件
            self.label_jpg_val.setDisabled(False)
            self.slider.setDisabled(False)
        else:
            self.label_jpg.setDisabled(True)        # 如果是 JPG,停用 JPG 壓縮品質調整相關元件
            self.label_jpg_val.setDisabled(True)
            self.slider.setDisabled(True)

    # 改變數值
    def changeVal(self):
        self.val = self.slider.value()              # 取得滑桿數值
        self.label_jpg_val.setText(str(self.slider.value()))

    # 存檔
    def saveImage(self):
        global output
        if self.format == 'JPG':
            filePath, filterType = QtWidgets.QFileDialog.getSaveFileName(filter='JPG(*.jpg)')
            if filePath:
                nw = int ( output.size[0] * self.imgsize/100 )    # 根據縮放比例調整大小
                nh = int ( output.size[1] * self.imgsize/100 )
                img2 = output.resize((nw, nh))                    # 調整大小
                img2.save(filePath, quality=self.val, subsampling=0)  # JPG 存檔
                self.close()
        else:
            filePath, filterType = QtWidgets.QFileDialog.getSaveFileName(filter='PNG(*.png)')
            if filePath:
                nw = int ( output.size[0] * self.imgsize/100 )    # 根據縮放比例調整大小
                nh = int ( output.size[1] * self.imgsize/100 )
                img2 = output.resize((nw, nh))                    # 調整大小
                img2.save(filePath, 'png')                        # PNG 存檔
                self.close()

    def closeWindow(self):
        self.close()

PyQt6 教学 - 调整图片亮度对比、饱和度、锐利度 - 开新视窗,设定另存图片格式

完整程序码

from PyQt6 import QtWidgets
from PyQt6.QtGui import *
from PyQt6.QtCore import *
import sys
from PIL import Image, ImageQt, ImageEnhance

class MyWidget(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('oxxo.studio')
        self.resize(540, 360)
        self.setUpdatesEnabled(True)
        self.img = False    # 建立一個變數儲存圖片
        self.ui()
        self.adjustUi()

    # 主要按鈕和文字標籤
    def ui(self):
        self.canvas = QPixmap(360,360)         # 建立畫布元件
        self.canvas.fill(QColor('#ffffff'))    # 預設填滿白色
        self.label = QtWidgets.QLabel(self)    # 建立 QLabel 元件,作為顯示圖片使用
        self.label.setGeometry(0, 0, 360, 360) # 設定位置和尺寸
        self.label.setPixmap(self.canvas)      # 放入畫布元件

        self.mbox = QtWidgets.QMessageBox(self)        # 建立對話視窗元件

        self.btn_open = QtWidgets.QPushButton(self)    # 開啟圖片按鈕
        self.btn_open.setText('開啟圖片')
        self.btn_open.setGeometry(400, 10, 100, 30)
        self.btn_open.clicked.connect(self.newFile)

        self.btn_save = QtWidgets.QPushButton(self)    # 另存圖片按鈕
        self.btn_save.setText('另存圖片')
        self.btn_save.setGeometry(400, 40, 100, 30)
        self.btn_save.clicked.connect(self.saveFile)

        self.btn_reset = QtWidgets.QPushButton(self)    # 重設數值按鈕
        self.btn_reset.setText('重設數值')
        self.btn_reset.setGeometry(400, 290, 100, 30)
        self.btn_reset.clicked.connect(self.resetVal)

        self.btn_close = QtWidgets.QPushButton(self)    # 關閉視窗按鈕
        self.btn_close.setText('關閉')
        self.btn_close.setGeometry(400, 320, 100, 30)
        self.btn_close.clicked.connect(self.closeFile)

    # 調整數值拉霸
    def adjustUi(self):
        self.label_adj_1 = QtWidgets.QLabel(self)       # 調整亮度說明文字
        self.label_adj_1.setGeometry(400, 80, 100, 30)
        self.label_adj_1.setText('調整亮度')
        self.label_adj_1.setAlignment(Qt.AlignmentFlag.AlignCenter)

        self.label_val_1 = QtWidgets.QLabel(self)       # 調整亮度數值
        self.label_val_1.setGeometry(500, 100, 40, 30)
        self.label_val_1.setText('0')
        self.label_val_1.setAlignment(Qt.AlignmentFlag.AlignCenter)

        self.slider_1 = QtWidgets.QSlider(self)         # 調整亮度滑桿
        self.slider_1.setOrientation(Qt.Orientation.Horizontal)
        self.slider_1.setGeometry(400,100,100,30)
        self.slider_1.setRange(-100, 100)
        self.slider_1.setValue(0)
        self.slider_1.valueChanged.connect(self.showImage)

        self.label_adj_2 = QtWidgets.QLabel(self)       # 調整對比說明文字
        self.label_adj_2.setGeometry(400, 130, 100, 30)
        self.label_adj_2.setText('調整對比')
        self.label_adj_2.setAlignment(Qt.AlignmentFlag.AlignCenter)

        self.label_val_2 = QtWidgets.QLabel(self)       # 調整對比數值
        self.label_val_2.setGeometry(500, 150, 40, 30)
        self.label_val_2.setText('0')
        self.label_val_2.setAlignment(Qt.AlignmentFlag.AlignCenter)

        self.slider_2 = QtWidgets.QSlider(self)         # 調整對比滑桿
        self.slider_2.setOrientation(Qt.Orientation.Horizontal)
        self.slider_2.setGeometry(400,150,100,30)
        self.slider_2.setRange(-100, 100)
        self.slider_2.setValue(0)
        self.slider_2.valueChanged.connect(self.showImage)

        self.label_adj_3 = QtWidgets.QLabel(self)       # 調整飽和度說明文字
        self.label_adj_3.setGeometry(400, 180, 100, 30)
        self.label_adj_3.setText('調整飽和度')
        self.label_adj_3.setAlignment(Qt.AlignmentFlag.AlignCenter)

        self.label_val_3 = QtWidgets.QLabel(self)       # 調整飽和度數值
        self.label_val_3.setGeometry(500, 200, 40, 30)
        self.label_val_3.setText('0')
        self.label_val_3.setAlignment(Qt.AlignmentFlag.AlignCenter)

        self.slider_3 = QtWidgets.QSlider(self)         # 調整飽和度滑桿
        self.slider_3.setOrientation(Qt.Orientation.Horizontal)
        self.slider_3.setGeometry(400,200,100,30)
        self.slider_3.setRange(-100, 100)
        self.slider_3.setValue(0)
        self.slider_3.valueChanged.connect(self.showImage)

        self.label_adj_4 = QtWidgets.QLabel(self)       # 調整銳利度說明文字
        self.label_adj_4.setGeometry(400, 230, 100, 30)
        self.label_adj_4.setText('調整銳利度')
        self.label_adj_4.setAlignment(Qt.AlignmentFlag.AlignCenter)

        self.label_val_4 = QtWidgets.QLabel(self)       # 調整銳利度數值
        self.label_val_4.setGeometry(500, 250, 40, 30)
        self.label_val_4.setText('0')

        self.slider_4 = QtWidgets.QSlider(self)         # 調整銳利度滑桿
        self.slider_4.setOrientation(Qt.Orientation.Horizontal)
        self.slider_4.setGeometry(400,250,100,30)
        self.slider_4.setRange(-100, 100)
        self.slider_4.setValue(0)
        self.slider_4.valueChanged.connect(self.showImage)

    # 開新圖片
    def newFile(self):
        global output      # 建立一個全域變數,在不同視窗之間傳遞圖片資訊
        filePath , filetype = QtWidgets.QFileDialog.getOpenFileName(filter='IMAGE(*.jpg *.png *.gif)')
        if filePath:
            # 如果選擇檔案,彈出視窗詢問是否開啟
            ret = self.mbox.question(self, 'question', '確定開新檔案?')
            # 如果確定開啟
            if ret == self.mbox.StandardButton.Yes:
                self.img = Image.open(filePath)                 # 使用 Pillow Image 開啟
                output = self.img                               # 紀錄圖片資訊
                qimg = ImageQt.toqimage(self.img)               # 轉換成 Qpixmap 格式
                self.canvas = QPixmap(360,360).fromImage(qimg)  # 顯示在畫布中
                self.label.setPixmap(self.canvas)               # 重設畫布內容
                self.update()                                   # 更新視窗
            else:
                return

    # 關閉
    def closeFile(self):
        ret = self.mbox.question(self, 'question', '確定關閉視窗?')
        if ret == self.mbox.StandardButton.Yes:
            app.quit()            # 如果點擊 yes,關閉視窗
        else:
            return

    # 重設
    def resetVal(self):
        self.slider_1.setValue(0)        # 滑桿預設值 0
        self.slider_2.setValue(0)        # 滑桿預設值 0
        self.slider_3.setValue(0)        # 滑桿預設值 0
        self.slider_4.setValue(0)        # 滑桿預設值 0
        self.label_val_1.setText('0')    # 滑桿數值顯示 0
        self.label_val_2.setText('0')    # 滑桿數值顯示 0
        self.label_val_3.setText('0')    # 滑桿數值顯示 0
        self.label_val_4.setText('0')    # 滑桿數值顯示 0
        qimg = ImageQt.toqimage(self.img)               # 圖片顯示 self.img 內容
        self.canvas = QPixmap(360,360).fromImage(qimg)  # 更新畫布內容
        self.label.setPixmap(self.canvas)               # 重設畫布
        self.update()                                   # 更新視窗

    # 調整並顯示圖片
    def showImage(self):
        global output
        # 如果已經開啟圖片
        if self.img != False:
            val1 = self.slider_1.value()         # 取得滑桿數值
            val2 = self.slider_2.value()         # 取得滑桿數值
            val3 = self.slider_3.value()         # 取得滑桿數值
            val4 = self.slider_4.value()         # 取得滑桿數值
            self.label_val_1.setText(str(val1))  # 顯示滑桿數值
            self.label_val_2.setText(str(val2))  # 顯示滑桿數值
            self.label_val_3.setText(str(val3))  # 顯示滑桿數值
            self.label_val_4.setText(str(val4))  # 顯示滑桿數值
            output = self.img.copy()                        # 複製 img 圖片 ( 避免更動原始圖片 )
            brightness = ImageEnhance.Brightness(output)    # 調整亮度
            output = brightness.enhance(1+int(val1)/100)    # 讀取滑桿數值並轉換成調整的數值
            contrast = ImageEnhance.Contrast(output)        # 調整對比
            output = contrast.enhance(1+int(val2)/100)      # 讀取滑桿數值並轉換成調整的數值
            color = ImageEnhance.Color(output)              # 調整飽和度
            output = color.enhance(1+int(val3)/100)         # 讀取滑桿數值並轉換成調整的數值
            sharpness = ImageEnhance.Sharpness(output)      # 調整銳利度
            output = sharpness.enhance(1+int(val4)/10)      # 讀取滑桿數值並轉換成調整的數值

            qimg = ImageQt.toqimage(output)                 # 圖片顯示 self.img 內容
            self.canvas = QPixmap(360,360).fromImage(qimg)  # 更新畫布內容
            self.label.setPixmap(self.canvas)               # 重設畫布
            self.update()                                   # 更新視窗

    def saveFile(self):
        self.nw = saveWindow()      # 連接新視窗
        self.nw.show()              # 顯示新視窗

class saveWindow(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('選擇存檔格式')    # 新視窗標題
        self.resize(300, 180)                # 新視窗尺寸
        self.ui()

    def ui(self):
        self.label_size = QtWidgets.QLabel(self)     # 顯示尺寸縮放比例說明文字
        self.label_size.setGeometry(15, 10, 80, 30)
        self.label_size.setText('尺寸改變')

        self.imgsize =100                            # 預設圖片尺寸縮放比例

        self.box_size = QtWidgets.QSpinBox(self)     # 尺寸縮放調整元件
        self.box_size.setGeometry(15, 40, 60, 30)
        self.box_size.setRange(0,200)
        self.box_size.setValue(self.imgsize)
        self.box_size.valueChanged.connect(self.changeSize) # 串連調整函式

        self.label_format = QtWidgets.QLabel(self)   # 存檔格式說明文字
        self.label_format.setGeometry(100, 10, 100, 30)
        self.label_format.setText('儲存格式')

        self.format = 'JPG'                          # 預設格式

        self.box_format  = QtWidgets.QComboBox(self) # 下拉選單元件
        self.box_format.addItems(['JPG','PNG'])      # 兩個選項
        self.box_format.setGeometry(90,40,100,30)
        self.box_format.currentIndexChanged.connect(self.changeFormat) # 串連改變時的程式

        self.label_jpg = QtWidgets.QLabel(self)      # 壓縮品質說明文字
        self.label_jpg.setGeometry(100, 70, 100, 30)
        self.label_jpg.setText('JPG 壓縮品質')

        self.val = 75                                # 預設 JPG 壓縮品質

        self.label_jpg_val = QtWidgets.QLabel(self)  # 壓縮品質數值
        self.label_jpg_val.setGeometry(190, 100, 100, 30)
        self.label_jpg_val.setText(str(self.val))

        self.slider = QtWidgets.QSlider(self)        # 壓縮品質調整滑桿
        self.slider.setOrientation(Qt.Orientation.Horizontal)                # 水平顯示
        self.slider.setGeometry(100,100,80,30)
        self.slider.setRange(0, 100)                 # 數值範圍
        self.slider.setValue(self.val)               # 預設值
        self.slider.valueChanged.connect(self.changeVal)  # 串連改變時的函式

        self.btn_ok = QtWidgets.QPushButton(self)    # 確定儲存按鈕
        self.btn_ok.setText('確定儲存')
        self.btn_ok.setGeometry(200, 10, 90, 30)
        self.btn_ok.clicked.connect(self.saveImage)  # 串連儲存函式

        self.btn_cancel = QtWidgets.QPushButton(self)  # 取消儲存按鈕
        self.btn_cancel.setText('取消')
        self.btn_cancel.setGeometry(200, 40, 90, 30)
        self.btn_cancel.clicked.connect(self.closeWindow)  # 串連關閉視窗函式

    # 改變尺寸
    def changeSize(self):
        self.imgsize = self.box_size.value()         # 取得改變的數值

    # 改變格式
    def changeFormat(self):
        self.format = self.box_format.currentText()  # 顯示目前格式
        if self.format == 'JPG':
            self.label_jpg.setDisabled(False)        # 如果是 JPG,啟用 JPG 壓縮品質調整相關元件
            self.label_jpg_val.setDisabled(False)
            self.slider.setDisabled(False)
        else:
            self.label_jpg.setDisabled(True)        # 如果是 JPG,停用 JPG 壓縮品質調整相關元件
            self.label_jpg_val.setDisabled(True)
            self.slider.setDisabled(True)

    # 改變數值
    def changeVal(self):
        self.val = self.slider.value()              # 取得滑桿數值
        self.label_jpg_val.setText(str(self.slider.value()))

    # 存檔
    def saveImage(self):
        global output
        if self.format == 'JPG':
            filePath, filterType = QtWidgets.QFileDialog.getSaveFileName(filter='JPG(*.jpg)')
            if filePath:
                nw = int ( output.size[0] * self.imgsize/100 )    # 根據縮放比例調整大小
                nh = int ( output.size[1] * self.imgsize/100 )
                img2 = output.resize((nw, nh))                    # 調整大小
                img2.save(filePath, quality=self.val, subsampling=0)  # JPG 存檔
                self.close()
        else:
            filePath, filterType = QtWidgets.QFileDialog.getSaveFileName(filter='PNG(*.png)')
            if filePath:
                nw = int ( output.size[0] * self.imgsize/100 )    # 根據縮放比例調整大小
                nh = int ( output.size[1] * self.imgsize/100 )
                img2 = output.resize((nw, nh))                    # 調整大小
                img2.save(filePath, 'png')                        # PNG 存檔
                self.close()

    def closeWindow(self):
        self.close()

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    Form = MyWidget()
    Form.show()
    sys.exit(app.exec())

PyQt6 教学 - 调整图片亮度对比、饱和度、锐利度

意见反馈

微信二维码 微信扫码关注 抖音二维码 抖音扫码关注