You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

265 lines
9.7KB

  1. import time
  2. from io import BytesIO
  3. import cv2
  4. import requests
  5. from PIL import Image, ImageDraw, ImageFont
  6. import numpy as np
  7. '''
  8. 文字水印
  9. '''
  10. class TextWaterMark():
  11. def __init__(self):
  12. self.color_dict = {
  13. # R G B
  14. # 网址查看:https://tool.oschina.net/commons?type=3
  15. # 网址查看:http://tools.jb51.net/static/colorpicker/
  16. 'white': (255, 255, 255, 255),
  17. 'black': (0, 0, 0, 255),
  18. 'gray': (205, 201, 201, 255),
  19. 'red': (255, 0, 0, 255),
  20. 'yellow': (255, 215, 0, 255),
  21. 'blue': (0, 0, 170, 255),
  22. 'purple': (205, 105, 201, 255),
  23. 'green': (0, 205, 0, 255)
  24. }
  25. self.position_list = [1, 2, 3, 4]
  26. """
  27. 普通照片水印
  28. params:
  29. image:图片
  30. text:水印文字
  31. position:水印位置
  32. 1:左上
  33. 2:右上
  34. 3:右下
  35. 4:左下
  36. fontface: 字体
  37. fontsize:字体大小
  38. fontcolor:字体颜色
  39. [white, black, gray, red, yellow, blue, purple, green]
  40. """
  41. def common_water(self, image, text, position=1, fontface='../font/simsun.ttc', fontsize=20, fontcolor='black'):
  42. flag = False
  43. if isinstance(image, np.ndarray): # 判断是否OpenCV图片类型
  44. flag = True
  45. image = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGRA2RGBA))
  46. if position not in self.position_list:
  47. position = 1
  48. w, h = image.size[:2]
  49. keys = self.color_dict.keys()
  50. if fontcolor not in keys:
  51. fontcolor = 'black'
  52. color = self.color_dict[fontcolor]
  53. fnt = ImageFont.truetype(fontface, fontsize)
  54. im = image.convert('RGBA')
  55. mask = Image.new('RGBA', im.size, (0, 0, 0, 0))
  56. d = ImageDraw.Draw(mask)
  57. size_w, size_h = d.textsize(text, font=fnt)
  58. if position == 1:
  59. weizhi = (w * 0.1, h * 0.1)
  60. elif position == 2:
  61. weizhi = (w * 0.9 - size_w, h * 0.1)
  62. elif position == 3:
  63. weizhi = (w * 0.9 - size_w, h * 0.9 - size_h)
  64. else:
  65. weizhi = (w * 0.1, h * 0.9 - size_h)
  66. # position 为左上角位置
  67. d.text(weizhi, text, font=fnt, fill=color)
  68. out = Image.alpha_composite(im, mask)
  69. if flag:
  70. out = cv2.cvtColor(np.asarray(out), cv2.COLOR_BGRA2RGBA)
  71. return out
  72. """
  73. 半透明水印,布满整张图,并且自动旋转45°
  74. params:
  75. image:图片
  76. text:文字
  77. fontsize:文字大小
  78. """
  79. def fill_water(self, image, text, fontsize):
  80. flag = False
  81. if isinstance(image, np.ndarray): # 判断是否OpenCV图片类型
  82. flag = True
  83. image = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGRA2RGBA))
  84. font = ImageFont.truetype('../font/simsun.ttc', fontsize)
  85. # 添加背景
  86. new_img = Image.new('RGBA', (image.size[0] * 3, image.size[1] * 3), (255, 255, 255, 255))
  87. new_img.paste(image, image.size)
  88. # 添加水印
  89. font_len = len(text)
  90. rgba_image = new_img.convert('RGBA')
  91. text_overlay = Image.new('RGBA', rgba_image.size, (0, 0, 0, 0))
  92. image_draw = ImageDraw.Draw(text_overlay)
  93. for i in range(0, rgba_image.size[0], font_len * 40 + 100):
  94. for j in range(0, rgba_image.size[1], 200):
  95. # print(f'i:{i}, j:{j}, text:{text}, font:{font}')
  96. image_draw.text((i, j), text, font=font, fill=(0, 0, 0, 50))
  97. text_overlay = text_overlay.rotate(-45)
  98. image_with_text = Image.alpha_composite(rgba_image, text_overlay)
  99. image_with_text = image_with_text.crop((image.size[0], image.size[1], image.size[0] * 2, image.size[1] * 2))
  100. if flag:
  101. image_with_text = cv2.cvtColor(np.asarray(image_with_text), cv2.COLOR_BGRA2RGBA)
  102. return image_with_text
  103. class PictureWaterMark:
  104. def __init__(self):
  105. self.logo = cv2.imread("./image/logo.png", -1)
  106. def common_water(self, image, logo):
  107. width, height = image.shape[1], image.shape[0]
  108. mark_width, mark_height = logo.shape[1], logo.shape[0]
  109. rate = int(width * 0.2) / mark_width
  110. logo_new = cv2.resize(logo, None, fx=rate, fy=rate, interpolation=cv2.INTER_NEAREST)
  111. position = (int(width * 0.95 - logo_new.shape[1]), int(height * 0.95 - logo_new.shape[0]))
  112. b = Image.new('RGBA', (width, height), (0, 0, 0, 0)) # 创建新图像:透明'
  113. a = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
  114. watermark = Image.fromarray(cv2.cvtColor(logo_new, cv2.COLOR_BGRA2RGBA))
  115. # 图片旋转
  116. # watermark = watermark.rotate(45)
  117. b.paste(a, (0, 0))
  118. b.paste(watermark, position, mask=watermark)
  119. return cv2.cvtColor(np.asarray(b), cv2.COLOR_BGR2RGB)
  120. def common_water_1(self, image, logo, alpha=1):
  121. h, w = image.shape[0], image.shape[1]
  122. # if w >= h:
  123. rate = int(w * 0.1) / logo.shape[1]
  124. # else:
  125. # rate = int(h * 0.1) / logo.shape[0]
  126. mask = cv2.resize(logo, None, fx=rate, fy=rate, interpolation=cv2.INTER_NEAREST)
  127. mask_h, mask_w = mask.shape[0], mask.shape[1]
  128. mask_channels = cv2.split(mask)
  129. dst_channels = cv2.split(image)
  130. # b, g, r, a = cv2.split(mask)
  131. # 计算mask在图片的坐标
  132. # if w >= h:
  133. ul_points = (int(h * 0.95) - mask_h, int(w - h * 0.05 - mask_w))
  134. dr_points = (int(h * 0.95), int(w - h * 0.05))
  135. # else:
  136. # ul_points = (int(h * 0.95) - mask_h, int(w - h * 0.05 - mask_w))
  137. # dr_points = (int(h * 0.95), int(w - h * 0.05))
  138. for i in range(3):
  139. dst_channels[i][ul_points[0]: dr_points[0], ul_points[1]: dr_points[1]] = dst_channels[i][
  140. ul_points[0]: dr_points[0],
  141. ul_points[1]: dr_points[1]] * (
  142. 255.0 - mask_channels[
  143. 3] * alpha) / 255
  144. dst_channels[i][ul_points[0]: dr_points[0], ul_points[1]: dr_points[1]] += np.array(
  145. mask_channels[i] * (mask_channels[3] * alpha / 255), dtype=np.uint8)
  146. dst_img = cv2.merge(dst_channels)
  147. return dst_img
  148. # 差值感知算法
  149. def dHash(image):
  150. # 缩放9*8
  151. image = cv2.resize(image, (9, 8), interpolation=cv2.INTER_CUBIC)
  152. # 转换灰度图
  153. image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
  154. # print(image.shape)
  155. hash = []
  156. # 每行前一个像素大于后一个像素为1,相反为0,生成哈希
  157. for i in range(8):
  158. for j in range(8):
  159. if image[i, j] > image[i, j + 1]:
  160. hash.append(1)
  161. else:
  162. hash.append(0)
  163. return hash
  164. # 计算汉明距离
  165. def Hamming_distance(hash1, hash2):
  166. num = 0
  167. for index in range(len(hash1)):
  168. if hash1[index] != hash2[index]:
  169. num += 1
  170. return num
  171. def url2Array(url):
  172. response = requests.get(url)
  173. image = Image.open(BytesIO(response.content))
  174. image1 = np.array(image)
  175. img_bgr = cv2.cvtColor(image1, cv2.COLOR_RGB2BGR)
  176. return img_bgr
  177. def url2Content(url):
  178. response = requests.get(url)
  179. return response.content
  180. def url2Image(url):
  181. response = requests.get(url)
  182. image = Image.open(BytesIO(response.content))
  183. image1 = np.array(image)
  184. img_bgr = cv2.cvtColor(image1, cv2.COLOR_RGB2BGR)
  185. img = Image.fromarray(img_bgr)
  186. return img
  187. def url2Byte(url):
  188. response = requests.get(url)
  189. return BytesIO(response.content)
  190. def markRectangle(url, text, textCoordinate, imageLeftUpCoordinate, imageRightDownCoordinate, color):
  191. img = url2Array(url)
  192. #( 蓝, 绿, 红)
  193. # 红色 (0, 0, 255)
  194. # 洋红色 (255, 0, 255)
  195. # 青色 (255, 255, 0)
  196. # 黑色 (0, 0, 0)
  197. # 蓝色 (255, 0, 0)
  198. # 绿色 (0, 255, 0)
  199. # 黄色 (0, 255, 255) # 不考虑
  200. cv2.putText(img, text, textCoordinate, cv2.FONT_HERSHEY_SIMPLEX, 1.0, color, 1, cv2.LINE_AA)
  201. # rectangle 坐标的参数格式为左上角(x1, y1),右下角(x2, y2), 颜色 , 粗细
  202. cv2.rectangle(img, imageLeftUpCoordinate, imageRightDownCoordinate, color, 2)
  203. return img
  204. # if __name__ == '__main__':
  205. # # img = cv2.imread("../test/a.jpg", -1)
  206. # # fontcolor = 'yellow'
  207. # #
  208. # # water = TextWaterMark()
  209. # # text = "hello world"
  210. # #
  211. # # # fill_img = water.common_water(img, text, position=4, fontface='../font/庞门正道标题体2.0增强版.ttf', fontsize=20, fontcolor='black')
  212. # # fill_img = water.fill_water(img, text, 20)
  213. # # # 一定要保存为png格式
  214. # # cv2.imshow('result', fill_img)
  215. # # cv2.waitKey(111111110)
  216. # # print('finish')
  217. # pic = PictureWaterMark()
  218. # image = cv2.imread("a.jpg")
  219. # logo = cv2.imread("../image/logo.png", -1)
  220. # # print(image, logo)
  221. # start = time.time()
  222. # frame = pic.common_water(image, logo)
  223. # print(time.time() - start)
  224. # start1 = time.time()
  225. # frame1 = pic.common_water_1(image, logo)
  226. # # cv2.imwrite("watermarked.jpg", frame1)
  227. # print(time.time() - start1)
  228. # # cap = cv2.VideoCapture("../data/111111.mp4")
  229. # # logo = cv2.imread("../image/logo.png", -1)
  230. # # while True:
  231. # # is_opened, frame = cap.read()
  232. # # frame = pic.common_water(frame, logo)
  233. # # cv2.imshow('frame', frame)
  234. # # cv2.waitKey(1) # 等待输入任何按键
  235. # # # 关闭
  236. # # cap.release()