美文网首页
PIL庫(中文驗證碼生成)

PIL庫(中文驗證碼生成)

作者: wong小尧 | 来源:发表于2017-12-19 18:02 被阅读0次

    公司要求做一個途牛網的驗證碼識別,需要用深度學習,為了生成對應網站驗證碼的訓練集,我網上搜了一些資料學習了一下,過程寫在這裡


    途牛.png
    #改變圖像大小
    from PIL import Image
    
    image = Image.open("1.jpg")
    #Image.BILINEAR代表雙線性插值法
    new_img1 = image.resize((256,256),Image.BILINEAR)
    new_img1.save("2.jpg")
    
    #旋轉45度,圖片如果不是正方形則會有缺失部分,
    new_img2 = image.rotate(45)
    new_img2.save("3.jpg")
    #需要相對完整的旋轉可以先轉成正方形
    new_img3 = new_img.rotate(45)
    new_img3.save("4.jpg")
    
    
    1.jpg
    2.jpg
    3.jpg
    4.jpg
    #直線繪製(可以繪製直線,弧線,橢圓,矩形等,這裡只介紹驗證碼中會出現的點,弧線和直線)
    from PIL import Image,ImageDraw
    
    image = Image.open("1.jpg")
    draw =ImageDraw.Draw(image)
    width,height = image.size
    ##前兩個參數為兩個坐標點,後面的參數為線條顏色,
    也可以用字符串"black"/"yellow"代替
    draw.line(((0,0),(width-1,height-1)),fill = 255)
    draw.line(((66,height-22),(width-29,15)),fill = 255)
    #draw.line(((66,height-22),(width-29,15)),fill = (255,0,0),width= 5)#選顏色和線寬
    
    
    image.save("5.jpg")
    
    5.jpg
    #點,點使用的方法是point(xy),但是單像素點很小看不清,
    #實際中用實心小圓代替
    #橢圓/圓的方法是ellipse([x1,y1,x2,y2],options)
    #[x1,y1,x2,y2],左上角坐標為(x1,y1),右下角坐標為(x2,y2)
    from PIL import Image,ImageDraw
    
    image = Image.open("1.jpg")
    draw =ImageDraw.Draw(image)
    width,height = image.size
    
    #畫圓:outline代表顏色,fill代表填充色
    draw2.ellipse((10,10,60,60),outline = 255,fill= 255)
    #畫點:就是一個小一點的圓
    draw2.ellipse((10,10,12,12),outline = 255,fill= 255)
    image.save("6.jpg")
    #畫弧線:draw.arc((10,10,60,60),startAngle,endAngle,fill = "blue")
    #(10,10,60,60)代表位置,startAngle,endAngle代表角度,這裡不做演示
    
    6.jpg
    # -*- coding: utf-8 -*-
    """
    Created on Tue Dec 19 11:20:03 2017
    
    @author: ers-wangyao
    """
    
    from PIL import Image,ImageDraw,ImageFont  
    import random  
    
    #獲取途牛網驗證碼的size
    image = Image.open("yzm_size.jpg")
    
    #前兩種類是隨機生成漢字
    #第一種方法unicode法,unicode編碼中漢字範圍是(0x4E00, 0x9FBF),
    #收錄了包含大量生僻字在內的兩萬多個漢字
    class RandomChar(): 
        
      @staticmethod  
      def Unicode():  
        val = random.randint(0x4E00, 0x9FBF)  
        return chr(val)    
    
    #第二種方法,GBK2312
    #GBK2312編碼採用兩個字節 相組合,第一個範圍是(0xB0, 0xF7),
    #第二個字節範圍(0xA1, 0xFe),收錄六千多常用漢字,可根據需求切換
      @staticmethod  
      def GB2312():  
        head = random.randint(0xB0, 0xF7)  
        body = random.randint(0xA1, 0xFe)   
        val = f'{head:x}{body:x}' 
        str = bytes.fromhex(val).decode('gb2312')  
        return str  
    
    #隨機數字
      @staticmethod  
      def randomNum():  
        num = random.randint(0, 9)  
        return str(num)  
    
    #隨機字母
      @staticmethod  
      def randomLetter():  
        s  = random.randint(65,90)
        r = chr(s)
        a = random.randint(0,1)
        if a == 0:
            return r.lower()
        else:
            return r
    
    class ImageChar:  
      def __init__(self, fontColor = (0, 0, 0),  
                         size = image.size,  
                         ##下載宋體文件并寫上絕對路徑
                         fontPath = 'C:/Users/CuiShan/Anaconda3/Lib/site-packages/matplotlib/mpl-data/fonts/ttf/simhei.ttf', 
                         bgColor = (255, 255, 255),  
                         fontSize = 25):  
        self.size = size  
        self.fontPath = fontPath  
        self.bgColor = bgColor  
        self.fontSize = fontSize  
        self.fontColor = fontColor  
        #ImageFont.truetype函數选择字体和字的大小
        self.font = ImageFont.truetype(self.fontPath, self.fontSize)
        #Image.new("RGB",(width,height),(255, 255, 255))新建一个Image,背景色是白色((0,0,0)就代表的颜色)
        self.image = Image.new('RGB', size, bgColor)    
      
        #隨機旋轉角度
      def rotate(self):  
        self.image.rotate(random.randint(0, 30), expand=0)    
      
        #插入文本drawObject.text(position,  string,  options)
      def drawText(self, position, txt, fill):  
        draw = ImageDraw.Draw(self.image)  
        draw.text(position, txt, font=self.font, fill=fill)  
      
        #隨機顏色,選擇較深的顏色(0,150)
      def randRGB(self):  
        return (random.randint(0, 150),  
               random.randint(0, 150),  
               random.randint(0, 150))  
        
        #隨機線段的起始點和終點
      def randPoint(self):  
        (width, height) = self.size  
        return (random.randint(0, width), random.randint(0, height))    
        
        #隨機線段
      def randLine(self, num):  
        draw = ImageDraw.Draw(self.image)  
        for i in range(0, num):  
          draw.line([self.randPoint(), self.randPoint()], self.randRGB())
     
        #隨機噪聲點,point畫的點太小,這裡畫一個實心小圓
      def randNoisePoint(self,num): 
        draw = ImageDraw.Draw(self.image)
        for i in range(0, num):
            color = self.randRGB()
            RandPoint = self.randPoint()
            draw.ellipse([RandPoint, tuple([i+1 for i in RandPoint])],outline = color,fill= color)
         
        #隨機弧線
      def randarc(self,num): 
        draw = ImageDraw.Draw(self.image) 
        for i in range(0, num):  
          startAngle = random.randint(0,360)
          endAngle = random.randint(0,360)
          draw.arc([self.randPoint(), self.randPoint()],startAngle,endAngle,fill = self.randRGB())
      
      #隨機純數字
      def randnum(self,num):
        #gap代表文字間隔
        gap = 5  
        start = random.randint(5, 20) 
        str = ''
        for i in range(num):  
          char = RandomChar().randomNum()
          str = str + char
          #隨機圖片位置
          x = start + self.fontSize * i + random.randint(0, gap) + gap * i  
          self.drawText((x + random.randint(0, 5), random.randint(5, 20)), char, self.randRGB()) 
          #旋轉
          self.rotate() 
        self.randLine(random.randint(1, 4))
        self.randarc(random.randint(1, 8))
        self.randNoisePoint(random.randint(100, 150))
        return str
        
      #隨機純字母
      def randletter(self,num):
        #gap代表文字間隔
        gap = 5  
        start = random.randint(5, 20) 
        str = ''
        for i in range(num):  
          char = RandomChar().randomLetter()
          str = str + char
          #隨機圖片位置
          x = start + self.fontSize * i + random.randint(0, gap) + gap * i  
          self.drawText((x + random.randint(0, 5), random.randint(5, 20)), char, self.randRGB()) 
          #旋轉
          self.rotate() 
        self.randLine(random.randint(1, 4))
        self.randarc(random.randint(1, 8))
        self.randNoisePoint(random.randint(100, 150))
        return str
    
        #隨機字母或者數字
      def randLN(self,num):
        #gap代表文字間隔
        gap = 5  
        start = random.randint(5, 20)
        str = ''
        for i in range(num):  
            a = random.randint(0,1)
            if a == 0:
                char = RandomChar().randomLetter()
                str = str + char
                #隨機圖片位置
                x = start + self.fontSize * i + random.randint(0, gap) + gap * i  
                self.drawText((x + random.randint(0, 5), random.randint(5, 20)), char, self.randRGB()) 
                #旋轉
                self.rotate()
            else:
                char = RandomChar().randomNum()
                str = str + char
                #隨機圖片位置
                x = start + self.fontSize * i + random.randint(0, gap) + gap * i  
                self.drawText((x + random.randint(0, 5), random.randint(5, 20)), char, self.randRGB()) 
                #旋轉
                self.rotate()
        self.randLine(random.randint(1, 4))
        self.randarc(random.randint(1, 8))
        self.randNoisePoint(random.randint(100, 150))
        return str
          
        #隨機中文
      def randChinese(self, num):  
        #gap代表文字間隔
        gap = 5  
        start = random.randint(5, 20) 
        str = ''
        for i in range(num):  
          char = RandomChar().GB2312() 
          str = str + char
          #隨機圖片位置
          x = start + self.fontSize * i + random.randint(0, gap) + gap * i  
          self.drawText((x + random.randint(0, 5), random.randint(5, 20)), char, self.randRGB()) 
          #旋轉
          self.rotate()
        #隨機添加一定數量的線段和點
        self.randLine(random.randint(1, 4))
        self.randarc(random.randint(1, 8))
        self.randNoisePoint(random.randint(100, 150))
        return str
      
      def save(self, path):  
        self.image.save(path) 
    
    純數字.png 純字母.png 數字字母.png 中文.png
    #for i in range(20): 
    #    ic = ImageChar()
        #生成中文
    #    s = ic.randChinese(4)
        #生成純數字
    #    s = ic.randnum(4)
        #生成純字母
    #    s = ic.randletter(4)
        #生成數字字母
    #    s = ic.randLN(4)
    #    filename = "%05s.jpg" % s
    #    ic.save(filename)  
    

    相关文章

      网友评论

          本文标题:PIL庫(中文驗證碼生成)

          本文链接:https://www.haomeiwen.com/subject/ihmmwxtx.html