11import os
22import tkinter as tk
33from tkinter import filedialog , messagebox
4+ from pydub import AudioSegment
45
5- def embed_image_in_audio ( audio_file , image_file ):
6+ def generate_empty_audio ( output_file , file_name ):
67 """
7- 将图片嵌入到音频文件中,并生成嵌入后的文件
8+ 生成一个无声的短音频文件,包含标准 MP3 元数据
89 """
9- output_file = os .path .join (os .path .dirname (audio_file ), "embedded.mp3" )
1010 try :
11- with open (audio_file , "rb" ) as audio , open (image_file , "rb" ) as image :
11+ # 创建 1 秒无声音频
12+ silent_audio = AudioSegment .silent (duration = 1000 ) # 1000 毫秒 = 1 秒
13+ # 设置必要的 MP3 元数据
14+ silent_audio .export (output_file , format = "mp3" , tags = {
15+ "title" : file_name ,
16+ "artist" : "Apermesa" ,
17+ "album" : "Half Life 3" ,
18+ "year" : "2024"
19+ })
20+ return True
21+ except Exception as e :
22+ messagebox .showerror ("错误" , f"生成空音频失败:{ str (e )} " )
23+ return False
24+
25+ def embed_image_in_audio (image_file ):
26+ """
27+ 将图片嵌入到生成的无声音频文件中
28+ """
29+ file_name = os .path .splitext (os .path .basename (image_file ))[0 ]
30+ output_audio_file = os .path .join (os .path .dirname (image_file ), "temp_silent.mp3" )
31+ if not generate_empty_audio (output_audio_file , file_name ):
32+ return
33+
34+ output_file = os .path .join (os .path .dirname (image_file ), file_name + "(embedded).mp3" )
35+ try :
36+ with open (output_audio_file , "rb" ) as audio , open (image_file , "rb" ) as image :
1237 with open (output_file , "wb" ) as output :
1338 output .write (audio .read ()) # 写入音频数据
1439 output .write (image .read ()) # 写入图片数据
40+ os .remove (output_audio_file ) # 删除临时音频文件
1541 messagebox .showinfo ("完成" , f"图片已嵌入!文件保存为:{ output_file } " )
1642 except Exception as e :
1743 messagebox .showerror ("错误" , f"嵌入失败:{ str (e )} " )
@@ -20,36 +46,46 @@ def extract_image_from_file(input_file):
2046 """
2147 从伪装文件中提取图片,并生成图片文件
2248 """
23- output_image_file = os .path .join (os .path .dirname (input_file ), "extracted_image.jpg" )
2449 try :
2550 with open (input_file , "rb" ) as file :
2651 data = file .read ()
2752
28- # 搜索 JPG 文件头
29- jpg_start = data .find (b'\xFF \xD8 \xFF ' ) # JPG 的文件头
30- if jpg_start == - 1 :
31- messagebox .showerror ("错误" , "未找到 JPG 文件头,文件可能不包含图片。" )
53+ # 检测图片格式
54+ formats = {
55+ b'\xFF \xD8 \xFF ' : ".jpg" , # JPG 文件头
56+ b'\x89 PNG' : ".png" # PNG 文件头
57+ }
58+
59+ start_index = - 1
60+ file_extension = None
61+ for header , ext in formats .items ():
62+ index = data .find (header )
63+ if index != - 1 :
64+ start_index = index
65+ file_extension = ext
66+ break
67+
68+ if start_index == - 1 :
69+ messagebox .showerror ("错误" , "未找到支持的图片文件头,文件可能不包含图片。" )
3270 return
3371
3472 # 提取图片数据
73+ embedded_file_name = os .path .splitext (os .path .basename (input_file ))[0 ].replace ("(embedded)" , "" )
74+ output_image_file = os .path .join (os .path .dirname (input_file ), f"{ embedded_file_name } { file_extension } " )
3575 with open (output_image_file , "wb" ) as image_file :
36- image_file .write (data [jpg_start :]) # 保存从图片头开始的所有数据
76+ image_file .write (data [start_index :]) # 保存从图片头开始的所有数据
3777
3878 messagebox .showinfo ("完成" , f"图片已提取!文件保存为:{ output_image_file } " )
3979 except Exception as e :
4080 messagebox .showerror ("错误" , f"提取失败:{ str (e )} " )
4181
4282def embed_action ():
43- """选择音频和图片文件并嵌入图片"""
44- audio_file = filedialog .askopenfilename (title = "选择音频文件" , filetypes = [("音频文件" , "*.mp3" )])
45- if not audio_file :
46- return
47-
83+ """选择图片文件并嵌入到生成的无声音频中"""
4884 image_file = filedialog .askopenfilename (title = "选择图片文件" , filetypes = [("图片文件" , "*.jpg;*.jpeg;*.png" )])
4985 if not image_file :
5086 return
5187
52- embed_image_in_audio (audio_file , image_file )
88+ embed_image_in_audio (image_file )
5389
5490def extract_action ():
5591 """选择伪装文件并提取图片"""
0 commit comments