美文网首页
Python图片处理脚本,个人用于Unity图片处理

Python图片处理脚本,个人用于Unity图片处理

作者: hh5460 | 来源:发表于2019-09-17 14:14 被阅读0次

    先介绍功能点

    原图

    原图.png
    1.自动裁切掉透明像素(可对边缘透明度过滤)
    处理后.png
    2.自动裁切后充满填充到目标像素
    image.png image.png
    3.不裁切自动缩放后填充到目标像素
    image.png
    4.将图片自动处理到etc2压缩支持的格式,即长和宽都是4的倍数
    image.png
    5.将图片自动处理到pvrtc压缩支持的格式,即长和宽都是2的n次幂(这里长宽都取最近,不强行处理成正方形)
    处理前
    处理后
    6.将图片自动处理到pvrtc压缩支持的格式,即长和宽都是2的n次幂(这里强行处理为正方形)
    处理前
    处理后
    import os
    from PIL import Image
    
    ##########################################################
    ##未封装成类,需要请自行修改
    ##########################################################
    
    def get_auto_crop_box(img,filter_alpha):
        '''
        删除一张图的空白元素,img为原图像,filterAlpha为四边Alpha的过滤强度0-255,返回 [裁切范围Box]
        '''
        if img.mode!='RGBA':
            raise AttributeError('非RBGA图像,没有Alpha通道~')
        if filter_alpha<0 or filter_alpha>=255:
            raise AttributeError('filter_alpha范围是[0,255)')
        w,h = img.size
        top_2_bottom_row = 0    #从上往下扫描得到行
        bottom_2_top_row = h    #从下网上扫描得到行
        left_2_right_col = 0    #从左往右扫描得到列
        right_2_left_col = w    #从右往左扫描得到列
        isDone = False
        for i in range(h):
            if isDone:
                break
            for j in range(w):
                if(img.getpixel((j,i))[3]>filter_alpha):
                    isDone = True
                    top_2_bottom_row = i
                    break
        isDone = False
        for i in range(h-1,-1,-1):
            if isDone:
                break
            for j in range(w-1,-1,-1):
                if(img.getpixel((j,i))[3]>filter_alpha):
                    isDone = True
                    bottom_2_top_row = i
                    break
        isDone = False
        for i in range(w):
            if isDone:
                break
            for j in range(h):
                if(img.getpixel((i,j))[3]>filter_alpha):
                    isDone = True
                    left_2_right_col = i
                    break
        isDone = False
        for i in range(w-1,-1,-1):
            if isDone:
                break
            for j in range(h-1,-1,-1):
                if(img.getpixel((i,j))[3]>filter_alpha):
                    isDone = True
                    right_2_left_col = i
                    break
        
        if top_2_bottom_row>bottom_2_top_row or left_2_right_col > right_2_left_col:
            raise AttributeError('检测到图像是纯透明图像~')
    
        return (left_2_right_col,top_2_bottom_row,right_2_left_col,bottom_2_top_row)
    
    def get_auto_crop_box_image(img,filter_alpha):
        '''
        删除一张图的空白元素,img为原图像,filterAlpha为四边Alpha的过滤强度0-255.并返回 [新的Image]
        '''
        return img.crop(get_auto_crop_box(img,filter_alpha))
    
    def get_auto_resize_box(img_w_h,resize_w_h):
        '''
        将图片本身根据长宽比匹配到需要缩放的尺寸,该尺寸是自身匹配目标尺寸进行无损缩放后的尺寸,返回该 [尺寸]
        PS:注意,这里的缩放指的是原图如果要匹配到指定目标尺寸,自身最终会无损缩放到的尺寸,并不会对边缘进行填充变成指定的resize_w_h大小,若要此变化,可再进一步get_img_copy_2_transparent_image操作
        '''
        if resize_w_h[0]<=0 or resize_w_h[1]<=0:
            raise AttributeError('无法将图像缩放到小于等于0')
    
        ratio_w = img_w_h[0]/resize_w_h[0]    #目标图像和需要缩放的尺寸的宽度比
        ratio_h = img_w_h[1]/resize_w_h[1]    #目标图像和需要缩放的尺寸的高度比
        img_new_w_h = img_w_h
        if ratio_w>ratio_h:
            #宽度比大于高度比,则以宽度为准去匹配需要缩放的宽度
            img_new_w_h = (resize_w_h[0],(int)(img_w_h[1]/ratio_w))
        else:
            #高度比大于宽度比,则以高度为准去匹配需要缩放的高度
            img_new_w_h = ((int)(img_w_h[0]/ratio_h),resize_w_h[1])
        return img_new_w_h   
    
    def get_auto_resize_box_image_no_fill(img,resize_w_h):
        '''
        将图片本身根据长宽比匹配到需要缩放的尺寸,该尺寸是自身匹配目标尺寸进行无损缩放后的尺寸,并返回 [新的Image]
        PS:注意,这里的缩放指的是原图如果要匹配到指定目标尺寸,自身最终会无损缩放到的尺寸,并不会对边缘进行填充变成指定的resize_w_h大小,若要此变化,可再进一步get_img_copy_2_transparent_image操作
        '''
        return img.resize(get_auto_resize_box(img.size,resize_w_h))
    
    def get_auto_resize_box_image_fill(img,resize_w_h):
        '''
        将图片本身根据长宽比匹配到需要缩放的尺寸,然后填充到resize_w_h尺寸中取,并返回 [新的Image]
        '''
        return get_img_copy_2_transparent_image(img.resize(get_auto_resize_box(img.size,resize_w_h)),resize_w_h)
    
    def get_img_copy_2_transparent_image(img,resize_w_h):
        '''
        将图像填充到指定resize_w_h透明图像的中间,并返回 [新的Image]
        '''
        new_img = img
        if resize_w_h[0]<new_img.size[0] or resize_w_h[1]<new_img.size[1]:
            new_img = get_auto_resize_box_image_no_fill(img,resize_w_h)             
        newImage = Image.new('RGBA',resize_w_h)
        startPoint = (int((newImage.size[0]-new_img.size[0])/2),int((newImage.size[1]-new_img.size[1])/2))
        newImage.paste(new_img.copy(),startPoint)
        return newImage
    
    def auto_resize_with_set_width(img,width):
        '''
        指定宽度让高度自动缩放,返回缩放后 [新的Image]
        '''
        if width<=0:
            raise AttributeError('width不能小于等于0~')
        r = img.size[0]/width
        new_height = int(img.size[1]/r)
        return img.resize((width,new_height))
    
    def auto_resize_with_set_height(img,height):
        '''
        指定高度让宽度自动缩放,返回缩放后 [新的Image]
        '''
        if height<=0:
            raise AttributeError('height~')
        r = img.size[1]/height
        new_width = int(img.size[0]/r)
        return img.resize((new_width,height))
    
    def get_auto_crop_and_resize_and_fill_image(img,resize_w_h,filter_alpha):
        '''
        自动裁切图片并指定缩放到目标尺寸,不拉伸,自动等比缩放后再填充到目标像素大小
        img为原图像
        resize_w_h为指定缩放尺寸
        filterAlpha为四边Alpha的过滤强度0-255
        返回 [新图像]
        '''
        return get_auto_resize_box_image_fill(get_auto_crop_box_image(img,filter_alpha),resize_w_h)
    
    def deal_img_2_etc2_support(img):
        '''
        #将图片处理成etc2 压缩格式支持的大小,即长和宽必须都是4的倍数
        '''
        res_w = 4
        res_h = 4
        if img.size[0]>=4:
            modnum = img.size[0] % 4
            if modnum < 2:
                res_w = img.size[0] - modnum
            else:
                res_w = img.size[0] + (4 - modnum)
    
        if img.size[1]>=4:
            modnum = img.size[1] % 4
            if modnum < 2:
                res_h = img.size[1] - modnum
            else:
                res_h = img.size[1] + (4 - modnum)
    
        return get_auto_resize_box_image_fill(img,(res_w,res_h))
        
    def deal_img_2_pvrtc_support(img):
        '''
        #将图片处理成pvrtc压缩格式支持的大小,即长和宽必须都是2的幂次方,这里不处理成为正方形,下面的方法处理成正方形
        '''
        res_w = 1
        res_h = 1
        min_2 = 0
        max_2 = 0  
        surplus = img.size[0]
        while(True):
            surplus = surplus - (2**max_2)
            if max_2 == 0:
                max_2 += 1
            else:
                min_2 += 1
                max_2 += 1
    
            if surplus <= 0:
                if abs((2**min_2)-img.size[0]) <= abs((2**max_2)-img.size[0]):
                    res_w = 2**min_2
                else:
                    res_w = 2**max_2
                break
    
        min_2 = 0
        max_2 = 0  
        surplus = img.size[1]
        while(True):
            surplus = surplus - (2**(max_2))
            if max_2 == 0:
                max_2 += 1
            else:
                min_2 += 1
                max_2 += 1
    
            if surplus <= 0:
                if abs((2**min_2)-img.size[1]) <= abs((2**max_2)-img.size[1]):
                    res_h = (2**min_2)
                else:
                    res_h = (2**max_2)
                break
    
        return get_auto_resize_box_image_fill(img,(res_w,res_h))
    
    def deal_img_2_pvrtc_support_with_square(img):
        '''
        #将图片处理成pvrtc压缩格式支持的大小,即长和宽必须都是2的幂次方,一般避免拉伸处理成正方形,这里处理成正方形
        '''
        bigger_side = max(img.size[0],img.size[1])
        res_side = 1
        min_2 = 0
        max_2 = 0
        
        surplus = bigger_side
        while(True):
            surplus = surplus - 2**max_2
            if max_2 == 0:
                max_2 += 1
            else:
                min_2 += 1
                max_2 += 1
    
            if surplus <= 0:
                if abs((2**min_2)-bigger_side) <= abs((2**max_2)-bigger_side):
                    res_side = 2**min_2
                else:
                    res_side = 2**max_2
                break
    
        return get_auto_resize_box_image_fill(img,(res_side,res_side))
    
    ############################################################################
    ################################  分割线  ###################################
    ############################################################################
    
    print('start')
    
    lstfiles = os.listdir()
    for i in lstfiles:
        if os.path.isfile(i):
            if os.path.splitext(i)[1].lower() in ('.png','.jpg','tga'): ##需要则补充
                img = Image.open(i)
                new_image = deal_img_2_pvrtc_support_with_square(img)
                new_image.save('new_'+i)
    
    print('end')
    

    相关文章

      网友评论

          本文标题:Python图片处理脚本,个人用于Unity图片处理

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