运行结果:
同样调用imwrite()
方法也是无法生成带有中文路径的图片的,可以自行编写两个函数来解决:
def cv_imread(file_path): cv_img = cv2.imdecode(np.fromfile(file_path, dtype=np.uint8), -1) return cv_img def cv_imwrite(img, file_path): cv2.imencode('.jpg', img)[1].tofile(file_path)
行吧,能获取到宽高了,接着调用opencv提供的resize()
方法调整图片的尺寸,参数依次为:图片,宽高元组,还有一个可选参数:interpolation插值方法,默认使用INTER_LINEAR双线性插值,其他的还有:INTER_NEAREST,INTER_AREA,INTER_CUBIC,INTER_LANCZOS4。
import cv2 import numpy as np def cv_imread(file_path): cv_img = cv2.imdecode(np.fromfile(file_path, dtype=np.uint8), -1) return cv_img def cv_imwrite(img, file_path): cv2.imencode('.jpg', img)[1].tofile(file_path) img = cv_imread('测试.jpg') (h, w) = img.shape[:2] print("缩放前的尺寸:", img.shape[:2]) res = cv2.resize(img, (900, round(h * (900 / w)))) print("裁剪后的尺寸:", res.shape[:2])
运行结果:
缩放前的尺寸: (956, 1080) 缩放后的尺寸: (797, 900)
5.图片裁剪
缩放完,接着就到裁剪了,先是计算图片能裁剪成几张:
crop_pic_count = int(ch / 383) print("图片可以裁剪为:%d张" % crop_pic_count) # 输出结果:图片可以裁剪为:2张
接着是裁剪图片,可以通过:图片对象[y轴起始坐标:y轴终点坐标, x轴起始坐标:x轴终点坐标],来裁剪。 所以,我们要计算每个裁剪区域的对应的坐标方位。另外,这里还要考虑一个偏移,以中间位置为基准进行 裁剪,这样感觉会好一点。给个加偏移和不加偏移裁剪后的对比图吧:
so,我还是倾向于加偏移,计算偏移也很简单,直接拿高对383进行求余,然后除以2。
start_y = int(ch % 383 / 2)
接着根据能切成的图片张数,计算怎么裁剪
for i in range(0, crop_pic_count): crop_img = res[383 * i + start_y: 383 * (i + 1) + start_y, 0:900] cv_imwrite(crop_img, '剪切图%d.jpg' % (i+1))
裁剪后的图片:
6.图片加字
行吧,图片也裁剪好了,接着就是图片加字了,可以通过opencv提供的putText()
添加文字, 参数依次为: 图像,文字内容, 坐标 ,字体,大小,颜色,字体厚度。
img = cv_imread('剪切图0.jpg') cv2.putText(img, 'Test', (50, 300), cv2.FONT_HERSHEY_SIMPLEX, 1.2, (255, 255, 255), 2) cv2.imshow('image', img) cv2.waitKey()
运行结果如下:
加字成功,挺简单的,是吧?但是,如果你添加的文字不是字母或数字,而是中文的话,那么恭喜,黑人问号~
原因是:opencv自带的putText函数无法输出utf8类型的字符,因此无法将中文打印到图片上。 两个解决方法:
- 方法一:利用另一个freetype库,将字符解码转码,不过有点繁琐。
- 方法二:利用pillow库里ImageDraw类的text函数绘制中文,先从成cv2转PIL格式,加完中文再转回cv2格式输出。
这里采用的是方法二,text函数的参数:起始坐标元组,文字内容,字体,颜色。问题来了,怎么确定绘制文字的起始坐标?
答:如果你要程序算,挺麻烦的,文字宽度怎么获取,既然图片尺寸固定,文字长度不变,为何不取巧一下呢?
直接在Pixelmator Pro上把文字拖好,然后复制下坐标,不就好了~
另外,这里笔者用的字体是 苹果-简,常规体
,可以自行下载,记得把字体文件名改成英文文件名, 不然,会读取不到字体。好的,撸代码试试:
img = cv_imread('剪切图0.jpg') # 将图片从OpenCv格式转为PIL格式 img_pil = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) # 加载字体(字体文件名,字体大小) title_font = ImageFont.truetype('apple-simple.ttf', 52) date_font = ImageFont.truetype('apple-simple.ttf', 44) # 绘制文字的位置 title_pos = (236, 110) date_pos = (338, 192) # 绘制内容 title_content = u"『抠腚早报速读』" date_content = u"第190111期" # 绘制 draw = ImageDraw.Draw(img_pil) draw.text(title_pos, title_content, font=title_font, fill=(255, 255, 255)) draw.text(date_pos, date_content, font=date_font, fill=(255, 255, 255)) img_open_cv = cv2.cvtColor(np.asarray(img_pil), cv2.COLOR_RGB2BGR) cv_imwrite(img_open_cv, "加字后.jpg")
接着看下输出的图片:
啧啧啧,完美,到此自动裁剪生成一个早报封面的脚本就完成啦,接下来我们来补全和完善下我们的程序。