Python 转换圆形、五边形、六边形、八边形PNG图片

################################################################################
### Copyright Version 1.00 by xiaozhanfeng, Last modify at 2020-01-13
### 本程序将图片转换为圆形、菱形、五边形、六边形、八边形的png文件,推送邮件
### 需转换的文件从convertimage.cfg读取
################################################################################

### 程序初始化
#coding=utf-8
import os,math,time                                                             # 系统,计算,时间库
from PIL import Image                                                           # 图形库
import smtplib as sb                                                            # 邮件库
from email.mime.text import MIMEText                                            # 邮件库
from email.header import Header                                                 # 邮件库

INTLISTcnttime=[0,0,0,0,0]                                                      # 功能运行耗时

################################################################################
### 处理一批图形文件
################################################################################  
def FUNCconvertimage(STRLISTfilenamein,STRfilenameoutflag):
    INTbegintime=time.perf_counter()
    for STRfilenameintmp in STRLISTfilenamein:
        STRfilenamein=STRfilenameintmp.split()
        STRfilenamein=STRfilenamein[0]
        INTcnttime=FUNCconvert(STRfilenamein,STRfilenameoutflag)
    INTcnttime=round(time.perf_counter()-INTbegintime)        
    return INTcnttime
    
################################################################################
### 处理一个图形文件
################################################################################  
def FUNCconvert(STRfilenamein,STRfilenameoutflag):
    INTbegintime=time.perf_counter()
    if os.path.exists(STRfilenamein):                                           # 输入图片不存在,直接返回
        FILEIMGhandlein=Image.open(STRfilenamein).convert("RGBA")               # 读入输入图片
        INTLISTsizeorg=FILEIMGhandlein.size                                     # 输入图片原始尺寸,高,宽
        INTlengthuse=min(INTLISTsizeorg[0],INTLISTsizeorg[1])                   # 剪裁后的图片尺寸,高,宽,正方形
        if INTLISTsizeorg[0] != INTLISTsizeorg[1]:                              # 输入图片剪裁为正方形
            FILEIMGhandlein.resize((INTlengthuse,INTlengthuse),Image.ANTIALIAS)
        FLOATtan18=math.tan(math.radians(18))                                   # 18度的正切值
        FLOATtan30=math.tan(math.radians(30))                                   # 30度的正切值
        FLOATtan36=math.tan(math.radians(36))                                   # 36度的正切值
        FLOATtan45=math.tan(math.radians(45))                                   # 45度的正切值
        FLOATsin45=math.sin(math.radians(45))                                   # 45度的正弦值
        FLOAT921=float(INTlengthuse/2)                                          # 1/2位置
        FLOAT5x1=float((INTlengthuse-INTlengthuse/2*FLOATtan36)*FLOATtan18)     # 五边形x轴位置1,正五边形内角108度
        FLOAT5x2=float(INTlengthuse-FLOAT5x1)                                   # 五边形x轴位置2,正五边形内角108度
        FLOAT5y1=float(INTlengthuse/2*FLOATtan36)                               # 五边形y轴位置,正五边形内角108度
        FLOAT6x1=float(INTlengthuse/2*FLOATtan30)                               # 六边形x轴位置1,正六边形内角120度
        FLOAT6x2=float(INTlengthuse-FLOAT6x1)                                   # 六边形x轴位置2,正六边形内角120度
        FLOAT8x1=float(INTlengthuse*FLOATsin45/(1+2*FLOATsin45))                # 八边形x轴位置1,正八边形内角135度
        FLOAT8x2=float(INTlengthuse-FLOAT8x1)                                   # 八边形x轴位置2,正八边形内角135度
                                                                                # 八边形x轴位置2,正八边形内角135度
        INTsize0,INTsize5,INTsize6,INTsize8=0,0,0,0
        if STRfilenameoutflag=="0" or STRfilenameoutflag=="9":                  # 圆形
            STRfilenameout0=STRfilenamein[0:len(STRfilenamein)-4]+"-circle.png" # 圆形输出文件名称
            FILEIMGhandleout0=Image.new('RGBA', (round(INTlengthuse),round(INTlengthuse)),(255,255,255,0))
                                                                                # 圆形输出文件
            IMGPIMhandleout0=FILEIMGhandleout0.load()                           # 圆形加载输出像素
        if STRfilenameoutflag=="5" or STRfilenameoutflag=="9":                  # 五边形
            STRfilenameout5=STRfilenamein[0:len(STRfilenamein)-4]+"-pentagon.png"
                                                                                # 五边形输出文件名称
            FILEIMGhandleout5=Image.new('RGBA', (round(INTlengthuse),round(INTlengthuse)),(255,255,255,0))
                                                                                # 五边形输出文件
            IMGPIMhandleout5=FILEIMGhandleout5.load()                           # 五边形加载输出像素
        if STRfilenameoutflag=="6" or STRfilenameoutflag=="9":                  # 六边形
            STRfilenameout6=STRfilenamein[0:len(STRfilenamein)-4]+"-hexagon.png"# 六边形输出文件名称
            FILEIMGhandleout6=Image.new('RGBA', (round(INTlengthuse),round(INTlengthuse)),(255,255,255,0))
                                                                                # 六边形输出文件
            IMGPIMhandleout6=FILEIMGhandleout6.load()                           # 六边形加载输出像素
        if STRfilenameoutflag=="8" or STRfilenameoutflag=="9":                  # 八边形
            STRfilenameout8=STRfilenamein[0:len(STRfilenamein)-4]+"-octagon.png"# 八边形输出文件名称
            FILEIMGhandleout8=Image.new('RGBA', (round(INTlengthuse),round(INTlengthuse)),(255,255,255,0))
                                                                                # 八边形输出文件
            IMGPIMhandleout8=FILEIMGhandleout8.load()                           # 八边形加载输出像素
        IMGPIMhandlein=FILEIMGhandlein.load()                                   # 加载输入像素 
        INToldpercent=0
        INTscale=1
        INTfornumber=INTlengthuse**2
        for INTposx in range(INTlengthuse): 
            for INTposy in range(INTlengthuse):
                INTnewpercent=round(INTscale/INTfornumber*100)
                if INTnewpercent>INToldpercent:
                    INToldpercent=INTnewpercent
                    INTcnttime=round(time.perf_counter()-INTbegintime)
                    os.system("clear")
                    print("正在处理{},坐标{:>4}*{:>4}的像素,耗时{:>3}秒,完成{:>2}%".format(STRfilenamein,INTposx,INTposy,INTcnttime,INTnewpercent))
                if STRfilenameoutflag=="0" or STRfilenameoutflag=="9":          # 圆形
                    if FUNCcircle(INTposx,INTposy,INTlengthuse,FLOAT921):
                        IMGPIMhandleout0[INTposx,INTposy]=IMGPIMhandlein[INTposx,INTposy]
                if STRfilenameoutflag=="5" or STRfilenameoutflag=="9":          # 五边形
                    if FUNCpentagon(INTposx,INTposy,INTlengthuse,FLOAT921,FLOAT5x1,FLOAT5x2,FLOAT5y1,FLOATtan18,FLOATtan36):
                        IMGPIMhandleout5[INTposx,INTposy]=IMGPIMhandlein[INTposx,INTposy]
                if STRfilenameoutflag=="6" or STRfilenameoutflag=="9":          # 六边形
                    if FUNChexagon(INTposx,INTposy,INTlengthuse,FLOAT921,FLOAT6x1,FLOAT6x2,FLOATtan30):
                        IMGPIMhandleout6[INTposx,INTposy]=IMGPIMhandlein[INTposx,INTposy]
                if STRfilenameoutflag=="8" or STRfilenameoutflag=="9":          # 八边形
                    if FUNCoctagon(INTposx,INTposy,INTlengthuse,FLOAT921,FLOAT8x1,FLOAT8x2,FLOATtan45):
                        IMGPIMhandleout8[INTposx,INTposy]=IMGPIMhandlein[INTposx,INTposy]
                INTscale+=1
        if STRfilenameoutflag=="0" or STRfilenameoutflag=="9":                  # 圆形
            FILEIMGhandleout0.save(STRfilenameout0)                             # 圆形输出文件
        if STRfilenameoutflag=="5" or STRfilenameoutflag=="9":                  # 五边形
            FILEIMGhandleout5.save(STRfilenameout5)                             # 五边形输出文件
        if STRfilenameoutflag=="6" or STRfilenameoutflag=="9":                  # 六边形
            FILEIMGhandleout6.save(STRfilenameout6)                             # 六边形输出文件
        if STRfilenameoutflag=="8" or STRfilenameoutflag=="9":                  # 八边形
            FILEIMGhandleout8.save(STRfilenameout8)                             # 八边形输出文件
    else:
        print("图形文件:"+STRfilenamein+"不存在!")
    INTcnttime=round(time.perf_counter()-INTbegintime)        
    return INTcnttime

