首页 > 编程语言 >python 图片查看器

python 图片查看器

时间:2024-09-30 21:23:49浏览次数:7  
标签:查看器 python image show file format path self 图片

 

#coding=utf-8

# tkinter的Label控件以及三种布局管理方法 
# https://www.cnblogs.com/jackie-lee/p/16191662.html 

# python 对话框图形界面显示图片
# https://blog.csdn.net/SAPmatinal/article/details/131818285  

# 菜单设置
# https://blog.csdn.net/weixin_42272768/article/details/100808828   

#opencv PIL格式互相转换
# https://blog.csdn.net/qq_19707521/article/details/78367617

#Pyinstaller 打包exe后,打开出现can‘t find package tkdnd 报错
#https://blog.csdn.net/qq_43079386/article/details/139725149


#1 BUILD
# pyinstaller -F --windowed oplus_imageview.py --paths "C:\Program Files\Python311\lib\site-packages" --add-data "C:\Program Files\Python311\lib\site-packages\tkinterdnd2;tkinterdnd2"  --hidden-import=tkinterdnd2 --hidden-import=tkdnd --clean
# 2 DEBUG
# 如果在打包过程中遇到问题,可以将输出重定向到一个日志文件中,以便详细检查:
# pyinstaller -F ccc.py --paths C:\Program Files\Python311\lib\site-packages --add-data "C:\Program Files\Python311\lib\site-packages\tkinterdnd2;tkinterdnd2" --hidden-import=tkinterdnd2 --hidden-import=tkdnd --clean > build_log.txt 2>&1
# 这样所有输出(包括错误信息)都会保存到 build_log.txt 文件中,你可以查看该文件以获取详细的调试信息。


import tkinter as tk  
import tkinter.filedialog
from tkinter import messagebox
from tkinterdnd2 import DND_FILES, TkinterDnD  
from PIL import Image, ImageTk  
import cv2
import numpy as np
import os
import re  

image_show_width = 1024
image_show_height = 768
window_width = image_show_width+100
window_height = image_show_height+100

def NV21_P8_CONVERT_BGR(yuv_path,width,height):
    with open(yuv_path, 'rb') as f:
        yuvdata = np.fromfile(f, dtype=np.uint8)
    cv_format=cv2.COLOR_YUV2BGR_NV21
    bgr_img = cv2.cvtColor(yuvdata.reshape(((int)(height*3/2), width)), cv_format)                    
    return bgr_img

def NV21_P010_CONVERT_BGR(file_path, width10, height10):
    width8 = int(width10 / 2)
    height8 = height10
    databuf10 = np.fromfile(file_path, dtype=np.uint16)
    databuf8 = (databuf10 / 4).astype(np.uint8);
    cv_format=cv2.COLOR_YUV2BGR_NV12
    bgr_img = cv2.cvtColor(databuf8.reshape(((int)(height8*3/2), width8)), cv_format)                    
    return bgr_img

def find_number_x_number(s):  
    # 定义正则表达式模式  
    # pattern = r'\b(\d+)x(\d+)\b'  

    # input_string = "IMG20240926193220_wh=4096x3072_ss=4096x3072_idx0_beforebeauty_doBokehEffect"
    pattern = r'ss\=(\d+)x(\d+)\_'   #find _ss=4096x3072_
    # 使用 re.findall() 查找所有匹配的内容  
    matches = re.findall(pattern, s) 

    if len(matches) == 0:
        # input_string = "IMG20240926193220_4096x3072_idx0_beforebeauty_doBokehEffect"
        pattern = r'\_(\d+)x(\d+)\_'  #find _4096x3072_
        # 使用 re.findall() 查找所有匹配的内容  
        matches = re.findall(pattern, s) 

    return matches  

def find_yuvimage_size(input_string):
    results = find_number_x_number(input_string)  
    width = -1
    height = -1
    for match in results:  
        # print(f"{match[0]}x{match[1]}") 
        width = int(match[0])
        height = int(match[1])
    return width, height

