主页 > 编程 > python >

python 图片处理 添加水印 水平翻转 裁剪类

2019-03-13 17:03 阅读:79 来源:智宇SEO自媒体
用python封装了一个图片处理类 python 图片处理 添加水印 水平翻转 裁剪类
# -*- coding: utf-8 -*-
# @Time         : 2019/3/13 15:12
# @Author       : Zhiyu
# @File         : imask.py
# @Software     : PyCharm
# @Description  :

import os
import sys
import math

from PIL import Image, ImageFont, ImageDraw, ImageEnhance, ImageChops

class IMask:
    TTF_FONT = u'./Raleway-Bold.ttf'
    args = None
    im = None
    def __init__(self , args):
        self.args = args
        self.im = Image.open(self.args['file'])

    def add_mark(self):
        '''
        添加水印,然后保存图片
        '''
        mark = self.gen_mark()
        self.im = self.mark_im(mark)


    def save(self):
        imagePath = self.args['file']
        name = os.path.basename(imagePath)
        if not os.path.exists(self.args['out']):
            os.mkdir(self.args['out'])

        new_name = os.path.join(self.args['out'], name)
        if os.path.splitext(new_name)[1] != '.png':
            self.im = self.im.convert('RGB')
        return self.im.save(new_name)

    def set_opacity(self, im, opacity):
        '''
        设置水印透明度
        '''
        assert opacity >= 0 and opacity <= 1

        alpha = im.split()[3]
        alpha = ImageEnhance.Brightness(alpha).enhance(opacity)
        im.putalpha(alpha)
        return im

    def crop_image(self, im):
        '''裁剪图片边缘空白'''
        bg = Image.new(mode='RGBA', size=im.size)
        diff = ImageChops.difference(im, bg)
        del bg
        bbox = diff.getbbox()
        if bbox:
            return im.crop(bbox)
        return im

    def gen_mark(self):
        '''
        生成mark图片,返回添加水印的函数
        '''
        # 字体宽度
        width = len(self.args['mark']) * self.args['size']

        # 创建水印图片(宽度、高度)
        mark = Image.new(mode='RGBA', size=(width, self.args['size']))

        # 生成文字
        draw_table = ImageDraw.Draw(im=mark)
        draw_table.text(xy=(0, 0),
                        text=self.args['mark'],
                        fill=self.args['color'],
                        font=ImageFont.truetype(self.TTF_FONT,
                                                size=self.args['size']))
        del draw_table

        # 裁剪空白
        mark = self.crop_image(mark)

        # 透明度
        return self.set_opacity(mark, self.args['opacity'])

    def mark_im(self,  mark):
        ''' 在im图片上添加水印 im为打开的原图'''

        # 计算斜边长度
        c = int(math.sqrt(self.im.size[0] * self.im.size[0] + self.im.size[1] * self.im.size[1]))

        # 以斜边长度为宽高创建大图(旋转后大图才足以覆盖原图)
        mark2 = Image.new(mode='RGBA', size=(c, c))

        # 在大图上生成水印文字,此处mark为上面生成的水印图片
        y, idx = 0, 0
        while y < c:
            # 制造x坐标错位
            x = -int((mark.size[0] + self.args['space']) * 0.5 * idx)
            idx = (idx + 1) % 2

            while x < c:
                # 在该位置粘贴mark水印图片
                mark2.paste(mark, (x, y))
                x = x + mark.size[0] + self.args['space']
            y = y + mark.size[1] + self.args['space']

        # 将大图旋转一定角度
        mark2 = mark2.rotate(self.args['angle'])

        # 在原图上添加大图水印
        if self.im.mode != 'RGBA':
            self.im = self.im.convert('RGBA')
        self.im.paste(mark2,  # 大图
                 (int((self.im.size[0] - c) / 2), int((self.im.size[1] - c) / 2)),  # 坐标
                 mask=mark2.split()[3])
        del mark2
        return self.im

    def img_cut(self , left = 0, upper = 0, right = 0, lower =0):
        box = (left, upper, right, lower)
        self.im = self.im.crop(box)
        return self.im

    def mirror(self ):
        self.im = self.im.transpose(Image.FLIP_LEFT_RIGHT)
        return self.im


# 实例
args = {"angle":30, "color":'#8B8B1B', "file":'./a.jpg', "mark":u'www.baidu.com', "opacity":0.15, "out":'./output', "size":20, "space":75}
imask = IMask(args)
print imask.im.size
imask.mirror()
imask.add_mark()
imask.mirror()
imask.img_cut(right=700 , lower= 526)
imask.save()


处理结果: