Python 生成随机验证码图像(数字与大小写字母组合,验证码图像旋转并添加图像噪声,生成bmp图像)

Python 生成随机验证码(数字与大小写字母组合,验证码图像旋转并添加图像噪声,生成bmp图像)

代码如下:

from array import array
import random
import cv2 
import PIL.ImageFont as ImageFont
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt

# http://mirrors.aliyun.com/pypi/simple/

class bmp:
    """ bmp data structure """
 
    def __init__(self, w=1080, h=1920, color = 0xffffff):
        self.w = w
        self.h = h
        self.gen_bmp_header()
        self.paint_bgcolor(color)
 
    def calc_data_size (self):
        if((self.w*3)%4 == 0):
            self.dataSize = self.w * 3 * self.h
        else:
            self.dataSize = (((self.w * 3) // 4 + 1) * 4) * self.h
 
        self.fileSize = self.dataSize + 54
 
    def conv2byte(self, l, num, len):
        tmp = num
        for i in range(len):
            l.append(tmp & 0x000000ff)
            tmp >>= 8
 
    def gen_bmp_header (self):
        self.calc_data_size();
        self.bmp_header = [0x42, 0x4d]
        self.conv2byte(self.bmp_header, self.fileSize, 4) #file size
        self.conv2byte(self.bmp_header, 0, 2)
        self.conv2byte(self.bmp_header, 0, 2)
        self.conv2byte(self.bmp_header, 54, 4) #rgb data offset
        self.conv2byte(self.bmp_header, 40, 4) #info block size
        self.conv2byte(self.bmp_header, self.w, 4)
        self.conv2byte(self.bmp_header, self.h, 4)
        self.conv2byte(self.bmp_header, 1, 2)
        self.conv2byte(self.bmp_header, 24, 2) #888
        self.conv2byte(self.bmp_header, 0, 4)  #no compression
        self.conv2byte(self.bmp_header, self.dataSize, 4) #rgb data size
        self.conv2byte(self.bmp_header, 0, 4)
        self.conv2byte(self.bmp_header, 0, 4)
        self.conv2byte(self.bmp_header, 0, 4)
        self.conv2byte(self.bmp_header, 0, 4)
 
    def print_bmp_header (self):
        length = len(self.bmp_header)
        for i in range(length):
            print("{:0>2x}".format(self.bmp_header[i]), end=' ')
            if i%16 == 15:
                print('')
        print('')
 
    def paint_bgcolor(self, color=0xFFB6C1):
        self.rgbData = []
        for r in range(self.h):
            self.rgbDataRow = []
            for c in range(self.w):
                self.rgbDataRow.append(color)
            self.rgbData.append(self.rgbDataRow)
 
    def paint_line(self, x1, y1, x2, y2, color):
        k = (y2 - y1) / (x2 - x1)
        for x in range(x1, x2+1):
            y = int(k * (x - x1) + y1)
            self.rgbData[y][x] = color
 
    def paint_rect(self, x1, y1, w, h, color):
        for x in range(x1, x1+w):
            for y in range(y1, y1+h):
                self.rgbData[y][x] = color
 
    def paint_point(self, x, y, color=0x000000):
        self.rgbData[y][x] = color
 
    def save_image(self, name="save.bmp"):
        f = open(name, 'wb')
 
        #write bmp header
        f.write(array('B', self.bmp_header).tobytes())
 
        #write rgb data
        zeroBytes = self.dataSize // self.h - self.w * 3
 
        for r in range(self.h):
            l = []
            for i in range(len(self.rgbData[r])):
                p = self.rgbData[r][i]
                l.append(p & 0x0000ff)
                p >>= 8
                l.append(p & 0x0000ff)
                p >>= 8
                l.append(p & 0x0000ff)
 
            f.write(array('B', l).tobytes())
 
            for i in range(zeroBytes):
                f.write(bytes([0x00]))
 
        #close file
        f.close()
        


def generate_text(text):
    
    global mask
    
    fnt = ImageFont.truetype('arial.ttf', 60)

    img = Image.new("RGB",fnt.getsize(text),(255,182,193))
    
    #img = Image.new("RGB",(32,32),(255,182,193))
    
    mask = [x for x in fnt.getmask(text, mode='RGB')]

    img.putdata(mask)

    #img = img.convert('RGB')

    return img

def rgb2hex(RGB):
    text = '0x' + ''.join([hex(i)[-2:].replace('x', '0') for i in list(map(int, RGB))])
    return text

 
if __name__ == '__main__':
 
    w = int(45*6*2*0.677)
    h = 45*2
    image = bmp(w, h)
    image.paint_bgcolor(color=0xFFB6C1)
    for i in range(w):
        ii = random.randint(0,h-1)
        r = random.randint(0,255)
        g = random.randint(0,255)
        b = random.randint(0,255)
        rgb = r*256*256+g*256+b
        image.paint_point(i,ii,rgb)
 
    image.save_image("save1.bmp")
    import os
    os.system("save1.bmp")
    img_bg = cv2.imread("save1.bmp")
    img3 = img_bg
    img_change = Image.fromarray(cv2.cvtColor(img_bg, cv2.COLOR_BGR2RGB))
    code = ''
    code_end = ""
    for i in range(6):
        code = ''
        n = random.randint(0, 9)
        b = chr(random.randint(65, 90))
        s = chr(random.randint(97, 122))
        #code = str(random.choice([n, b, s]))
        code_c = [n,b,s]
        choice = random.randint(0,2)
        code = code_c[choice]
        code_end += str(code)
        img_smaller = generate_text(str(code))
        angle = random.randint(0,4)
        angle2 = random.randint(0,90)
        img_smaller = img_smaller.rotate(angle2)
        if angle == 0:
            img_smaller  = img_smaller.transpose(Image.ROTATE_270)
        elif angle == 1:
            img_smaller  = img_smaller.transpose(Image.ROTATE_180)
        elif angle == 2:
            img_smaller  = img_smaller.transpose(Image.ROTATE_90) 
        else:
            print(end="")   
        #img_smaller.resize((28,22))
        #img2 = cv2.imread("1.jpg")
        img_change.paste(img_smaller,(60*i,10))
        
print(code_end)
img_change.show()               

效果如下:

 

 

你可能感兴趣的:(Python,编程和应用实现,python,opencv,计算机视觉)