美文网首页Python
iOS【图片国际化处理】python脚本Assets.xcass

iOS【图片国际化处理】python脚本Assets.xcass

作者: NJ_墨 | 来源:发表于2021-10-05 16:35 被阅读0次

    相关国际化处理:
    iOS【语言国际化处理】python脚本读取Excel内容批量导入国际化语言文件中(一)
    iOS【语言国际化处理】python脚本将国际化语言文件批量导入Excel文件中(二)
    iOS【图片国际化处理】python脚本Assets.xcassets图片名称及MD5批量处理(三)

    iOS项目图片资源文件名批量调整(添加或替换前缀)

    在国际化处理过程中,图片资源偶尔进行调整;

    同时也可以修复xx. imageset文件下xxa.png的文件名不一致问题,
    最好统一的样式是:xx. imageset文件下xx.png

    同时导出资源文件中不合理的资源、命名等:
    如文件夹、图片名大小写、资源图片里有gif、jpg等,
    (这里没有修复统一改成小写,不然使用的地方要进行调整)
    导出相关异常数据【errorName.txt】文件

    更新内容

    1、修改图片的md5值(脚本中方法:get_file_md5change_file_md5

    终端查看md5命令: md5 -q 文件路径
    $ md5 -q /Users/odd/test/user.png
    e27610a6e720bd58f2eebf07cb9ddead

    修改 md5 值
    终端:输入「echo」,任意字符,「>>」,文件路径,命令如下
    $ echo a >> /Users/odd/test/user.png

    文件结构示意图 异常示意图
    终端使用示例
    python3.9 /Users/odd/Documents/Project/测试国际化/TestPython/CCLocalizationAssetsTool.py
    
    配置使用:
    # 需要修改的
    change_head = "caaaimg_"
    # 旧的,若没有给空字符:""
    old_head = "cbbbimg_"
    # 资源路径
    #rootDir = "/Users/odd/Documents/Project/测试国际化/国际化图片资源"
    rootDir = "/Users/odd/Documents/Project/测试国际化/TestImageDemo/TestImageDemo"
    
    完整脚本:CCLocalizationAssetsTool.py
    #-*-coding:utf-8-*-
    import os , re
    import os.path
    import json
    
    
    '''
    文件夹示意图
    -----[demo]----[Assets.xcassets]-----[file]-----[xxx1.imageset]---xxx1.png
    ------------------------------------------------[xxx2.imageset]---xxx2.png
    ---------------[AssetsM.xcassets]----[fileM]----[yyy1.imageset]---yyy1.png
    '''
    
    
    # 需要修改的
    change_head = "caaaimg_"
    # 旧的,若没有给空字符:""
    old_head = "cbbbimg_"
    # 资源路径
    #rootDir = "/Users/odd/Documents/Project/测试国际化/国际化图片资源"
    rootDir = "/Users/odd/Documents/Project/测试国际化/TestImageDemo/TestImageDemo"
    
    # 统计含有大写字符图片名
    errorOldImageNameArray = []
    errorNewImageNameArray = []
    # 统计异常未修改资源名
    errorNOChangeImageNameArray = []
    # 统计.imageset资源里图片类型
    imageFileTypeArray = []
    
    def change_assets_name():
    
        print(" ======== 图集名称开始处理 ======== ")
        xcassetsArray = get_assets_dir_Array(rootDir)
        print("图片资源文件:\n",xcassetsArray)
        print("\n")
        
        # assets资源组
        for xassetsIndex,xassetsGroupName in enumerate(xcassetsArray):
        
            xassetsGroupPath = os.path.join(rootDir, xassetsGroupName)
            print("\n>>>>>>资源:【" + str(xassetsIndex) + "】 图片路径:\n" + xassetsGroupPath)
            
            categoryNameArray = get_sub_dir_files(xassetsGroupPath)
            print("当前分类集:\n",categoryNameArray)
            print("\n")
    
            for categoryName in categoryNameArray:
                pictureCategoryFilePath = os.path.join(xassetsGroupPath,categoryName)
                imagesetArray = get_sub_dir_files(pictureCategoryFilePath)
                
                # 将图片名称统一改成对应的文件名称一致
                for imagesetFileName in imagesetArray:
                    
                    # xxxx.imageset的图片资源名可能有大小写,就不强制处理了,不然要改使用的地方
                    imagesetName = imagesetFileName.replace(".imageset","")
                    #print("\n图片文件夹名:" + imagesetName)
    
                    # 需要改的图片集合文件名
                    if imagesetName.startswith(change_head):
                        changeImagetName = imagesetName
                        #print(".imageset文件夹名 不需要调整:" + imagesetName)
                    else:
                        # 先替换旧的前缀,在添加新的前缀
                        if old_head != "" and imagesetName.startswith(old_head):
                            changeImagetName = change_head + imagesetName.replace(old_head,"")
                        else:
                            changeImagetName = change_head + imagesetName
                        #print(".imageset文件夹名 需要调整为:" + changeImagetName)
                        
                    imagesetFilePath = os.path.join(pictureCategoryFilePath, imagesetFileName)
                    
                    # 统计含有大写的图片命名
                    if has_upper_char(changeImagetName):
                        #print("图片调整有大写:" + changeImagetName)
                        errorOldImageNameArray.append(imagesetName)
                        errorNewImageNameArray.append(changeImagetName)
                        
                    # 获取.imageset文件夹里:图片名 + Contents.json
                    picturesNames = os.listdir(imagesetFilePath)
                    
                    # 1、先修最底层的:图片名 + Contents.json
                    handle_pictures_imageset_sel(imagesetFilePath,picturesNames,changeImagetName)
                    
                    # 2、修改当前的.imageset文件名
                    if not(imagesetName.startswith(change_head)):
                        changeImagesetFileName = changeImagetName + ".imageset"
                        change_imageset_file_name_sel(pictureCategoryFilePath,imagesetFileName,changeImagesetFileName)
               
                # 3、修改一级图片分类名,APPIcon不需要调整
                if categoryName.startswith(change_head) or categoryName.startswith("AppIcon"):
                    tttt=""
                    #print("分类 不用调整: " + categoryName)
                else:
                    changeCategoryFileName = change_head + categoryName
                    
                    # 已经包含前缀的,去掉前缀,重新拼接
                    if old_head != "" and categoryName.startswith(old_head):
                        changeCategoryFileName = change_head + categoryName.replace(old_head,"")
                    
                    # 文件名统一小写处理
                    changeCategoryFileName = changeCategoryFileName.lower()
                    print("分类 调整为: " + changeCategoryFileName)
                    change_category_file_name_sel(xassetsGroupPath,categoryName,changeCategoryFileName)
                
        # 4、统计异常文件
        write_error_image_name_sel()
    
    
    # ==================== 文件夹名修改:分类,imageset ================= #
    
    def change_category_file_name_sel(dirPath,sourceName,changeName):
    
        sourceNamePath = os.path.join(dirPath,sourceName)
        changeNamePath = os.path.join(dirPath,changeName)
        os.rename(sourceNamePath,changeNamePath)
        print("category文件夹修改结果:" + sourceName + " : " + changeName)
                    
    def change_imageset_file_name_sel(dirPath,sourceName,changeName):
    
        sourceNamePath = os.path.join(dirPath,sourceName)
        changeNamePath = os.path.join(dirPath,changeName)
        os.rename(sourceNamePath,changeNamePath)
        print(".imageset文件夹修改结果:" + sourceName + " : " + changeName)
    
    
    
    # ==================== 图片名 + .json修改 ================= #
    
                
    
    # .imageset图片文件夹处理
    def handle_pictures_imageset_sel(dirPath,picturesNames,fileName):
    
        #print("\n图片资源改名处理:\n",picturesNames)
        
        for pictureName in picturesNames:
            
            #资源图片里文件类型
            filteType = ""
            if pictureName.find(".") != -1:
                tempList = pictureName.split(".")
                filteType = tempList[-1]
                # 不包含时,加入
                if not(filteType in imageFileTypeArray):
                    imageFileTypeArray.append(filteType)
        
            if filteType != "" and filteType != "json":
                change_picture_name_sel(dirPath,pictureName,fileName)
               
            elif pictureName.endswith(".json"):
                sourceName = os.path.join(dirPath,pictureName)
                jsonDict = get_json_data_sel(sourceName)
                write_json_data_sel(sourceName,jsonDict,fileName)
    
    
    # 修改图片名为:前缀+图片文件夹名
    def change_picture_name_sel(dirPath,sourceName,changeName):
    
        # 前缀判断
        if sourceName.startswith(changeName):
            #print("不需要处理: " + sourceName)
            return
        
        suffixStr = ""
        # 因为有些图片命名错误@2X, X大写
        lowerSourceName = sourceName.lower()
        if lowerSourceName.endswith("@3x.png"):
            suffixStr = "@3x.png"
        elif lowerSourceName.endswith("@2x.png"):
            suffixStr = "@2x.png"
        elif lowerSourceName.endswith(".png"):
            suffixStr = ".png"
        elif lowerSourceName.endswith(".pdf"):
            suffixStr = ".pdf"
        elif lowerSourceName.find(".") != -1:
            print("\n\n异常图片>>>>>>>>>:" + sourceName + "\n\n")
            # 逗号分割,取后缀(如xx.jpg.xx.gif)
            tempValueList = sourceName.split(".")
            suffixStr = "." + tempValueList[-1]
            errorOldImageNameArray.append(sourceName)
            errorNewImageNameArray.append(changeName + suffixStr)
        else:
            #错误资源可以统计到一个文档里
            print("\n\n异常图片>>>>>>>>>:" + sourceName + "\n\n")
            errorNOChangeImageNameArray.append(sourceName)
            return
        
        sourceNamePath = os.path.join(dirPath,sourceName)
        changeNamePath = os.path.join(dirPath,changeName + suffixStr)
        os.rename(sourceNamePath,changeNamePath)
        print("修改结果:" + sourceName + " : " + changeName + suffixStr)
    
        print("\n md5 \n")
        oldMd5 = get_file_md5(changeNamePath)
        change_file_md5(changeNamePath)
        newMd5 = get_file_md5(changeNamePath)
        print(oldMd5 + ":-->:" + newMd5)
        print("\n \n")
    
    
    # json读取
    def get_json_data_sel(path):
        # 获取json里面数据
        dict = {}
        with open(path, 'rb') as f:
            # 定义为只读模型,并定义名称为f
            params = json.load(f)
            #print("\njson内容:\n", params)
            # 打印
            dict = params
     
        f.close()
        # 关闭json读模式
        return dict
    
    # png、jpg、pdf、gif
    #{'images': [{'idiom': 'universal', 'scale': '1x'}, {'filename': 'BannerPlaceholder@2x.png', 'idiom': 'universal', 'scale': '2x'}, {'filename': 'BannerPlaceholder@3x.png', 'idiom': 'universal', 'scale': '3x'}], 'info': {'author': 'xcode', 'version': 1}}
    #{'images': [{'filename': 'testbanner.jpg', 'idiom': 'universal', 'scale': '1x'}, {'idiom': 'universal', 'scale': '2x'}, {'idiom': 'universal', 'scale': '3x'}], 'info': {'author': 'xcode', 'version': 1}}
    #{'images': [{'filename': 'oostlimg_placeholder_pdf.pdf', 'idiom': 'universal'}], 'info': {'author': 'xcode', 'version': 1}}
    #{'data': [{'filename': 'timing.gif', 'idiom': 'universal'}], 'info': {'author': 'xcode', 'version': 1}}
    
    # 写入json文件
    def write_json_data_sel(path,dict,pictureName):
    
        #print("\n开始处理json: " + pictureName)
        #print(dict)
        imagesArray = dict.get("images", [])
        # 不是png图片的
        if "data" in dict.keys():
            imagesArray = dict.get("data", [])
        
        for imageDic in imagesArray:
    
            scale = imageDic.get("scale", "")
            idiom = imageDic.get("idiom", "")
            filename = imageDic.get("filename", "")
            #print("json: " + scale + " filename: " + filename + " idiom: " + idiom)
    
            if scale != "" and filename.endswith(".png"):
                if scale.find("1x") != -1:
                    imageDic["filename"] = pictureName + ".png"
                else:
                    imageDic["filename"] = pictureName + "@" + scale + ".png"
            elif filename != "" and filename.find(".") != -1:
                filenameCompents = filename.split(".")
                # 取最后后缀
                suffixStr = filenameCompents[-1]
                imageDic["filename"] = pictureName + "." + suffixStr
    
    #    print("json处理结果:",dict)
    #
        with open(path, 'w') as r:
            json.dump(dict, r)
        r.close()
        # 关闭json写模式
        #print("==== 图片资源json处理完成 =====")
     
    # ====================  ================= #
    
    # 目录是否存在
    def is_dir_path(path):
        if path == '':
            print("\n异常>>>>> 不是文件目录路径:" + path)
            return False
        
        if not os.path.exists(path):
            print("\n异常>>>>>不存在目录,不创建目录:" + path)
            #os.makedirs(dirs)
            return False
        return True
        
    # 获取xcassets图片资源文件夹名
    def get_assets_dir_Array(filePath):
        results = []
        if not(is_dir_path(filePath)):
            return results
            
        # 获取文件夹里子文件夹名
        pathDirNames = os.listdir(filePath)
        for dirName in pathDirNames:
            if dirName.endswith(".xcassets"):
                results.append(dirName)
        
        return results
        
    # 获取目录子文件夹名
    def get_sub_dir_files(filePath):
        results = []
        if not(is_dir_path(filePath)):
            return results
        
        # 获取文件夹里子文件夹名
        for root, dirs, files in os.walk(filePath):
            #print(root) #当前目录路径
            #print(dirs) #当前路径下所有子目录
            #print(files) #当前路径下所有非目录子文件
            #print("\n")
            return dirs
    
        return results
        
    #def change_picture_imageset_name(filePath,nameHead):
    #    for dirName,subDir, fileNames in os.walk(filePath):
    #        print("imageset: " + dirName + " " + subDir + " ")
    #        for fileName in fileNames:
    #            print("fileName: " + fileName)
                
    # 是否有大写字符
    def has_upper_char(name):
        upper = any(cstr.isupper() for cstr in name)
        return upper
    
    
    # 写异常数据到txt文件
    def write_error_image_name_sel():
    
        resultsError = []
        resultsError.append("====== 图片资源处文件数据类型:=====")
        resultsError.append("\n")
        if isinstance(imageFileTypeArray,list) and len(imageFileTypeArray):
            resultsError.extend(imageFileTypeArray)
        
        resultsError.append("\n")
        resultsError.append("====== 旧图片名 异常:=====")
        resultsError.append("\n")
        if isinstance(errorOldImageNameArray,list) and len(errorOldImageNameArray):
            resultsError.extend(errorOldImageNameArray)
        
        resultsError.append("\n")
        resultsError.append("====== 新图片名 异常:=====")
        resultsError.append("\n")
    
        if len(errorNewImageNameArray):
            resultsError.extend(errorNewImageNameArray)
            
        resultsError.append("\n")
        resultsError.append("====== 未改文件名 异常:=====")
        resultsError.append("\n")
        if len(errorNOChangeImageNameArray):
            resultsError.extend(errorNOChangeImageNameArray)
        
        # 清空txt文件内容(方式一)
        clearfile = open(rootDir+"/errorName.txt", 'w').close()
        
        if len(imageFileTypeArray) or len(errorOldImageNameArray) or len(errorNewImageNameArray) or len(errorNOChangeImageNameArray):
            
            errorTextpath = rootDir+"/errorName.txt"
            sqlWriteFile = open(errorTextpath,"a+")
            #写入对应行+换行
            sqlWriteFile.writelines([tempName+"\r" for tempName in resultsError])
            sqlWriteFile.close()
            #print(resultsError)
            print("\n>>>>>> 异常数据txt文件路径:\n",errorTextpath)
            print("\n\n")
            return
            
        print("\n>>>>>>无异常数据")
    
    
    # 获取MD5
    def get_file_md5(filename):
        if not os.path.isfile(filename):
            return
        myhash = hashlib.md5()
        f = open(filename,'rb')
        while True:
            b = f.read(8096)
            if not b :
                break
            myhash.update(b)
        f.close()
        return myhash.hexdigest()
        
    # 给文件添加末尾,改变md5
    def change_file_md5(filename):
        myfile = open(filename,'a')
        #添加一个自定义内容,并不影响文件
        myfile.write("ab")
        myfile.close
        
    change_assets_name()
    

    相关文章

      网友评论

        本文标题:iOS【图片国际化处理】python脚本Assets.xcass

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