import base64,hashlib,os,shutil import math,time,json from PIL import Image from tinydb import TinyDB, Query from common.Constant import pathStr class imageUtils: @classmethod def encodeImage(cls,str_en): #print("en",str_en) enc = base64.b64decode(str_en) #print("解密:",enc) m = hashlib.md5() m.update(enc) md5 = m.digest() d = md5[-1] #print(md5) try: blocks = d % 10 + 5 except: blocks = 0 %10 + 5 #print("blocks=",blocks) return blocks @classmethod def scrambleImage(cls,file_path): #检测到未下载完的图像 直接返回None if str(file_path).endswith(".downloads"): os.remove(file_path) return None file_str = str(file_path).split("=") #10_29.jpg base_dir = file_str[0].replace("scramble","") base_name = file_str[-1] base_fn = base_name.split("_") save_name = base_fn[1] save_name_delesu = save_name.split(".")[0] blocks = int(base_fn[0]) save_file_path = os.path.join(base_dir,save_name) print("sva",save_file_path) if os.path.exists(save_file_path): print("图片已解密,已跳过:", save_file_path) return None image_su = str(file_path).split(".")[-1] try: img = Image.open(file_path) except: print(f"error Image: {file_path}") width = img.width height = img.height #blocks = cls.encodeImage(enStr) print("blocks=",blocks) block_height = int(height / blocks) block_width = int(width / blocks) print("blockHeight=",block_height) prefix = str(file_path).split(".")[-1] split_path = os.path.join(base_dir,save_name_delesu+"split") if image_su == "downloads": return None is_split = cls.splitimage(file_path,blocks,1,split_path) if is_split != None: cls.image_compose(split_path,blocks,1,save_file_path,block_height,width) else: if os.path.exists(split_path): shutil.rmtree(split_path) if os.path.exists(file_path): shutil.move(file_path, save_file_path) #完成后清空 return file_path @classmethod def splitimage(cls,src,rownum,colnum,dstpath): img=Image.open(src) w,h=img.size if rownum<= h and colnum<=w: s=os.path.split(src) if dstpath=='': dstpath = s[0] if not os.path.exists(dstpath): os.makedirs(dstpath) fn=s[1].split('.') basename=fn[0] ext=fn[-1] num=0 rowheight=h//rownum colwidth=w//colnum for r in range(rownum): for c in range(colnum): box=(c*colwidth,r*rowheight,(c+1)*colwidth,(r+1)*rowheight) count_image = "{:0>3d}".format(num) file_path = os.path.join(dstpath,str(count_image)+'.'+ext) print("file_path=",file_path) img.crop(box).save(file_path) num=num+1 return "成功" else: print('不数!') return None @classmethod def image_compose(cls,src,row,column,save_path,image_height,image_width): image_size = image_height #image_height = 376 #image_width = 720 images_format = ['.png','.jpg'] #image_names = [name for name in os.listdir(src) for item in images_format if # os.path.splitext(name)[1] == item][::-1] img_list=os.listdir(src) img_list.sort() img_list.sort(key=lambda x: int(x[:-4])) ##文件名按数字排序 img_nums=len(img_list) image_names = [] for i in range(img_nums): img_name=os.path.join(src,img_list[i]) image_names.append(img_name) #使用倒序 image_names = image_names[::-1] # 简单的对于参数的设定和实际图片集的大小进行数量判断 if len(image_names) < row * column: raise ValueError("合成图片的参数和要求的数量不能匹配!") to_image = Image.new('RGB', (column * image_width, row * image_height)) #创建一个新图 # 循环遍历,把每张图片按顺序粘贴到对应位置上 for y in range(1, row + 1): for x in range(1, column + 1): #1 * (row=1 -1) col=1 -1 image_path = image_names[column * (y - 1) + x - 1] print("split_image=",image_path) from_image = Image.open(image_path) #保持原图片大小 #.resize( # (image_size, image_size),Image.ANTIALIAS) to_image.paste(from_image, ((x - 1) * image_size, (y - 1) * image_size)) from_image.close() to_image.save(save_path) print("图片合并完成:", save_path) shutil.rmtree(src) # 保存新图 @classmethod def getScrambleImage(cls,path): scramble_file_cache = cls.scrambleImage(path) if scramble_file_cache != None and os.path.exists(scramble_file_cache): os.remove(scramble_file_cache) @classmethod def encode_scramble_image(cls,imgpath): image = Image.open(imgpath) w, h = image.size #image.show() file_str = str(imgpath).split("=") #10_29.jpg base_dir = file_str[0].replace("scramble","") base_name = file_str[-1] base_fn = base_name.split("_") save_name = base_fn[1] save_name_delesu = save_name.split(".")[0] blocks = int(base_fn[0]) img_type = os.path.basename(imgpath).split('.')[-1] save_path = os.path.join(os.path.dirname(imgpath),save_name_delesu+"."+img_type) # print(type(aid),type(img_name)) if blocks: s = blocks # 随机值 # print(s) l = h % s # 切割最后多余的值 box_list = [] hz = 0 for i in range(s): c = math.floor(h / s) g = i * c hz += c h2 = h - c * (i + 1) - l if i == 0: c += l;hz += l else: g += l box_list.append((0, h2, w, h - g)) # print(box_list,len(box_list)) item_width = w # box_list.reverse() #还原切图可以倒序列表 # print(box_list, len(box_list)) newh = 0 image_list = [image.crop(box) for box in box_list] # print(box_list) newimage = Image.new("RGB", (w, h)) for image in image_list: # image.show() b_w, b_h = image.size newimage.paste(image, (0, newh)) newh += b_h newimage.save(save_path) print("解密成功=",save_path) if os.path.exists(imgpath): os.remove(imgpath) print("remove=",imgpath) class fileUtils: @classmethod def exists(cls,path): return os.path.exists(path) @classmethod def notExists(cls,path): return not cls.exists(path) @classmethod def size(cls,file_path,unit=None): size = 0 if cls.exists(file_path): size = os.path.getsize(file_path) if unit == "kb" or unit == "KB": return str(size/1000)+"KB" if unit == None: return size @classmethod def ver_file(cls,file_path,type,min_size=10): time.sleep(0.1) file_size_unit = cls.size(file_path,unit="kb") if type == "image" and int(cls.size(file_path)) > min_size: #验证是否是图像 try: img = Image.open(file_path) img.verify() img.close() print(f"{file_path} 类型为type:{type} size: {file_size_unit}") return True except: if os.path.exists(file_path): os.remove(file_path) print(f"{file_path}已损坏 type:{type} size: {file_size_unit},删除重试中") return False else: print(f"文件小于100b删除中,{file_path} size: {file_size_unit}") try: os.remove(file_path) except Exception as e: print(e) return False @classmethod def dirFilesName(cls,path,type="file",prefix=None): result = [] if cls.exists(path): for file_or_dir in os.listdir(path): if type == "file" and os.path.isfile(os.path.join(path,file_or_dir)): result.append(file_or_dir) if type == "dir" and os.path.isdir(os.path.join(path,file_or_dir)): result.append(file_or_dir) return result @classmethod def equImages(cls,dir,files,prefix=".jpg"): len_count = 0 file_names = cls.dirFilesName(dir,"file") for file in file_names: if str(file).endswith(prefix): len_count += 1 return len_count == len(files) @classmethod def remove(cls,path): if not os.path.exists(path): return None try: print(f"{path} 删除中...") if os.path.isfile(path): os.remove(path) if os.path.isdir(path): shutil.rmtree(path) print(f"已删除:{path}") return True except: print(f"删除错误:{path}") return False #文件保存 @classmethod def file_save(cls,path,data,mode=None,print_msg=False): result = {} f = {} dir_name = os.path.dirname(path) if not os.path.exists(dir_name): os.makedirs(dir_name) save_path = os.path.join(path) if os.path.exists(save_path): os.remove(save_path) data = json.dumps(data) if mode == None: mode = "w+" try: f = open(save_path, mode, encoding="utf-8") f.write(data) f.close() if print_msg: print("data=",data) result = path + "文件写入成功" except: result = path + "文件写入失败" print(result) return result class dbUtils: @classmethod def base_path(cls,path): base_dir = pathStr.base_db() if not os.path.exists(base_dir): os.makedirs(base_dir) return os.path.join(base_dir,path) @classmethod def init_db(cls,db_name=None): if db_name != None: db_name = cls.base_path(db_name)+".json" else: db_name = "Comics.json" return TinyDB(cls.base_path(db_name)) @classmethod def setComic(cls,name,progress,db_name=None): db = cls.init_db(db_name) comic = Query() if len(db.search(comic.name == name)) == 0: db.insert({"name":name,"progress":progress}) else: db.update({"progress":progress},comic.name== name) @classmethod def query(cls,name,progress=None,db_name=None): db = cls.init_db(db_name) result = db.search(Query().name == name) if progress != None: try: if len(db.search((Query().name == name) & (Query().progress == progress))) != 0: result = True else: result = False except Exception as e: print(e) return result @classmethod def remove(cls,name,db_name=None): db = cls.init_db(db_name) db.remove(Query().name == name)