class ImageDropApp:  
    def __init__(self, root):  
        self.root = root  
        self.root.title("图片查看器--IMAGE_VIEW_1.0")  
        self.root.geometry(f"{window_width}x{window_height}+100+100")  

        self.image_has_open = False

        # 创建标签用于显示图片    
        self.label = tk.Label(root, text="拖拽图片到这里", width=image_show_width, height=image_show_height, bg="lightgrey")  
        self.label.pack(padx=0, pady=0, side="left", fill="both", expand = True)

        # 注册拖放功能  
        self.label.drop_target_register(DND_FILES)  
        self.label.dnd_bind('<<Drop>>', self.on_drop)  

        #设置打开关闭菜单
        menubar = tk.Menu(root)
        filemenu=tk.Menu(menubar,activebackground='blue',tearoff=False)

        filemenu.add_command(label='打开文件',command=self.open_file)
        filemenu.add_command(label='另存文件',command=self.save_file_choosefolder)
        menubar.add_cascade(label='文件', menu=filemenu)
        menubar.add_command(label='退出',command=root.destroy)

        root.bind('<Control-o>',self.open_file)
        root.config(menu=menubar)

    def winshow_image(self, image_path):
        self.current_image_path = image_path    
        self.image_format = "." + image_path.split('.')[-1]
        if self.image_format == ".yuv":
            #fine image size
            self.image_srcwidth, self.image_srcheight = find_yuvimage_size(image_path)
            print("image src size " + str(self.image_srcwidth) + "x" + str(self.image_srcheight))

            if self.image_srcwidth == -1:
                messagebox.showinfo("prompt","not find yuv image size")

            #存储opencv原图
            if self.image_srcwidth > 6000:
                print("input p010 yuv ")
                self.save_image_cv = NV21_P010_CONVERT_BGR(self.current_image_path, self.image_srcwidth, self.image_srcheight)
                self.image_srcwidth = int(self.image_srcwidth / 2)
                print("image src size p010_TO_p8 " + str(self.image_srcwidth) + "x" + str(self.image_srcheight))
            else:
                self.save_image_cv = NV21_P8_CONVERT_BGR(self.current_image_path, self.image_srcwidth, self.image_srcheight)        

            #opencv图像转换为PTL图像进行显示
            self.show_image_PIL = Image.fromarray(cv2.cvtColor(self.save_image_cv,cv2.COLOR_BGR2RGB))
            self.show_image_PIL = self.show_image_PIL.resize((image_show_width, image_show_height))#, Image.ANTIALIAS) 

            # 将图片转换为Tkinter格式  
            photo = ImageTk.PhotoImage(self.show_image_PIL)  

            # 更新标签内容以显示图片  
            self.label.config(image=photo)  
            self.label.image = photo  # 保持引用以避免被垃圾回收  
            self.image_has_open = True

        else:
            image = Image.open(image_path)  
            self.image_srcwidth = image.size[0]
            self.image_srcheight = image.size[0]
            print("image src size " + str(self.image_srcwidth) + "x" + str(self.image_srcheight))

            #存储opencv原图
            self.save_image_cv = cv2.cvtColor(np.asarray(image),cv2.COLOR_RGB2BGR)  

            # 调整图片大小以适应标签  
            self.show_image_PIL = image.resize((image_show_width, image_show_height))#, Image.ANTIALIAS)  

            # 将图片转换为Tkinter格式  
            photo = ImageTk.PhotoImage(self.show_image_PIL)  

            # 更新标签内容以显示图片  
            self.label.config(image=photo)  
            self.label.image = photo  # 保持引用以避免被垃圾回收  
            self.image_has_open = True


    def on_drop(self, event):  
        # 获取文件路径  
        file_path = event.data
        #如果文件路径出现中文"新建文件夹",file_path会增加{file_path}
        if(len(file_path)> 2):
            if file_path[0] == "{" and file_path[-1] == "}":
                print("chinese path " + file_path)
                file_path = file_path[1:-1]
                print("remove {} in path " + file_path)
 
        if file_path.endswith(('.yuv', '.png', '.jpg', '.jpeg', '.gif', '.bmp')):  
            print("find " + file_path)
            self.winshow_image(file_path) 
        else:
            print(file_path + " format not support")
            messagebox.showinfo("prompt","this file format not support, please choose format like these , \
                                '.yuv', '.png', '.jpg', '.jpeg', '.gif', '.bmp'")


    def open_file(self):
        file_path = tkinter.filedialog.askopenfilename()
        if file_path.endswith(('.yuv', '.png', '.jpg', '.jpeg', '.gif', '.bmp')):  
            print("find " + file_path)
            self.winshow_image(file_path) 
        else:
            print(file_path + " format not support")
            messagebox.showinfo("prompt","this file format not support, please choose format like these , \
                                '.yuv', '.png', '.jpg', '.jpeg', '.gif', '.bmp'")

    def save_file_choosefolder(self):
        if self.image_has_open:
            defaultextension = ".png"
            init_current_image_name = self.current_image_path.replace(self.image_format, defaultextension)
            # print("src file " + init_current_image_name)
            savefolderpath = tkinter.filedialog.asksaveasfilename(
                                title="保存图像",  
                                defaultextension=".png",  
                                initialfile=os.path.basename(init_current_image_name),  
                                initialdir=os.path.dirname(self.current_image_path),  
                                filetypes=(("PNG files", "*.png"), ("JPEG files", "*.jpg"), ("All files", "*.*")))

            image_save_format = "." + savefolderpath.split('.')[-1]

            if savefolderpath:   
                print("save file " + savefolderpath)
                # image = cv_imread(self.current_image_path)
                cv2.imencode(image_save_format, self.save_image_cv)[1].tofile(savefolderpath)
        else:
            print("please open image file") 
            messagebox.showinfo("prompt","please open image file")



