import time from io import BytesIO import cv2 import requests from PIL import Image, ImageDraw, ImageFont import numpy as np ''' 文字水印 ''' class TextWaterMark(): def __init__(self): self.color_dict = { # R G B # 网址查看:https://tool.oschina.net/commons?type=3 # 网址查看:http://tools.jb51.net/static/colorpicker/ 'white': (255, 255, 255, 255), 'black': (0, 0, 0, 255), 'gray': (205, 201, 201, 255), 'red': (255, 0, 0, 255), 'yellow': (255, 215, 0, 255), 'blue': (0, 0, 170, 255), 'purple': (205, 105, 201, 255), 'green': (0, 205, 0, 255) } self.position_list = [1, 2, 3, 4] """ 普通照片水印 params: image:图片 text:水印文字 position:水印位置 1:左上 2:右上 3:右下 4:左下 fontface: 字体 fontsize:字体大小 fontcolor:字体颜色 [white, black, gray, red, yellow, blue, purple, green] """ def common_water(self, image, text, position=1, fontface='../font/simsun.ttc', fontsize=20, fontcolor='black'): flag = False if isinstance(image, np.ndarray): # 判断是否OpenCV图片类型 flag = True image = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGRA2RGBA)) if position not in self.position_list: position = 1 w, h = image.size[:2] keys = self.color_dict.keys() if fontcolor not in keys: fontcolor = 'black' color = self.color_dict[fontcolor] fnt = ImageFont.truetype(fontface, fontsize) im = image.convert('RGBA') mask = Image.new('RGBA', im.size, (0, 0, 0, 0)) d = ImageDraw.Draw(mask) size_w, size_h = d.textsize(text, font=fnt) if position == 1: weizhi = (w * 0.1, h * 0.1) elif position == 2: weizhi = (w * 0.9 - size_w, h * 0.1) elif position == 3: weizhi = (w * 0.9 - size_w, h * 0.9 - size_h) else: weizhi = (w * 0.1, h * 0.9 - size_h) # position 为左上角位置 d.text(weizhi, text, font=fnt, fill=color) out = Image.alpha_composite(im, mask) if flag: out = cv2.cvtColor(np.asarray(out), cv2.COLOR_BGRA2RGBA) return out """ 半透明水印,布满整张图,并且自动旋转45° params: image:图片 text:文字 fontsize:文字大小 """ def fill_water(self, image, text, fontsize): flag = False if isinstance(image, np.ndarray): # 判断是否OpenCV图片类型 flag = True image = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGRA2RGBA)) font = ImageFont.truetype('../font/simsun.ttc', fontsize) # 添加背景 new_img = Image.new('RGBA', (image.size[0] * 3, image.size[1] * 3), (255, 255, 255, 255)) new_img.paste(image, image.size) # 添加水印 font_len = len(text) rgba_image = new_img.convert('RGBA') text_overlay = Image.new('RGBA', rgba_image.size, (0, 0, 0, 0)) image_draw = ImageDraw.Draw(text_overlay) for i in range(0, rgba_image.size[0], font_len * 40 + 100): for j in range(0, rgba_image.size[1], 200): # print(f'i:{i}, j:{j}, text:{text}, font:{font}') image_draw.text((i, j), text, font=font, fill=(0, 0, 0, 50)) text_overlay = text_overlay.rotate(-45) image_with_text = Image.alpha_composite(rgba_image, text_overlay) image_with_text = image_with_text.crop((image.size[0], image.size[1], image.size[0] * 2, image.size[1] * 2)) if flag: image_with_text = cv2.cvtColor(np.asarray(image_with_text), cv2.COLOR_BGRA2RGBA) return image_with_text class PictureWaterMark: def __init__(self): self.logo = cv2.imread("./image/logo.png", -1) def common_water(self, image, logo): width, height = image.shape[1], image.shape[0] mark_width, mark_height = logo.shape[1], logo.shape[0] rate = int(width * 0.2) / mark_width logo_new = cv2.resize(logo, None, fx=rate, fy=rate, interpolation=cv2.INTER_NEAREST) position = (int(width * 0.95 - logo_new.shape[1]), int(height * 0.95 - logo_new.shape[0])) b = Image.new('RGBA', (width, height), (0, 0, 0, 0)) # 创建新图像:透明' a = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) watermark = Image.fromarray(cv2.cvtColor(logo_new, cv2.COLOR_BGRA2RGBA)) # 图片旋转 # watermark = watermark.rotate(45) b.paste(a, (0, 0)) b.paste(watermark, position, mask=watermark) return cv2.cvtColor(np.asarray(b), cv2.COLOR_BGR2RGB) def common_water_1(self, image, logo, alpha=1): h, w = image.shape[0], image.shape[1] if w >= h: rate = int(w * 0.1) / logo.shape[1] else: rate = int(h * 0.1) / logo.shape[0] mask = cv2.resize(logo, None, fx=rate, fy=rate, interpolation=cv2.INTER_NEAREST) mask_h, mask_w = mask.shape[0], mask.shape[1] mask_channels = cv2.split(mask) dst_channels = cv2.split(image) # b, g, r, a = cv2.split(mask) # 计算mask在图片的坐标 ul_points = (int(h * 0.95) - mask_h, int(w - h * 0.05 - mask_w)) dr_points = (int(h * 0.95), int(w - h * 0.05)) for i in range(3): dst_channels[i][ul_points[0]: dr_points[0], ul_points[1]: dr_points[1]] = dst_channels[i][ ul_points[0]: dr_points[0], ul_points[1]: dr_points[1]] * ( 255.0 - mask_channels[3] * alpha) / 255 dst_channels[i][ul_points[0]: dr_points[0], ul_points[1]: dr_points[1]] += np.array( mask_channels[i] * (mask_channels[3] * alpha / 255), dtype=np.uint8) dst_img = cv2.merge(dst_channels) return dst_img #差值感知算法 def dHash(image): #缩放9*8 image=cv2.resize(image,(9,8),interpolation=cv2.INTER_CUBIC) #转换灰度图 image=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) # print(image.shape) hash=[] #每行前一个像素大于后一个像素为1,相反为0,生成哈希 for i in range(8): for j in range(8): if image[i,j]>image[i,j+1]: hash.append(1) else: hash.append(0) return hash #计算汉明距离 def Hamming_distance(hash1,hash2): num = 0 for index in range(len(hash1)): if hash1[index] != hash2[index]: num += 1 return num def url2Array(url): response = requests.get(url) image = Image.open(BytesIO(response.content)) image1= np.array(image) img_bgr = cv2.cvtColor(image1, cv2.COLOR_RGB2BGR) return img_bgr if __name__ == '__main__': # img = cv2.imread("../test/a.jpg", -1) # fontcolor = 'yellow' # # water = TextWaterMark() # text = "hello world" # # # fill_img = water.common_water(img, text, position=4, fontface='../font/庞门正道标题体2.0增强版.ttf', fontsize=20, fontcolor='black') # fill_img = water.fill_water(img, text, 20) # # 一定要保存为png格式 # cv2.imshow('result', fill_img) # cv2.waitKey(111111110) # print('finish') pic = PictureWaterMark() image = cv2.imread("a.jpg") logo = cv2.imread("../image/logo.png", -1) # print(image, logo) start = time.time() frame = pic.common_water(image, logo) print(time.time() - start) start1 = time.time() frame1 = pic.common_water_1(image, logo) # cv2.imwrite("watermarked.jpg", frame1) print(time.time() - start1) # cap = cv2.VideoCapture("../data/111111.mp4") # logo = cv2.imread("../image/logo.png", -1) # while True: # is_opened, frame = cap.read() # frame = pic.common_water(frame, logo) # cv2.imshow('frame', frame) # cv2.waitKey(1) # 等待输入任何按键 # # 关闭 # cap.release()