################################################################################
### 计算圆形是否拷贝像素
################################################################################    
def FUNCcircle(INTposx,INTposy,INTlengthuse,FLOAT921):
    LOGIMGwrite=False
    FLOAT000=pow(pow(abs(INTposx-FLOAT921),2)+pow(abs(INTposy-FLOAT921),2),0.5) # 当前像素到圆心距离
    if FLOAT000<FLOAT921:
        LOGIMGwrite=True
    return LOGIMGwrite

################################################################################
### 计算五边形是否拷贝像素
################################################################################
def FUNCpentagon(INTposx,INTposy,INTlengthuse,FLOAT921,FLOAT5x1,FLOAT5x2,FLOAT5y1,FLOATtan18,FLOATtan36):
    LOGIMGwrite=False
    if   (INTposx<FLOAT921 and INTposy<FLOAT5y1) or (INTposx>FLOAT921 and INTposy<FLOAT5y1):
        if INTposy/abs(FLOAT921-INTposx)>FLOATtan36:
            LOGIMGwrite=True
    elif INTposx<FLOAT5x1 and INTposy>FLOAT5y1:
        if INTposx/abs(FLOAT5y1-INTposy)>FLOATtan18:
            LOGIMGwrite=True
    elif INTposx>FLOAT5x2 and INTposy>FLOAT5y1:
        if abs(INTlengthuse-INTposx)/abs(FLOAT5y1-INTposy)>FLOATtan18:
            LOGIMGwrite=True
    else:
        LOGIMGwrite=True
    return LOGIMGwrite

