# from UI.matching_photos.matching_photos import Ui_Form as matching_photos_Ui_Form import os from UI.matching_photos.matching_and_cutout_photos import ( Ui_Form as matching_photos_Ui_Form, ) from import_qt_mode import * import settings from collections import defaultdict from module.service.base_deal_image import BaseDealImage from module.view_control.generate_goods_art_no_table.module_generate_goods_art_no_table import GenerateGoodsArtNoTable from module.view_control.matching_photos.data import DataModeMatchPhoto from module.view_control.manual_image_matching.m_image_matching_cotrol import MainMatchingWindow from PySide6.QtGui import QPixmap from PIL import Image import io import threading import shutil import time from module.base_mode.pic_deal import PicDeal # import exifread from module.base_mode.base import * from module.view_control.MineQWidget import MineQWidget, DialogShow from threading import Event from functools import partial from UI.matching_photos.temp_item import Ui_Form as UI_temp_item """ 照片自动货号匹配 将图片放置在指定文件夹下,并自动对应不同的货号进行整理 """ class MatchingPhotos(MineQWidget): progress_sign = Signal(dict) info_sign = Signal(str) text_show = Signal(str) def __init__(self): super().__init__() self.image_dir = settings.PhotoImageDir self.ui = matching_photos_Ui_Form() self.ui.setupUi(self) # 0禁用 1进行中 2已结束 self.state = 2 self.event = Event() self.goods_images_count_dict = defaultdict(int) self.data_match_photo = DataModeMatchPhoto() self.excel_path = "" # 上次使用的详情模板 self.last_temp = settings.MATCHING_LAST_TEMP # 指定单独处理的颜色文件夹 self.special_goods_art_no_folder = [] self.init() self.show() def init(self): # 文本 self.ui.textBrowser.clear() text = """请将capture One 加工后的图片放在指定目录下(目录为当前文件夹下的{}/data文件夹),务必确保导出的图片有拍摄时间信息。""".format(os.getcwd()) self.ui.textBrowser.append(text) self.ui.tabWidget.setCurrentIndex(0) # 页面视图1 self.ui.stackedWidget.setCurrentIndex(0) self.text_show.connect(self.append_text_to_browser) self.show_img_dir() self.ui.select_path.mousePressEvent = self.change_img_dir self.ui.progressBar.setValue(0) self.ui.progressBar.setMaximum(100) self.ui.progressBar.setValue(0) self.ui.progressBar.hide() self.ui.line_image_pos.setText(settings.cutimage_dict['imageorder']) self.ui.need_resize.setText(settings.cutimage_dict['resize_image_view']) self.ui.check_image_total.setChecked(bool(settings.cutimage_dict['is_check_number'])) self.ui.check_is_pass.setChecked(bool(settings.cutimage_dict['is_filter'])) print(settings.cutimage_dict) if settings.DEFAULT_CUTOUT_MODE == '普通抠图': self.ui.cutout_nomal.setChecked(True) elif settings.DEFAULT_CUTOUT_MODE == ' 精细化抠图': self.ui.cutout_exquisite.setChecked(True) if not bool(settings.IsExquisiteMode): self.ui.cutout_exquisite.setEnabled(False) # 展示是否指定内容抠图 self.ui.is_do_other.toggled.connect(self.change_do_special_treatment) self.change_do_special_treatment() self.progress_sign.connect(self.show_progress) self.ui.run.clicked.connect(self.run_image_cut) # 抠图与主图加工 self.ui.run_2.clicked.connect(self.run_matching) # 匹配图片 self.ui.back.clicked.connect(self.back) # 页面视图2 self.ui.back.hide() self.set_logo_selected() # 手动匹配图片 self.ui.manual_matching_pic.mousePressEvent = self.manual_matching_pic_mousePressEvent # 切换是否特殊处理的开关 def change_do_special_treatment(self, *args): if self.ui.is_do_other.isChecked(): self.ui.show_deal_condition.show() else: self.ui.show_deal_condition.hide() # 设置选择logo模板 def set_logo_selected(self): logo_root_path = "" if settings.PROJECT == "红蜻蜓": logo_root_path = r"{}\resources\LOGO\HQT".format(os.getcwd()) elif settings.PROJECT == "惠利玛": if "小苏" in settings.Company: logo_root_path = r"{}\resources\LOGO\xiaosushuoxie".format(os.getcwd()) if "惠利玛" in settings.Company: logo_root_path = r"{}\resources\LOGO\HLM".format(os.getcwd()) self.logo_path_dict = {"请选择": "", "无logo": ""} if logo_root_path: if os.path.exists(logo_root_path): image_list = get_images(logo_root_path) print("111111111 image_list", image_list) for image_data in image_list: self.logo_path_dict[image_data["file_name"]] = image_data["file_path"] self.ui.logo_select_ui.addItems([x for x in self.logo_path_dict]) self.ui.logo_select_ui.setCurrentText("请选择") if settings.MATCHING_LAST_LOGO_TEMP: if settings.MATCHING_LAST_LOGO_TEMP in [x for x in self.logo_path_dict]: self.ui.logo_select_ui.setCurrentText(settings.MATCHING_LAST_LOGO_TEMP) def manual_matching_pic_mousePressEvent(self, event): if not self.image_dir: a = QMessageBox.question( self, "确认", "请先选择目标文件夹", QMessageBox.Yes, ) return self.manual = MainMatchingWindow(root_path=self.image_dir) @Slot() def on_stop_clicked(self): self.event.set() pass def change_img_dir(self, *args): folder = QFileDialog.getExistingDirectory(self, "选取文件夹", "./") print(folder) settings.set_config(data_dict={"photo_image_dir": folder}) # 清空已特殊选择等处理 self.ui.is_do_other.setChecked(False) self.show_img_dir(image_dir=folder) def show_img_dir(self, image_dir=None): if image_dir: self.image_dir = image_dir else: self.image_dir = settings.PhotoImageDir if self.image_dir: self.ui.path_name.show() self.ui.path_name.setText(self.image_dir) else: self.ui.path_name.hide() def show_progress(self, data): progress_bar_value = data["progress_bar_value"] self.ui.progressBar.setValue(progress_bar_value) def check(self): _path = self.image_dir + "/历史" if not os.path.exists(_path): os.mkdir(_path) return True def set_state(self, state_value: int): # 0禁用 1进行中 2已结束 if state_value not in [0, 1, 2]: return self.state = state_value if self.state == 0: self.ui.stackedWidget.setCurrentIndex(0) if self.state == 1: self.ui.stackedWidget.setCurrentIndex(1) self.ui.back.hide() self.ui.stop.show() self.ui.textBrowser_4.clear() self.ui.textBrowser_4.show() self.event.clear() if self.state == 2: self.ui.stackedWidget.setCurrentIndex(1) self.ui.back.show() self.ui.stop.hide() def back(self): self.ui.stackedWidget.setCurrentIndex(0) self.ui.back.hide() self.ui.run.show() self.ui.stop.hide() self.ui.textBrowser_4.clear() self.ui.textBrowser_4.hide() def check_first_call_back(self, data): # 首次数据校验的信息返回 # self.show_message(text="22222222222222222222222") # QMessageBox.critical(self, "警告", "1111111", QMessageBox.Ok) code = data["code"] if data["message"]: button_1, button_2, button_3 = None, None, None button_1 = "移除" button_2 = "继续" text = data["message"] my_dialog = DialogShow(self, text=text, button_1=button_1, button_2=button_2) ret = my_dialog.exec() print(my_dialog.flag_name) if "移除" in my_dialog.flag_name: pass if "继续" in my_dialog.flag_name: pass def check_test(self, test): print(test) time.sleep(3) return_data = {"code": 99, "message": "messagemessagemessagemessagemessagemessagemessage", "data": {"error_folder_list": [], "goods_no_dict": {}, "succeed_folder_list": [], }} return return_data def run_matching11111(self, *args): func = partial(self.check_test, test=1111111) self.do_thread_run(func=func, call_back=self.check_first_call_back, time_out=30) def run_matching(self, *args): if settings.PROJECT == "红蜻蜓": if not settings.IsLogin: a = QMessageBox.question( self, "确认", "请先进行登录红蜻蜓账号", QMessageBox.Yes | QMessageBox.No, ) return self.set_state(state_value=1) self.goods_images_count_dict = {} self.goods_images_count_dict = defaultdict(int) self.do_thread_run(func=self.run_by_thread, call_back=self.matchingCallBack, time_out=60) # self.t = threading.Thread(target=self.run_by_thread, args=()) # self.t.start() def matchingCallBack(self, data: dict): self.set_state(2) if data['code'] == 0: self.show_progress_detail('处理完成') button_1, button_2, button_3 = None, None, None button_1 = "去抠图" text = '移动完成' my_dialog = DialogShow(self, text=text, button_1=button_1, button_2=button_2) ret = my_dialog.exec() if "去抠图" in my_dialog.flag_name: self.back() self.ui.tabWidget.setCurrentIndex(1) path = os.getcwd() + "/" + data['target_path'] self.ui.path_name.setText(path) else: self.show_progress_detail(data['msg']) text = data['msg'] my_dialog = DialogShow(self, text=text) ret = my_dialog.exec() def run_image_cut(self, *args): if not settings.IsLogin: QMessageBox.question( self, "确认", "请先登录", QMessageBox.Yes | QMessageBox.No ) return logo_name = self.ui.logo_select_ui.currentText() if logo_name == "请选择": QMessageBox.question( self, "确认", "请先选择logo模板", QMessageBox.Yes | QMessageBox.No ) return if self.ui.cutout_exquisite.isChecked() and not bool(settings.IsExquisiteMode): QMessageBox.question( self, "确认", "暂无 精细化抠图权限", QMessageBox.Yes | QMessageBox.No ) return self.set_state(state_value=1) self.t = threading.Thread(target=self.threadImageCut, args=()) self.t.start() def threadImageCut( self, ): image_dir = self.ui.path_name.text() baseDealImage = BaseDealImage(image_dir=image_dir) image_order = self.ui.line_image_pos.text() is_check_number = self.ui.check_image_total.isChecked() is_filter = self.ui.check_is_pass.isChecked() resize_image_view = self.ui.need_resize.text() logo_name = self.ui.logo_select_ui.currentText() settings.MATCHING_LAST_LOGO_TEMP = logo_name logo_path = self.logo_path_dict[logo_name] cutout_mode = '1' if self.ui.cutout_exquisite.isChecked(): cutout_mode = '2' configData = { 'imageorder': image_order, 'resize_image_view': resize_image_view, 'is_check_number': str(is_check_number), 'is_filter': str(is_filter), 'cutout_mode': str(cutout_mode), 'matching_mode_last': settings.MATCHING_MODE_LAST, "matching_last_temp": self.last_temp, "matching_last_logo_temp": logo_name, } settings.cutimage_dict['imageorder'] = image_order settings.cutimage_dict['resize_image_view'] = resize_image_view settings.cutimage_dict['is_check_number'] = str(is_check_number) settings.cutimage_dict['is_filter'] = str(is_filter) settings.cutimage_dict['cutout_mode'] = str(cutout_mode) settings.set_config(data_dict=configData, section='cutimage') # =================整理要处理的货号文件夹数据================= is_ok = True all_goods_art_no_folder_data = get_all_goods_art_no_folder(path=image_dir) todo_goods_art_no_folder_name_list = [] if not self.ui.is_do_other.isChecked(): todo_goods_art_no_folder_name_list = [x["folder_name"] for x in all_goods_art_no_folder_data] else: is_filter = False specified_goods_art_no_folder = self.ui.special_goods_art_no_folder_line.text() specified_goods_art_no_folder = specified_goods_art_no_folder.strip() specified_goods_art_no_folder = specified_goods_art_no_folder.replace(",", ",") if not specified_goods_art_no_folder: self.show_progress_detail('请手动输入文件夹名称(多选),或关闭指定文件夹模式') is_ok = False else: specified_goods_art_no_folder_list = specified_goods_art_no_folder.split(",") all_folder_name_list = [x["folder_name"] for x in all_goods_art_no_folder_data] for goods_art_no_folder_name in specified_goods_art_no_folder_list: if goods_art_no_folder_name: if goods_art_no_folder_name not in all_folder_name_list: self.show_progress_detail('文件夹:{},在您选的目录下不存在'.format(goods_art_no_folder_name)) is_ok = False else: todo_goods_art_no_folder_name_list.append(goods_art_no_folder_name) if not is_ok: self.set_state(state_value=2) return # 清空指定文件夹的已抠图文件 print("todo_goods_art_no_folder_name_list",todo_goods_art_no_folder_name_list) if self.ui.is_do_other.isChecked(): if self.ui.is_clean_cutout_image.isChecked(): for goods_art_no_folder_name in todo_goods_art_no_folder_name_list: goods_art_no_folder_path = "{}/{}/原始图_已抠图".format(image_dir, goods_art_no_folder_name) print("goods_art_no_folder_path",goods_art_no_folder_path) if os.path.exists(goods_art_no_folder_path): remove_all_file(goods_art_no_folder_path) if settings.IS_TEST: result = baseDealImage.cutoutImage( image_dir=image_dir, todo_goods_art_no_folder_name_list=todo_goods_art_no_folder_name_list, image_order=image_order, is_check_number=is_check_number, is_filter=is_filter, resize_image_view=resize_image_view, callback_func=self.show_progress_detail, event=self.event, cutout_mode=cutout_mode, logo_path=logo_path, ) if "code" in result and result['code'] != 0: self.show_progress_detail(result['msg']) else: self.show_progress_detail('处理完成') else: try: result = baseDealImage.cutoutImage( image_dir=image_dir, image_order=image_order, todo_goods_art_no_folder_name_list=todo_goods_art_no_folder_name_list, is_check_number=is_check_number, is_filter=is_filter, resize_image_view=resize_image_view, callback_func=self.show_progress_detail, event=self.event, cutout_mode=cutout_mode, logo_path=logo_path, ) if "code" in result and result['code'] != 0: self.show_progress_detail(result['msg']) else: self.show_progress_detail('处理完成') except BaseException as e: print(e) self.show_progress_detail('程序异常') self.set_state(state_value=2) def show_progress_detail(self, text): self.text_show.emit(text) def append_text_to_browser(self, text): self.ui.textBrowser_4.append(text) def run_by_thread(self): image_dir = "{}/data".format(os.getcwd()) baseDealImage = BaseDealImage(image_dir=image_dir) # result = baseDealImage.dealMoveImage( # image_dir=settings.PhotoOutputDir, callback_func=self.show_progress_detail # ) result = baseDealImage.dealMoveImage( image_dir=image_dir, callback_func=self.show_progress_detail ) return result def run_by_thread_backup(self): if not self.check(): return # 遍历目标文件夹,获取有拍摄信息的图片,并按拍摄时间排序 files = os.listdir(self.image_dir) _Type = [".png", ".PNG", ".jpg", ".JPG", ".gif", ".GIF", ".jpge", ".JPGE"] original_photo_list = [] # 原始图片列表 for file in files: # -----图片清洗 file_path = self.image_dir + "/" + file if os.path.isdir(file_path): # 忽略文件夹 continue file_name, e = os.path.splitext(file) if e not in _Type: # 非图片进行移除 shutil.move(file_path, self.image_dir + "/历史/" + file) continue date_time_original = self.get_date_time_original( file_path ) # 获取照片拍照时间 if date_time_original: # 基于照片的时间,与数据库匹配goods_art_no _data = self.data_match_photo.get_goods_art_no(date_time_original) if _data: # 能匹配上数据库 goods_art_no, image_index, image_deal_mode = _data print( "与数据库匹配goods_art_no", file_name, date_time_original, goods_art_no, ) original_photo_list.append( { "file_path": file_path, "file": file, "date_time_original": date_time_original, "goods_art_no": goods_art_no, "image_index": image_index, "real_goods_art_no": "", "real_goods_number": "", } ) else: # 匹配不上报错 self.show_progress_detail( "图片:{} 无法对应货号,不做处理".format(file) ) # shutil.move(photo_dict["file_path"], self.image_dir + "/历史/" + photo_dict["file"]) continue else: shutil.move(file_path, self.image_dir + "/历史/" + file) if not original_photo_list: self.show_progress_detail("没有任何匹配的图片~") self.set_state(state_value=2) return if settings.PROJECT == "红蜻蜓": # 批量请求货号图信息 goods_art_no_list = [x["goods_art_no"] for x in original_photo_list] goods_art_no_list = list(set(goods_art_no_list)) goods_art_no_list = [x for x in goods_art_no_list if "NUM" not in x] if goods_art_no_list: goods_art_no_dict = ( self.data_match_photo.get_data_from_hqt_with_goods_art_no( goods_art_no_list=goods_art_no_list ) ) for i in original_photo_list: if i["goods_art_no"] in goods_art_no_dict: i["real_goods_art_no"] = i["goods_art_no"] i["real_goods_number"] = "NUM{}".format( goods_art_no_dict[i["goods_art_no"]]["编号"] ) # 批量请求编号对应信息 goods_number_list = [x["goods_art_no"] for x in original_photo_list] goods_number_list = list(set(goods_number_list)) goods_number_list = [x for x in goods_number_list if "NUM" in x] if goods_number_list: goods_number_dict = self.data_match_photo.get_data_from_hqt( goods_number_list=goods_number_list ) for i in original_photo_list: if i["goods_art_no"] in goods_number_dict: i["real_goods_number"] = i["goods_art_no"] i["real_goods_art_no"] = goods_number_dict[i["goods_art_no"]][ "商品货号" ] # 排序需要基于拍照的文件序号进行处理 original_photo_list.sort( key=lambda x: "{}-{}-{}".format( x["goods_art_no"], x["image_index"], x["file"] ) ) print(original_photo_list) # 对有拍摄信息的图片进行数据库比对,如有比对上,则移动至货号文件夹,否则移入历史文件夹 total_num = len(original_photo_list) # 当天日期作为文件夹 seconds = time.time() output_path = "output/{f_name}".format( f_name=time.strftime("%Y-%m-%d", time.localtime(seconds)) ) # 遍历每个匹配好的数据进行处理 n = 0 for photo_dict in original_photo_list: n += 1 # 进度条 goods_art_no = photo_dict["goods_art_no"] original_image_path = photo_dict["file_path"] # 输出货号文件夹 if photo_dict["real_goods_art_no"]: goods_art_no = "{}@{}".format( photo_dict["real_goods_art_no"], photo_dict["real_goods_number"] ) goods_art_no_path = "{output_path}/{goods_art_no}".format( output_path=output_path, goods_art_no=goods_art_no ) # 创建货号下的一系列文件夹 self.create_folder(goods_art_no_path) # 重命名并进行移动 self.move_images( goods_art_no, goods_art_no_path, original_image_path ) # 货号、货号文件路径、原始图路径 self.progress_sign.emit( {"type": "移动原始图片", "progress_bar_value": int(n / total_num * 100)} ) self.show_progress_detail( "货号{} 相关文件夹创建完成,已移动原图~".format(goods_art_no) ) if n != 0: # if settings.MattingPics: # # 检查所有未处理的货号文件夹,查看是否有完成图片加工处理 # self.deal_images() # 自动生成一个货号表 print("output_path", output_path) GenerateGoodsArtNoTable.deal(output_path) # 完成处理 self.set_state(state_value=2) def move_images(self, goods_art_no, goods_art_no_path, old_image_path): """ 步骤: 1、移动到原始图 Args: goods_art_no: goods_art_no_path: old_image_path: Returns: """ # 移动到原始图 file = os.path.split(old_image_path)[1] # 扩展名 e = os.path.splitext(file)[1] # 获取图片序列 self.goods_images_count_dict[goods_art_no] += 1 # A9999(1).jpg new_file_name = "{}({})".format( goods_art_no, self.goods_images_count_dict[goods_art_no] ) original_image_path = "{}/原始图/{}{}".format( goods_art_no_path, new_file_name, e ) # 移动图片 shutil.move(old_image_path, original_image_path) def deal_images(self): """ 2、压缩并上传平台获取抠图 3、抠图处理成白底图 4、做成800*800/200*200 :return: """ output_path = "output" """ 扫描文档,检查有哪些需要进行抠图等处理 """ to_do_images_total = 0 for _date_folder in os.listdir(output_path): if not os.path.isdir("{}/{}".format(output_path, _date_folder)): continue for goods_art_no_folder in os.listdir( "{}/{}".format(output_path, _date_folder) ): # print(goods_art_no_folder) all_original_images = os.listdir( "{}/{}/{}/原始图".format( output_path, _date_folder, goods_art_no_folder ) ) all_moved_images = [ os.path.splitext(x)[0] for x in os.listdir( "{}/{}/{}/原始图_已抠图".format( output_path, _date_folder, goods_art_no_folder ) ) ] for file in all_original_images: if os.path.splitext(file)[0] not in all_moved_images: print("----------》", goods_art_no_folder, file) to_do_images_total += 1 if to_do_images_total > 0: self.progress_sign.emit( {"type": "处理图片 抠图、加工等", "progress_bar_value": 0} ) else: return True """开始处理抠图等处理""" n = 0 for _date_folder in os.listdir(output_path): # 过滤非文件夹的文件 if not os.path.isdir("{}/{}".format(output_path, _date_folder)): continue # 扫描每个货号 for goods_art_no_folder in os.listdir( "{}/{}".format(output_path, _date_folder) ): all_original_images = os.listdir( "{}/{}/{}/原始图".format( output_path, _date_folder, goods_art_no_folder ) ) all_moved_images = [ os.path.splitext(x)[0] for x in os.listdir( "{}/{}/{}/原始图_已抠图".format( output_path, _date_folder, goods_art_no_folder ) ) ] for file in all_original_images: original_image_path = "{}/{}/{}/原始图/{}".format( output_path, _date_folder, goods_art_no_folder, file ) file_name = os.path.splitext(file)[0] if file_name not in all_moved_images: print("上传平台获取抠图结果----------》", file) goods_art_no_folder_path = "{}/{}/{}".format( output_path, _date_folder, goods_art_no_folder ) pic_deal = PicDeal() # 上传平台获取抠图结果 original_move_bg_image_path = "{}/原始图_已抠图/{}{}".format( goods_art_no_folder_path, file_name, ".png" ) if pic_deal.remove_bg( in_path=original_image_path, out_path=original_move_bg_image_path, ): self.show_progress_detail( "货号图{} 已完成抠图处理~".format(file_name) ) # 抠图处理成白底图 800*800 out_800_path = "{}/800x800/{}{}".format( goods_art_no_folder_path, file_name, ".jpg" ) pic_deal.create_800image( image_path=original_move_bg_image_path, out_path=out_800_path, ) # 抠图处理成白底图 200*200 out_200_path = "{}/200images/{}{}".format( goods_art_no_folder_path, file_name, ".jpg" ) pic_deal.resize_and_save( image_path=out_800_path, out_path=out_200_path, width=200, ) self.show_progress_detail( "货号图{} 已完成800*800图片和200*200图片制作~".format( file_name ) ) else: self.show_progress_detail( "货号图{} 抠图处理失败~".format(file_name) ) # 完成处理的图片进度 n += 1 self.progress_sign.emit( { "type": "处理图片 抠图、加工等", "progress_bar_value": int(n / to_do_images_total * 100), } ) def create_folder(self, path): def check_folder(__path): if not os.path.exists(__path): os.makedirs(__path) return False return True # 文件夹不存在,创建货号子集文件夹 if not check_folder(path): for name in ["原始图", "原始图_已抠图", "800x800", "200images"]: other_path = path + "/" + name check_folder(other_path) def get_date_time_original(self, file_path): with open(file_path, "rb") as file_data: tags = exifread.process_file(file_data) if "EXIF DateTimeOriginal" in tags: return str(tags["EXIF DateTimeOriginal"]) else: return False class TempItem(QWidget): select_sign = Signal(str) def __init__(self, parent, _id, image_path): super().__init__(parent) self.ui = UI_temp_item() self.ui.setupUi(self) self.image_path = image_path self.id = _id self.is_select = False self.init() def init(self): self.ui.label.mousePressEvent = self.pic_show self.ui.radioButton.clicked.connect(self.select) self.set_label_image() def cancel_select(self, *args): self.is_select = False self.ui.radioButton.setChecked(False) def select(self, *args): self.is_select = True self.ui.radioButton.setChecked(True) self.select_sign.emit(self.id) def pic_show(self, *args, **kwargs): if os.path.exists(self.image_path): im = Image.open(self.image_path) threading.Thread(target=im.show, args=()).start() def set_label_image(self): if not os.path.exists(self.image_path): return try: bytes_io = io.BytesIO() w, h = self.ui.image_show.width(), self.ui.image_show.height() _img_raw = Image.open(self.image_path) _img_raw = self.to_resize(_img_raw, width=w * 2) _img_raw = _img_raw.crop(box=(0, 0, w * 2, h * 2)) # _img_raw.thumbnail((w * 2, int(_img_raw.height * w * 2 / _img_raw.width))) # img_raw = _img_raw.resize(size=(w, h)) _img_raw.save(bytes_io, "JPEG") icon = QPixmap() # icon.loadFromData(img) icon.loadFromData(bytes_io.getvalue()) icon = icon.scaled( self.ui.image_show.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation ) self.ui.image_show.setPixmap(icon) # self.mousePressEvent = lambda x: self.show_one_data(row) except: pass def to_resize(self, _im, width=None, high=None): _im_x, _im_y = _im.size if width and high: if _im_x >= _im_y: high = None else: width = None if width: re_x = int(width) re_y = int(_im_y * re_x / _im_x) else: re_y = int(high) re_x = int(_im_x * re_y / _im_y) _im = _im.resize((re_x, re_y)) return _im