• 手撕一个图片色卡提取器,可自定义提取色卡数量!


    在一些特殊的业务场景中,我们需要一次性提取一张图片中的色卡信息,并且需要使用十六进制的颜色表示方法进行展示。

    今天得空做了一个小工具,用来自定义的提取某一张图片中的色卡信息,需要提取某张图片中的色卡可以自行选择。

    提取色卡信息.gif

    实现过程就是比较简单的,主要是通过extcolors的python非标准库来实现的。

    另外的python非标准库就是PyQt5的使用,还有os、sys等系统或文件操作模块。

    没有安装上述几个python非标准库的话,我们直接使用pip的方式安装一下即可。

    pip install PyQt5 -i https://pypi.tuna.tsinghua.edu.cn/simple/
    
    pip install extcolors -i https://pypi.tuna.tsinghua.edu.cn/simple/
    
    • 1
    • 2
    • 3

    在安装完成相关的模块之后,将我们需要的python模块导入到开发的代码块中。

    # It's a module that allows you to print the stack trace of an exception.
    import traceback
    
    # It's a module that allows you to print the stack trace of an exception.
    import extcolors
    
    # It's importing all the classes from the QtWidgets module.
    from PyQt5.QtWidgets import *
    
    # It's importing all the classes from the QtGui module.
    from PyQt5.QtGui import *
    
    # It's importing all the classes from the QtCore module.
    from PyQt5.QtCore import *
    
    # It's importing the sys module.
    import sys
    
    # It's importing the os module.
    import os
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在代码块中创建ColorUI作为UI组件及布局的使用类,将UI相关的操作和槽函数全部放到这个类中进行处理。

    class ColorUI(QWidget):
        def __init__(self):
            """
            A constructor. It is called when an object is created from a class and it allows the class to initialize the
            attributes of a class.
            """
            super(ColorUI, self).__init__()
            self.init_ui()
    
        def init_ui(self):
            """
            This function initializes the UI.
            """
            self.setWindowTitle('图片颜色提取器 公众号:Python 集中营')
            self.setWindowIcon(QIcon('color.ico'))
            self.resize(500, 300)
    
            self.image_label = QLabel()
            self.image_label.setMinimumWidth(300)
            self.image_label.setMaximumHeight(300)
            self.image_label.setText('公众号:Python 集中营')
            self.image_label.setAlignment(Qt.AlignCenter)
            self.image_label.setStyleSheet('font-size:20px;color:blue;')
            self.image_label.setScaledContents(True)
    
            self.image_path_in = QLineEdit()
            self.image_path_in.setPlaceholderText('源图片路径')
            self.image_path_in.setReadOnly(True)
    
            self.image_path_btn = QPushButton()
            self.image_path_btn.setText('加载源图片')
            self.image_path_btn.clicked.connect(self.image_path_btn_click)
    
            self.set_color_num_label = QLabel()
            self.set_color_num_label.setText('设置提取色卡数量:')
    
            self.set_color_num_in = QLineEdit()
            self.set_color_num_in.setPlaceholderText('例如:10')
    
            self.start_btn = QPushButton()
            self.start_btn.setText('开始提取颜色')
            self.start_btn.clicked.connect(self.start_btn_click)
    
            self.brower = QTextBrowser()
            self.brower.setReadOnly(True)
            self.brower.setFont(QFont('宋体', 8))
            self.brower.setPlaceholderText('日志处理过程区域...')
            self.brower.ensureCursorVisible()
    
            hbox = QHBoxLayout()
    
            left_box = QVBoxLayout()
            right_box = QVBoxLayout()
    
            left_box.addWidget(self.image_label)
            right_form_box = QFormLayout()
            right_form_box.addRow(self.image_path_in, self.image_path_btn)
            right_form_box.addRow(self.set_color_num_label, self.set_color_num_in)
            right_form_box.addRow(self.start_btn)
            right_box.addLayout(right_form_box)
            right_box.addWidget(self.brower)
    
            hbox.addLayout(left_box)
            hbox.addLayout(right_box)
    
            self.thread_ = ColorWork(self)
            self.thread_.message.connect(self.show_message)
    
            self.setLayout(hbox)
    
        def show_message(self, text):
            """
            It shows a message
    
            :param text: The text to be displayed
            """
            cursor = self.brower.textCursor()
            cursor.movePosition(QTextCursor.End)
            self.brower.append(text)
            self.brower.setTextCursor(cursor)
            self.brower.ensureCursorVisible()
    
        def start_btn_click(self):
            """
            A function that is called when the start button is clicked.
            """
            self.thread_.start()
    
        def image_path_btn_click(self):
            """
            It opens a file dialog box to select the image file.
            """
            path = QFileDialog.getOpenFileName(self, "选取文件", os.getcwd(), "Image File (*.jpg);;Image File (*.png)")
            self.image_path_in.setText(path[0])
            pixmap = QPixmap(path[0])
            self.image_label.clear()
            self.image_label.setPixmap(pixmap)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97

    创建一个ColorWork类,继承自子线程QThread,将提取色卡的业务操作写到这个类中,和UI主线程分开处理保证不影响主线程的逻辑处理。

    class ColorWork(QThread):
        message = pyqtSignal(str)
    
        def __init__(self, parent=None):
            """
            A constructor that initializes the class.
    
            :param parent: The parent widget
            """
            super(ColorWork, self).__init__(parent)
            self.working = True
            self.parent = parent
    
        def __del__(self):
            """
            A destructor. It is called when the object is destroyed.
            """
            self.working = False
    
        def run(self):
            """
            *|CURSOR_MARCADOR|*
            """
            try:
                image_path_in = self.parent.image_path_in.text().strip()
                set_color_num_in = self.parent.set_color_num_in.text().strip()
                if image_path_in == '' or set_color_num_in == '':
                    self.message.emit('系统参数设置不能为空,请检查参数设置!')
                    return
                colors_x = extcolors.extract_from_path(image_path_in, tolerance=12, limit=int(set_color_num_in))
    
                for turple_ in colors_x[0]:
                    rgb_ = turple_[0]
                    color_16 = ('{:02X}' * 3).format(rgb_[0], rgb_[1], rgb_[2])
                    color_16 = ('#' + color_16)
                    self.message.emit(color_16)
            except:
                traceback.print_exc()
                self.message.emit('系统运行出现错误,请检查相关参数是否正确!')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    最后,我们按照main的标准处理方式,将整个页面应用启动起来就大功告成啦!

    if __name__ == '__main__':
        app = QApplication(sys.argv)
        main = ColorUI()
        main.show()
        sys.exit(app.exec_())
    
    • 1
    • 2
    • 3
    • 4
    • 5

    下面使用一个动态图片简单演示一下提取色卡信息的处理过程。

    提取色卡信息.gif

    色卡提取器应用color-catch.zip已打包成exe文件,公众号内回复 ‘色卡提取器’ 获取百度网盘的下载链接。

  • 相关阅读:
    数据仓库工具hive面试题集锦
    C#的Winform窗体淡出关闭效果
    Spring boot 使用 Swagger3 生成API接口文档
    盘一盘那些年我们使用的Java
    高德地图 API,点击地图标记获取自定义标记 (Marker) 中的信息
    Flink系列之Flink中Broadcast和Counter整理和实战
    指针和数组笔试题讲解(2)
    恶补了 Python 装饰器的八种写法,你随便问~
    Spring IoC容器
    angle_ll
  • 原文地址:https://blog.csdn.net/chengxuyuan_110/article/details/128138079