################################################################################
### 计算六边形是否拷贝像素
################################################################################
def FUNChexagon(INTposx,INTposy,INTlengthuse,FLOAT921,FLOAT6x1,FLOAT6x2,FLOATtan30):
    LOGIMGwrite=False
    if   (INTposx<FLOAT6x1 and INTposy<FLOAT921) or (INTposx<FLOAT6x1 and INTposy>FLOAT921):
        if INTposx/abs(FLOAT921-INTposy)>FLOATtan30:
            LOGIMGwrite=True
    elif (INTposx>FLOAT6x2 and INTposy<FLOAT921) or (INTposx>FLOAT6x2 and INTposy>FLOAT921):
        if abs(INTlengthuse-INTposx)/abs(FLOAT921-INTposy)>FLOATtan30:
            LOGIMGwrite=True
    else:
        LOGIMGwrite=True
    return LOGIMGwrite

################################################################################
### 计算八边形是否拷贝像素
################################################################################
def FUNCoctagon(INTposx,INTposy,INTlengthuse,FLOAT921,FLOAT8x1,FLOAT8x2,FLOATtan45):
    LOGIMGwrite=False
    if   INTposx<FLOAT8x1 and INTposy<FLOAT8x1:
        if INTposx/abs(FLOAT8x1-INTposy)>FLOATtan45:
            LOGIMGwrite=True
    elif INTposx<FLOAT8x1 and INTposy>FLOAT8x2:
        if INTposx/abs(FLOAT8x2-INTposy)>FLOATtan45:
            LOGIMGwrite=True
    elif INTposx>FLOAT8x2 and INTposy<FLOAT8x1:
        if abs(INTlengthuse-INTposx)/abs(FLOAT8x1-INTposy)>FLOATtan45:
            LOGIMGwrite=True
    elif INTposx>FLOAT8x2 and INTposy>FLOAT8x2:
        if abs(INTlengthuse-INTposx)/abs(FLOAT8x2-INTposy)>FLOATtan45:
            LOGIMGwrite=True
    else:
        LOGIMGwrite=True
    return LOGIMGwrite

################################################################################
### 打印主程序菜单,输入功能耗时,标准输出
################################################################################
def FUNCmenu(INTLISTcnttime):
    INTbegintime=time.perf_counter()
    os.system("clear")                                                          # 清屏
    print("将原始图片转换为指定形状的png透明图片,配置文件convertimage.cfg >>>>>>>>>")
    print("        0............转换圆形图,耗时{:>3}秒".format(INTLISTcnttime[0]))
    print("        5............转换五边形图,耗时{:>3}秒".format(INTLISTcnttime[1]))
    print("        6............转换六边形图,耗时{:>3}秒".format(INTLISTcnttime[2]))
    print("        8............转换八边形图,耗时{:>3}秒".format(INTLISTcnttime[3]))
    print("        9............转换全部图形,耗时{:>3}秒".format(INTLISTcnttime[4]))
    print("        Quit.........退出程序")
    INTcnttime=round(time.perf_counter()-INTbegintime)
    return INTcnttime
    
################################################################################
### 读取配置文件
################################################################################
def FUNCreadcfg(STRcfgfilename):
    STRLISTfilenamein=[]
    STRprinttext=""
    if os.path.exists(STRcfgfilename):
        FILEhandlein=open(STRcfgfilename)
        STRLISTfilenamein=FILEhandlein.readlines()
        FILEhandlein.close()
    else:
        STRprinttext="(配置文件:"+STRcfgfilename+"不存在)"
    return STRLISTfilenamein,STRprinttext
    
### 程序主体部分
while True:
    INTcnttime=FUNCmenu(INTLISTcnttime)
    STRLISTfilenamein,STRprinttext=FUNCreadcfg("convertimage.cfg")
    STRinput=input("        >>>>>>>>> 请输入选择项"+STRprinttext+":")
    STRinput=STRinput.lower()                                                   # 将输入项转换为小写
    if len(STRinput) !=1:
        continue
    elif STRinput not in "05689qe":
        continue
    elif STRinput=="0":
        INTLISTcnttime[0]=FUNCconvertimage(STRLISTfilenamein,STRinput)
    elif STRinput=="5":
        INTLISTcnttime[1]=FUNCconvertimage(STRLISTfilenamein,STRinput)
    elif STRinput=="6":
        INTLISTcnttime[2]=FUNCconvertimage(STRLISTfilenamein,STRinput)
    elif STRinput=="8":
        INTLISTcnttime[3]=FUNCconvertimage(STRLISTfilenamein,STRinput)
    elif STRinput=="9":
        INTLISTcnttime[4]=FUNCconvertimage(STRLISTfilenamein,STRinput)
    elif STRinput in "qe":
        break
    else:
        continue



################################################################################
### math模块说明
################################################################################
# 函数	            说明	                                                实例
# math.e	    自然常数e	                                                >>> math.e   2.718281828459045
# math.pi	    圆周率pi	                                                >>> math.pi   3.141592653589793
# math.degrees(x)   弧度转度	                                                >>> math.degrees(math.pi)   180.0
# math.radians(x)   度转弧度	                                                >>> math.radians(45)   0.7853981633974483
# math.exp(x)	    返回e的x次方	                                        >>> math.exp(2)   7.38905609893065
# math.expm1(x)	    返回e的x次方减1	                                        >>> math.expm1(2)   6.38905609893065
# math.log(x[, base])   返回x的以base为底的对数,base默认为e	                >>> math.log(math.e)   1.0   >>> math.log(2, 10)   0.30102999566398114
# math.log10(x)	    返回x的以10为底的对数	                                >>> math.log10(2)   0.30102999566398114
# math.log1p(x)	    返回1+x的自然对数(以e为底)	                        >>> math.log1p(math.e-1)   1.0
# math.pow(x, y)    返回x的y次方	                                        >>> math.pow(5,3)   125.0
# math.sqrt(x)	    返回x的平方根	                                        >>> math.sqrt(3)   1.7320508075688772
# math.ceil(x)	    返回不小于x的整数	                                        >>> math.ceil(5.2)   6.0
# math.floor(x)	    返回不大于x的整数	                                        >>> math.floor(5.8)   5.0
# math.trunc(x)	    返回x的整数部分	                                        >>> math.trunc(5.8)   5
# math.modf(x)	    返回x的小数和整数	                                        >>> math.modf(5.2)   (0.20000000000000018, 5.0)
# math.fabs(x)	    返回x的绝对值	                                        >>> math.fabs(-5)   5.0
# math.fmod(x, y)   返回x%y(取余)	                                        >>> math.fmod(5,2)   1.0
# math.fsum([x, y, ...])返回无损精度的和	                                >>> 0.1+0.2+0.3   0.6000000000000001   >>> math.fsum([0.1, 0.2, 0.3])   0.6
# math.factorial(x) 返回x的阶乘	                                                >>> math.factorial(5)   120
# math.isinf(x)	    若x为无穷大,返回True;否则,返回False	                >>> math.isinf(1.0e+308)   False   >>> math.isinf(1.0e+309)   True
# math.isnan(x)	    若x不是数字,返回True;否则,返回False	                >>> math.isnan(1.2e3)   False
# math.hypot(x, y)  返回以x和y为直角边的斜边长	                                >>> math.hypot(3,4)   5.0
# math.copysign(x, y)	若y<0,返回-1乘以x的绝对值;# 否则,返回x的绝对值	>>> math.copysign(5.2, -1)   -5.2
# math.frexp(x)	    返回m和i,满足m乘以2的i次方	                                >>> math.frexp(3)   (0.75, 2)
# math.ldexp(m, i)  返回m乘以2的i次方	                                        >>> math.ldexp(0.75, 2)   3.0
# math.sin(x)	    返回x(弧度)的三角正弦值	                                >>> math.sin(math.radians(30))   0.49999999999999994
# math.asin(x)	    返回x的反三角正弦值	                                        >>> math.asin(0.5)   0.5235987755982989
# math.cos(x)	    返回x(弧度)的三角余弦值	                                >>> math.cos(math.radians(45))   0.7071067811865476
# math.acos(x)	    返回x的反三角余弦值	                                        >>> math.acos(math.sqrt(2)/2)   0.7853981633974483
# math.tan(x)	    返回x(弧度)的三角正切值	                                >>> math.tan(math.radians(60))   1.7320508075688767
# math.atan(x)	    返回x的反三角正切值	                                        >>> math.atan(1.7320508075688767)   1.0471975511965976
# math.atan2(x, y)  返回x/y的反三角正切值	                                >>> math.atan2(2,1)   1.1071487177940904
# math.sinh(x)	    返回x的双曲正弦函数
# math.asinh(x)	    返回x的反双曲正弦函数
# math.cosh(x)	    返回x的双曲余弦函数
# math.acosh(x)	    返回x的反双曲余弦函数
# math.tanh(x)	    返回x的双曲正切函数
# math.atanh(x)	    返回x的反双曲正切函数
# math.erf(x)	    返回x的误差函数
# math.erfc(x)	    返回x的余误差函数
# math.gamma(x)	    返回x的伽玛函数
# math.lgamma(x)    返回x的绝对值的自然对数的伽玛函数

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值