python为图片增加文字水印

场景

是这样的一个需求,为所有的图片增加一个水印,在图片底部增加联系电话。

思路

  1. 从图片服务器下载图片到本地
  2. open本地图片
  3. 根据手机号生成文本,返回文本的宽高
  4. 根据文本宽高和图片宽高,确定手机号背景色的起始位置
  5. 描绘文字和背景
  6. 保存到本地
  7. 将新保存图片上传图片服务器

代码

# -*- coding=utf-8 -*-

from PIL import Image, ImageDraw, ImageFont
import requests

def add_text_to_image(image, text):
    rgba_image = image.convert('RGBA')
    img_width, img_height = rgba_image.size
    text_overlay = Image.new('RGBA', rgba_image.size, (255, 255, 255, 0))
    image_draw = ImageDraw.Draw(text_overlay)
    font = ImageFont.truetype(font_path, int(img_width / 11 * 1.5),
                              index=0)

    text_size_x, text_size_y = image_draw.textsize(text, font=font)
    text_x = (img_width - text_size_x) / 2
    text_y = img_height - text_size_y - 20

    # min_x, min_y, max_x, max_y
    image_draw.rectangle(xy=(0, img_height, img_width, text_y), fill="red", outline="#ccc", width=0)

    text_xy = (text_x, text_y)
    image_draw.text(text_xy, text, font=font, fill=(255, 255, 255, 225))

    image_with_text = Image.alpha_composite(rgba_image, text_overlay)
    return image_with_text


def download_img(url):
    r = requests.request("GET", url)
    local_path = "tmp.jpg"
    with open(local_path, "wb") as code:
        code.write(r.content)
    return local_path

def start():
    i = 1
    max_num = 1000
    while i < max_num:
        img_url = 'http://test-oss.beijing.aliyun.com/abc.jpg'
        loca_url = download_img(img_url)

        im_before = Image.open(loca_url)
        im_after = add_text_to_image(im_before, phone_num)
        im_after.show()
        tmp_img_path = 'tmp.png'
        im_after.save(tmp_img_path)
        # upload_img(tmp_img_path, i)
        # i += 1
        break

font_path = 'wqyzht.ttf'
phone_num = "15771264412"
if __name__ == '__main__':
    start()

总结

遇到了这样的几个问题

1.OSError: cannot write mode RGBA as JPEG

这个问题就是打开图片和保存图片的方式不同,打开的时候是使用的RGBA,保存成jpg就会报错,以为rgba多了一个透明度,所以保存jpg会报错。

两种解决方案

a.打开方式改变rgb

b.保存成png即可

2.如何实现纯颜色背景块

在很多加水印的时候都要加个底色,可以使用  image_draw.rectangle 来解决这个问题,并且还支持边框

 # min_x, min_y, max_x, max_y
    image_draw.rectangle(xy=(0, img_height, img_width, text_y), fill="red", outline="#ccc", width=0)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值