if __name__ == "__main__":  
    root = TkinterDnD.Tk()  
    app = ImageDropApp(root)  
    root.mainloop()  

 

标签:查看器,python,image,show,file,format,path,self,图片
From: https://www.cnblogs.com/adong7639/p/18442460

相关文章

  • python远程登录Admin.NET
    defgetCipherPassword(password):private_key='8EDB615B1D48B8BE188FC0F18EC08A41DF50EA731FA28BF409E6552809E3A111'#这里假设你已经有了私钥字符串,实际中需通过特定方法生成public_key='0484C7466D950E120E5ECE5DD85D0C90EAA85081A3A2BD7C57AE6DC822EFCCBD66......
  • CNN模型实现CIFAR-10彩色图片识别
    关于深度实战社区我们是一个深度学习领域的独立工作室。团队成员有:中科大硕士、纽约大学硕士、浙江大学硕士、华东理工博士等,曾在腾讯、百度、德勤等担任算法工程师/产品经理。全网20多万+粉丝,拥有2篇国家级人工智能发明专利。社区特色:深度实战算法创新获取全部完整项目......
  • python 敏感词识别处理
    定义词库1、敏感词库(black_word.txt)2、jeiba分词库(jieba_db_file.txt)(我这简单的就用文本来记录了,可以将这些词库都通过数据库来存储,对企业来说通过可视化页面去增删改可能会更方便运营处理)代码示例importosimportjiebablack_word_list=list()defload_word......
  • SCIE1000  Python and Communication
    SCIE1000 Semester 2, 2024Python and Communication Assignment1    The scenarioA new public science museum in St Lucia is developing an exhibit. A feature ofthe museum is that each exhibit item is accompanied by two expla......
  • 【python开发环境搭建】
    虽然网上有很多python开发环境搭建的文章,不过重复造轮子还是要的,记录一下过程,方便自己以后配置,也方便正在学习中的同事配置他们的环境。1.准备好安装包1)上python官网下载python运行环境(DownloadPython|Python.org),目前比较稳定的是python-3.5.22)上pycharm官......
  • 解决 PbootCMS 后台 Ueditor 编辑器中单图片上传按钮无反应及多图片上传提示“后台配
    按照以下步骤进行修改:打开相关文件打开PbootCMS程序目录下的 core/extend/ueditor/php/controller.php 文件。修改时间区域配置将第四行的注释去掉,并将时间区域名称修改为首字母大写的形式。具体步骤打开相关文件使用文本编辑器(如Notepad++、VSCode等)打......
  • pbootcms模板后台编辑器无法上传图片提示:后端配置项没有正常加载,上传插件不能正常使用
    当你在使用PbootCMS后台时,遇到Ueditor编辑器中的单图片上传按钮无反应,多图片上传提示“后台配置项返回格式出错,上传功能将不能正常使用!”的问题时,可以通过以下步骤来解决。问题分析该问题通常是由于时间区域配置不正确导致的。具体来说,Linux系统对时间区域的大小写非常敏感......
  • Python 类型检查的利器
    Python类型检查的利器在Python编程中,类型注解(typehints)逐渐成为提高代码质量的重要工具。然而,Python的动态类型特性意味着类型错误可能在运行时才显现,这往往导致调试困难和运行时错误。为了解决这一问题,mypy提供了一种静态类型检查的解决方案,帮助开发者在编码阶段发现潜......
  • Python数据库操作:使用Python连接和操作数据库
    Python数据库操作:使用Python连接和操作数据库数据库入门小分队:Python带你探索数据海洋搭建桥梁:使用Python连接数据库的几种常见方式示例代码:使用`sqlite3`创建并连接一个SQLite数据库游刃有余:掌握基本SQL语句与Python的完美结合示例代码:执行复杂的SQL查询实战演练:通过......
  • Python与自然语言处理库BERT
    Python与自然语言处理库BERT揭开BERT的神秘面纱:从零开始理解这个改变游戏规则的语言模型实战演练:用Python和BERT搭建你的第一个情感分析小助手不只是翻译:探索BERT在跨语言任务中的神奇表现文本生成新高度:利用BERT创造流畅连贯的文章段落优化与调优:让BERT更好地适应特定......