在Python中常用的两个图像处理库,一个opencv,一个是PIL。其中,opencv是不支持中文显示的,所以只能显示英文。详细实现如下代码:
# -*- coding: utf-8 -*-#
# Author: weiz
# Date: 2020/1/13 下午6:26
# Name: testFont.py
# Description: 让文字信息以表格的形式在图片中显示
import numpy as np
from PIL import Image, ImageDraw, ImageFont
import cv2
def is_chinese(uchar):
"""
判断一个unicode是否是汉字
:param uchar:
:return:
"""
if uchar >= u'\u4e00' and uchar<=u'\u9fa5':
return True
else:
return False
def fitImageSize_pil(img, fontsize, font_w, font_h, row, longestChn, gap):
"""
适配图片大小
:param img:
:param fontsize:
:param font_w:
:param font_h:
:param row:
:param longestChn:
:param gap:
:return:
"""
img_h, img_w = img.shape[:2]
h_rate = (font_h * row) / img_h
w_rate = font_w / img_w
while (max(h_rate, w_rate) <= 0.7) or (max(h_rate, w_rate) >= 0.9):
if max(h_rate, w_rate) <= 0.7:
fontsize = fontsize + 1
font = ImageFont.truetype("simhei.ttf", fontsize, encoding="utf-8")
font_w, font_h = font.getsize(longestChn)
font_w = font_w + 2 * gap
font_h = font_h + 2 * gap
h_rate = (font_h * row) / img_h
w_rate = font_w / img_w
if max(h_rate, w_rate) >= 0.9:
fontsize = fontsize - 1
font = ImageFont.truetype("simhei.ttf", fontsize, encoding="utf-8")
font_w, font_h = font.getsize(longestChn)
font_w = font_w + 2 * gap
font_h = font_h + 2 * gap
h_rate = (font_h * row) / img_h
w_rate = font_w / img_w
font = ImageFont.truetype("simhei.ttf", fontsize, encoding="utf-8")
return font, font_w, font_h
def showChn4table_pil(img, chnList, fontsize=None, gap=None, start_x=None, start_y=None):
"""
以表格的形式在图片的居中(默认是居中)显示中文或者英文字符
:param img:
:param chnList:
:param fontsize:
:param gap:表格和字体之间的距离
:param start_x:
:param start_y:
:return:
"""
row = len(chnList)
if gap == None:
gap = 2
if fontsize == None:
fontsize = 20
longestChn = ""
longestChn_count = 0
# 涉及到中文汉字,一个汉字占两个字节。但是len()函数只计算字符串的个数,而显示涉及到像素
for chnStr in chnList:
count = 0
for chn in chnStr:
if is_chinese(chn):
count += 1
count = (len(chnStr) - count) + count * 2
if count > longestChn_count:
longestChn = chnStr
longestChn_count = count
img_h, img_w = img.shape[:2]
pil_img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
draw = ImageDraw.Draw(pil_img)
# 如果是在Linux系统下运行,可能需要把simhei.ttf字体放到当前运行脚本同路径下
font = ImageFont.truetype("simhei.ttf", fontsize, encoding="utf-8")
font_w, font_h = font.getsize(longestChn)
font_w = font_w + 2 * gap
font_h = font_h + 2 * gap
font, font_w, font_h = fitImageSize_pil(img, fontsize, font_w, font_h, row, longestChn, gap)
# 修改start_x和start_y就可以在图片的任意位置显示
if start_x == None:
start_x = (img_w - font_w) // 2
if start_y == None:
start_y = (img_h - font_h * row) // 2
end_x = start_x + font_w
end_y = start_y + font_h * row
for i, chnStr in enumerate(chnList):
line_spacing = i * font_h
draw.text((start_x+gap, start_y+line_spacing+gap), chnStr, (0, 0, 0), font)
draw.line((start_x, start_y+line_spacing, end_x, start_y+line_spacing), 'red')
draw.line((start_x, end_y, end_x, end_y), 'red')
draw.line((start_x, start_y, start_x, end_y), 'red')
draw.line((end_x, start_y, end_x, end_y), 'red')
img = cv2.cvtColor(np.asarray(pil_img), cv2.COLOR_RGB2BGR)
return img
def showEng4table_cv(img, engList, fontScale=None, gap=None, start_x=None, start_y=None):
"""
以表格的形式在图片的居中(默认是居中)显示英文字符(opencv不支持中文)
:param img:
:param engList:
:param fontScale:
:param gap:表格和字体之间的距离
:param start_x:
:param start_y:
:return:
"""
row = len(engList)
if gap == None:
gap = 2
if fontScale == None:
fontScale = 1
longestEng = ""
for engStr in engList:
if len(engStr) > len(longestEng):
longestEng = engStr
img_h, img_w = img.shape[:2]
(font_w, font_h), baseline = cv2.getTextSize(longestEng, cv2.FONT_HERSHEY_TRIPLEX, fontScale, 1)
font_h = font_h + baseline + 2 * gap
font_w = font_w + 2 * gap
if start_x == None:
start_x = (img_w - font_w) // 2
if start_y == None:
start_y = (img_h - (font_h * row)) // 2
end_x = start_x + font_w
end_y = start_y + font_h * row
for i, engStr in enumerate(engList):
line_spacing = i * font_h
cv2.rectangle(img, (start_x, start_y+line_spacing), (end_x, start_y+line_spacing+font_h), (0, 0, 0))
cv2.putText(img, engStr, (start_x+gap, start_y+line_spacing+font_h-baseline-gap), cv2.FONT_HERSHEY_TRIPLEX, fontScale, (0, 0, 0), 1)
return img
if __name__ == "__main__":
img = np.ones([600, 1000, 3], dtype=np.uint8) * 188
chnList = ['没有,不是,别乱说!', '产品型号|CCF| 符合标推| GB7251.3', '额定工作电压:220V/380V 额定工作电流', '额定绝缘电压:400V额定工作频率:50HZ', '出厂编号|| 出厂日期||年| |月', '河 南 西 西弗 电 气 有 限 公 司', 'abcdetfghidjkkdjddekdjieiij']
img_pil = showChn4table_pil(img, chnList, 20, 5)
cv2.imshow("img_pil", img_pil)
engList = ["How old are you?", "How are you!", "How are you!", "Of course the longest string is me!", "How are you!", "How are you!", "hello,world!", "No, no, don't talk nonsense!"]
img_cv = showEng4table_cv(img, engList, 0.8, 5)
cv2.imshow("img_cv", img_cv)
cv2.waitKey()
效果图片: