#!/usr/bin/python # -*- coding: GBK -*- #------------------------------------------------------------------------------- # #------------------------------------------------------------------------------- # ##@package VerificationCodePic # # @todo: Ëæ»úÉú³ÉͼƬ # @author zhengyang # @date 2010-02-25 17:30 # @version 1.4 # # # ÐÞ¸Äʱ¼ä ÐÞ¸ÄÈË ÐÞ¸ÄÄÚÈÝ # @change: 2011-06-20 14:00 zhengyang ÐÞ¸´ÒýÓÃ×ÖÌ屨´í£¬ÐÞ¸´Éú³ÉÃüÃû¸²¸Ç # @change: 2011-06-22 14:00 zhengyang Ôö¼Ó¹¦ÄܶÔ×îÖÕÉú³Éͼ½øÐмôÇÐ # @change: 2011-06-23 12:00 zhengyang Ôö¼Ó×ÖÌå¼ÓÔØ ĬÈϼÓÔØ¸ù·¾¶ÏÂ×ÖÌ壬Ȼºó²éÕÒϵͳ×ÖÌå # @change: 2011-07-11 18:00 Alee Ð޸İü ´óСдÎÊÌ⣬ͼƬ¶àÒ»ÕÅ # @note: #============================================================================== """Version = 2011-07-11 18:00""" #============================================================================== #µ¼ÈëÈý¸öÄ£¿é #try: # import PIL.Image as Image # import PIL.ImageDraw as ImageDraw # import PIL.ImageFont as ImageFont # import PIL.ImageFilter as ImageFilter #except: # import Image, ImageDraw, ImageFont, ImageFilter # import random import math #import dict4ini._dict4ini import os import sys import time ##¼ÓÔØPY·¾¶ # @param importDir µ¼ÈëµÄ½Å±¾Â·¾¶ # @return ·µ»ØÖµÎÞÒâÒå def ImportFile(importDir): tmpImportDir = '' for dirName in os.listdir(os.getcwd()): if not os.path.isdir(dirName) or dirName.lower() != importDir: continue tmpImportDir = dirName curPath = os.getcwd()+'\\'+tmpImportDir if curPath in sys.path: continue sys.path.append(curPath) #¼ÓÔØÂ·¾¶£¬±ÜÃâ´óСдÎÊÌâ ImportFile('pil') ImportFile('dict4ini') import Image, ImageDraw, ImageFont, ImageFilter import _dict4ini config = _dict4ini.DictIni('config.ini', format="%s=%s") #--------------------------------------------------------------------------- def GetRGBColor(min=0, max=255): return random.choice(range(min, max + 1)) def GetColor(rgbList): return (GetRGBColor(rgbList[0], rgbList[1]), GetRGBColor(rgbList[2], rgbList[3]), GetRGBColor(rgbList[4], rgbList[5])) def Log(*args): print args class CodePic(): count = 0 def __init__(self, config): self.background = config.background self.text = config.text self.confusion = config.confusion self.output = config.output self.fontDict = {} # {'×ÖÌå': {'×ÖºÅ': fontIns}} def CreateCodePic(self): # ´´½¨±³¾°Í¼Æ¬ if self.background.type == 1: image = self.CreateBackImg() elif self.background.type == 2: Log('background.type:%s, not realized'%self.background.type) image = self.CreateBackImg() else: Log('background.type:%s, not defined'%self.background.type) return # ÌîдÕýÎÄ colorList, content, value = self.FillText(image) # Ìí¼Ó¸ÉÈÅ self.AddConfusion(image, colorList) # Êä³ö return self.OutPut(image, content, value) # Ôö¼Ó¸ÉÈÅ def AddConfusion(self, image, colorList): # ¸ÉÈÅ×ÜÁ¿ confusionCount = self.confusion.linecount+self.confusion.pointcount # 1.ʹÓÃĬÈÏÑÕÉ« 2.ÿ¸ö¸ÉÈÅËæ»úÑÕÉ« 3.Ëæ»úÒ»¸öÑÕÉ«ËùÓÐ×Ö·û¹²Í¬Ê¹Óà if self.confusion.colortype == 1: color = [self.confusion.defaultcolor]*confusionCount elif self.confusion.colortype == 2: # ´Ó×ÖÌåÑÕÉ«ÖÐÈ¡ if self.confusion.randomfontcolor: color = [random.choice(colorList) for i in range(confusionCount)] else: color = [GetColor(self.confusion.randomcolor) for i in range(confusionCount)] elif self.confusion.colortype == 3: # ´Ó×ÖÌåÑÕÉ«ÖÐÈ¡ if self.confusion.randomfontcolor: color = [random.choice(colorList)] * confusionCount else: color = [GetColor(self.confusion.randomcolor)] * confusionCount draw = ImageDraw.Draw(image) # Ï߸ÉÈÅ if self.confusion.line: for i in range(self.confusion.linecount): #¶¼ÊÇËæ»úµÄ x1 = random.randint(0,self.background.width) x2 = random.randint(0,self.background.width) y1 = random.randint(0,self.background.height) y2 = random.randint(0,self.background.height) size = random.choice(range(self.confusion.size[0], self.confusion.size[1])) draw.line([(x1, y1), (x2, y2)], tuple(color[i]), width=size) # µã¸ÉÈÅ if self.confusion.point: for i in range(self.confusion.pointcount): #¶¼ÊÇËæ»úµÄ x1 = random.randint(0,self.background.width) y1 = random.randint(0,self.background.height) # x2 = random.randint(0,width) # y2 = random.randint(0,height) draw.point((x1, y1), tuple(color[i])) # Êä³ö def OutPut(self, image, content, value): # 1.Á÷Ë®ºÅ 2.ÄÚÈÝ 3.¶ÔÓ¦µÄº¬Òå if self.output.filenametype == 1: name = CodePic.count elif self.output.filenametype == 2: name = content elif self.output.filenametype == 3: name = value else: Log('output.filenametype.type:%s, not defined'%self.output.filenametype) return False # ºó׺ ext = self.output.filetype path = self.output.outpath if os.path.isabs(path): filePath = os.path.join(path, '%s.%s'%(name, ext)) else: savePath = os.path.join(os.getcwd(), path) if not os.path.isdir(savePath): os.mkdir(savePath) filePath = os.path.join(os.getcwd(), path, '%s.%s'%(name, ext)) # ÒѾ­´æÔÚÁË if os.path.exists(filePath): return False image.filter(ImageFilter.BLUR) box = self.output.crop image = image.crop(box) image.save(filePath) CodePic.count += 1 return True # ´´½¨±³¾°Í¼Æ¬ def CreateBackImg(self): #ͼƬ¿í¶È width = self.background.width #ͼƬ¸ß¶È height = self.background.height #±³¾°ÑÕÉ« if self.background.colortype == 1: bgcolor = tuple(self.background.defaultcolor) elif self.background.colortype == 2: bgcolor = GetColor(self.background.randomcolor) else: Log('background.colortype:%s not defined'%self.background.colortype) bgcolor = tuple(self.background.defaultcolor) #Éú³É±³¾°Í¼Æ¬ image = Image.new('RGB',(width,height),bgcolor) return image # Ìî³äÕýÎÄ def FillText(self, image): #ÐÂͼƬ newImage = image.copy() #ÉèÖñ¸·Ý newImageEx = image.copy() #ÉèÖñ¸·Ý colorList = [] draw = ImageDraw.Draw(newImage) content, value = self.GetContent(self.text) # 1.ʹÓÃĬÈÏÑÕÉ« 2.ÿ¸ö×Ö·ûËæ»úÑÕÉ« 3.Ëæ»úÒ»¸öÑÕÉ«ËùÓÐ×Ö·û¹²Í¬Ê¹Óà if self.text.colortype == 1: colorList = len(content) * [self.text.defaultcolor] elif self.text.colortype == 2: colorList = [GetColor(self.text.randomcolor) for i in range(len(content))] elif self.text.colortype == 3: colorList = len(content) * [GetColor(self.text.randomcolor)] else: Log('text.colortype:%s not defined'%self.text.colortype) # 1.ʹÓÃĬÈÏ×ÖÌå 2.ÿ¸ö×Ö·ûËæ»ú×ÖÌå 3.Ëæ»úÒ»¸ö×ÖÌåËùÓÐ×Ö·û¹²Í¬Ê¹Óà if self.text.fonttype == 1: fontTypeList = len(content) * [self.defaultfont] elif self.text.fonttype == 2: fontTypeList = [random.choice(self.text.randomfont) for i in range(len(content))] elif self.text.fonttype == 3: fontTypeList = len(content) * [random.choice(self.text.randomfont)] else: Log('text.fonttype:%s not defined'%self.text.fonttype) # ¿ªÊ¼»æÖÆ for k, v in enumerate(content): hpos = random.choice(range(self.text.voffset[0], self.text.voffset[1]))+k*self.text.hspace vpos = random.choice(range(self.text.voffset[0], self.text.voffset[1])) fontSize = random.choice(self.text.fontsize) font = None if self.fontDict.has_key(fontTypeList[k]): if self.fontDict[fontTypeList[k]].has_key(fontSize): font = self.fontDict[fontTypeList[k]][fontSize] if not font: filename = fontTypeList[k] + '.ttf' filePath = os.path.join(os.getcwd(), filename) if os.path.isfile(filePath): filaname = filePath else: windir = os.environ.get("WINDIR") if windir: filename = os.path.join(windir, "fonts", filename) font = ImageFont.truetype(filename, fontSize) self.fontDict[fontTypeList[k]] = {} self.fontDict[fontTypeList[k]][fontSize] = font fontcolor = colorList[k] draw.text((self.text.starth + hpos, self.text.startv + vpos),v,font=font,fill=fontcolor) del draw # ÖÆ×÷ŤÇú # hdistortion = 0.5 # vdistortion = 0 #loadÏñËØ newPix = newImage.load() pix = newImageEx.load() offset = 0 for y in range(0, self.background.height): offset += self.text.hdistortion for x in range(0, self.background.width): #еÄx×ø±êµã newx = x - offset #Äã¿ÉÒÔÊÔÊÔÈçϵÄЧ¹û # newx = x + math.sin(3.0*math.pi*y/height)*8 if 0 < newx < self.background.width: #°ÑÔ´ÏñËØÍ¨¹ýÆ«ÒÆµ½ÐµÄÏñËØµã pix[newx,y] = newPix[x,y] newPix = newImageEx.load() pix = image.load() offset = 0 for x in range(0, self.background.width): offset += self.text.vdistortion for y in range(0, self.background.height): #еÄy×ø±êµã newy = y - offset #Äã¿ÉÒÔÊÔÊÔÈçϵÄЧ¹û # newx = x + math.sin(3.0*math.pi*y/height)*8 if 0 < newy < self.background.height: #°ÑÔ´ÏñËØÍ¨¹ýÆ«ÒÆµ½ÐµÄÏñËØµã pix[x,newy] = newPix[x,y] return colorList, ''.join(content), value # ·µ»ØÕýÎÄÓõ½µÄÉ«²Ê # »ñÈ¡ÎÄ×Ö def GetContent(self, text): strList = [] # ×Ö·ûºòÑ¡Áбí retText = [] # ·µ»ØµÄÎÄ×ÖÁбí # ËùÓÐ×Ö·ûͳһ²ÉÑù if text.createtype == 1: if text.expr and random.random() < text.exprrate: element = text.exprelem digit = [random.choice(range(element[0],element[1])), random.choice(range(element[0],element[1]))] operator = random.choice(text.exproperator) if operator == '-' and not text.exprallownegsub: digit.sort() retText = list(str(digit[1])) + [operator] + list(str(digit[0])) + ['='] #¼ÆË㹫ʽֵ expr = ''.join(retText[:-1]) transDict = { '+':'+', '-':'-' } for k, v in transDict.items(): if k in expr: temp = expr.replace(k, v) value = eval(temp) return retText, value if text.digital: strList = strList + range(0, 10) if text.supper: strList = strList + [chr(i) for i in range(ord('A'), ord('Z') + 1)] if text.lower: strList = strList + [chr(i) for i in range(ord('a'), ord('z') + 1)] for i in range(text.chrcount): retText.append(str(random.choice(strList))) elif text.createtype == 2: retText = [str(random.choice(text['chr%s'%i])) for i in range(text.chrcount)] else: Log('text.createtype:%s not defined'%self.text.createtype) value = ''.join(retText) if text.ignoresupper: value = value.lower() return retText, value maker = CodePic(config) def Make(count): stime = time.time() temp = 0 while temp < count: if maker.CreateCodePic(): print 'making %s/%s ...'%(temp, count) temp += 1 print 'time cost:', time.time() - stime if __name__ == '__main__': if len(sys.argv) == 2: count = int(sys.argv[1]) Make(count) else: Make(10)