004.Qt&Python制作bmp转头文件过程

QtDesigner+Python制作图片转头文件过程记录(附完整代码)

一、功能描述

  • 能够使用文件管理器,即通过软件选择jpg或bmp图片
  • 能够对图片进行压缩裁剪,即通过设定的长宽数据对图片进行处理
  • 能够将裁剪后的图片进行显示
  • 能够对图片进行处理,生成hex数据
  • 能够在桌面新建txt文件,并将hex数据写入其中

004.Qt&Python制作bmp转头文件过程_第1张图片

二、各项功能的实现过程

1.使用文件管理器

通过软件选择jpg或bmp图片

    import tkinter as tk
    from tkinter import filedialog
    
    #将文件路径显示到lineEdit
    root = tk.Tk()#注意k为小写
    root.withdraw()
    f_path = filedialog.askopenfilename()
    self.ui.lineEdit.setText(f_path)

2.对图片进行压缩裁剪

  • 获得图片路径、长、宽
bmpfilepath=self.ui.lineEdit.text()
bmplenght=int(self.ui.lineEdit_2.text())
bmphigh = int(self.ui.lineEdit_3.text())
  • 读取图片
img_screen = cv.imread(bmpfilename)
  • 对图片进行处理
img_screen = np.asarray(img_screen)  # 将截屏转化为array,[[第1行像素],[第2行像素]...]
img_screen = cv.resize(img_screen, (myScreenWidth, myScreenHeight))  # 截切截屏图片为 指定长宽,如128*64
img_screen_play = cv.cvtColor(img_screen_play, cv.COLOR_BGR2GRAY)  # 转为灰度图
img_screen_play = cv.adaptiveThreshold(img_screen_play, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY,
                                               15, 1)  # 二值化
  • 将图片显示到Label
img_pil = Image.fromarray(screen_array)
img_pix = img_pil.toqpixmap()
img_img = img_pil.toqimage()
self.lb_screen.setPixmap(img_pix)
  • 继续对图片进行处理(将255降为1)
screen_array = cv.adaptiveThreshold(screen_array, 1, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY,15, 1)  # 二值化

此时图片已经变为了指定长宽的位图,即一个像素只需用0或1就能表示


3.读取图片的信息,用于生成HEX

  • 完整程序
str_bin_8bit = ''  # 建立空白字符串,用于存放二进制数字串
len_img_screen = int(len(img_screen_01str))  # 图像数据为二维数组[[],[],[]],数组的长度为图片的高度,里面每一个数组存放有图片宽度个0.1数字
str_hex = ''  # 建立空白字符串,用于存放'b2f0......'
# 因为imread读取图片的方式为从左往右,从上至下的方式进行
# 故应当先读取第一行,再读取第二行,依此类推
with open(txtpath, 'w') as f4:
    f4.write("const uint8_t bmp[] PROGMEM = {\n")
f4.close()

for i in range(0, len_img_screen):  # 图片高度64
    str_hex1 = '  '  # 建立空白字符串,用于存放'b2f0......'
    for k in range(0, int(myScreenWidth / 8)):  # 图片宽度128除8,用于取出每一个单一数组中的0.1数字
        for j in range(7 + 8 * k, -1 + 8 * k, -1):  # 低位在前,一次将8位二进制数字(0,1,0,0,1,1,0,1)反向合并为一个字符串'10110010'
            str_bin_8bit = str_bin_8bit + str(img_screen_01str[i][j])
            mumber = int(str_bin_8bit, 2)  # 字符串'00001001'转为10进制数字(178)
        str_bin_8bit = ''  # 二进制数字符串清零,读取下一个8位二进制数
        # 将转化得到的10进制数字(178)转化为'0xb2',确保'0xb2'宽度为2位,同时去除0x,得到b2,合并至字符串str_hex('b2f0......')
        str_hex1 = str_hex1 + '0x' + hex(mumber)[2:].zfill(2) + ','
  • 合并0.1字符串

一次反向读取8个像素信息,从图片左上角开始,逐行读取图片信息

str_bin_8bit = ''  # 建立空白字符串,用于存放二进制数字串
for j in range(7 + 8 * k, -1 + 8 * k, -1):  # 低位在前,一次将8位二进制数字(0,1,0,0,1,1,0,1)反向合并为一个字符串'10110010'
    str_bin_8bit = str_bin_8bit + str(img_screen_01str[i][j])
  • 将0.1字符串转为十六进制
mumber = int(str_bin_8bit, 2)  # 字符串'00001001'转为10进制数字(178)
str_hex1 = str_hex1 + '0x' + hex(mumber)[2:].zfill(2) + ','
  • 将十六进制写入txt文件
txtpath='C:/Users/Administrator/Desktop/TestHex.txt'
with open(txtpath, 'a') as f4:
    f4.write(str_hex1 + '\n')
f4.close()

注意open可选择’a’不清除文件内容继续添加,'w’清空内容后添加

  • 将十六进制在textEdit显示
self.ui.textEdit.append(str_hex1)

三、完整代码

import sys
from PyQt5 import uic
from PyQt5.QtWidgets import QApplication, QWidget,QAction,QMenu

from PIL import ImageGrab, Image
import cv2 as cv
import numpy as np
import tkinter as tk
from tkinter import filedialog



class BmpTransHex(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()
        global txtpath,bmplenght,bmphigh
        txtpath='C:/Users/Administrator/Desktop/TestHex.txt'

    def init_ui(self):
        self.ui = uic.loadUi("./BMP2C.ui")
        self.lb_screen=self.ui.label_2
        te_txt=self.ui.textEdit
        btn_trans = self.ui.pushButton
        btn_trans.clicked.connect(self.screen_pilot)
        btn_open = self.ui.pushButton_2
        btn_open.clicked.connect(self.getfilen)


    def getfilen(self):
        global bmplenght, bmphigh
        self.ui.textEdit.clear()
        root = tk.Tk()
        root.withdraw()
        f_path = filedialog.askopenfilename()
        self.ui.lineEdit.setText(f_path)#将文件路径显示到lineEdit
        bmplenght=int(self.ui.lineEdit_2.text())
        bmphigh = int(self.ui.lineEdit_3.text())
        return f_path


    def Numpy2HexArray(self,img_screen_01str):
        str_bin_8bit = ''  # 建立空白字符串,用于存放二进制数字串
        len_img_screen = int(len(img_screen_01str))  # 图像数据为二维数组[[],[],[]],数组的长度为图片的高度,里面每一个数组存放有图片宽度个0.1数字
        str_hex = ''  # 建立空白字符串,用于存放'b2f0......'
        # 因为imread读取图片的方式为从左往右,从上至下的方式进行
        # 故应当先读取第一行,再读取第二行,依此类推

        with open(txtpath, 'w') as f4:
            f4.write("const uint8_t bmp[] PROGMEM = {\n")
        f4.close()

        for i in range(0, len_img_screen):  # 图片高度64
            str_hex1 = '  '  # 建立空白字符串,用于存放'b2f0......'
            for k in range(0, int(myScreenWidth / 8)):  # 图片宽度128除8,用于取出每一个单一数组中的0.1数字
                for j in range(7 + 8 * k, -1 + 8 * k, -1):  # 低位在前,一次将8位二进制数字(0,1,0,0,1,1,0,1)反向合并为一个字符串'10110010'
                    str_bin_8bit = str_bin_8bit + str(img_screen_01str[i][j])
                mumber = int(str_bin_8bit, 2)  # 字符串'00001001'转为10进制数字(178)
                str_bin_8bit = ''  # 二进制数字符串清零,读取下一个8位二进制数
                # 将转化得到的10进制数字(178)转化为'0xb2',确保'0xb2'宽度为2位,同时去除0x,得到b2,合并至字符串str_hex('b2f0......')
                str_hex1 = str_hex1 + '0x' + hex(mumber)[2:].zfill(2) + ','
            with open(txtpath, 'a') as f4:
                f4.write(str_hex1 + '\n')
            f4.close()
            self.ui.textEdit.append(str_hex1)
            str_hex = str_hex + str_hex1

        with open(txtpath, 'a') as f4:
            f4.write("};\n")
        f4.close()
        return str_hex

    # 截屏或读取照片
    def screen_capture(self,bmpfilename):
        global myScreenWidth, myScreenHeight
        myScreenWidth = bmplenght
        myScreenHeight = bmphigh
        img_screen = cv.imread(bmpfilename)  # imread读取图片的方式为从左往右,从上至下的方式读取每个像素的信息,存放到[[第1行像素],[第2行像素]...]
        img_screen = np.asarray(img_screen)  # 将截屏转化为array,[[第1行像素],[第2行像素]...]
        img_screen = cv.resize(img_screen, (myScreenWidth, myScreenHeight))  # 截切截屏图片为128*64
        return img_screen  # 返回截屏图片

    # 截屏或读取照片,用于上位机显示
    def screen_capture_play(self,bmpfilename):
        img_screen_play = self.screen_capture(bmpfilename)
        img_screen_play = cv.cvtColor(img_screen_play, cv.COLOR_BGR2GRAY)  # 转为灰度图
        img_screen_play = cv.adaptiveThreshold(img_screen_play, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY,
                                               15, 1)  # 二值化
        return img_screen_play  # 返回截屏图片



    def screen_pilot(self):
        bmpfilepath=self.ui.lineEdit.text()
        screen_array = self.screen_capture_play(bmpfilepath)
        img_pil = Image.fromarray(screen_array)
        img_pix = img_pil.toqpixmap()
        img_img = img_pil.toqimage()
        self.lb_screen.setPixmap(img_pix)
        screen_array = cv.adaptiveThreshold(screen_array, 1, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY,15, 1)  # 二值化
        img_screen=self.Numpy2HexArray(screen_array)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = BmpTransHex()
    w.ui.show()
    sys.exit(app.exec_())

你可能感兴趣的:(Pyqt5,python,qt,开发语言)