python PIL库实践运用,对图像进行切碎片操作。
原图如图一
图一
我们想要的是图片的不同部分,比如图二中1、2、3、4每一个分区单独的碎片,
图二
做法是做出4张跟原图大小一样的碎片模版图,白底,想要的区域涂黑(非纯白)即可。1区域的碎片模板图如图三所示:
图三
脚本处理图片的方法:先找出碎片模版中的非白区域(可以不规则),然后将原图中这个区域内的所有像素点的颜色都放到新的一张跟原图像素大小一样的新图上,新图的其余位置都设置成透明(可以根据自己的不同需求进行不同的调整)。 1碎片模版得到的新图碎片如图四所示:
图四
附上处理脚本
1 # -*- coding=utf-8 -*- 2 from PIL import Image 3 import os 4 import shutil 5 6 SUFIX_PNG = "png" 7 SUFIX_JPEG = "jpeg" 8 SUFIX_LIST = [SUFIX_PNG, SUFIX_JPEG] 9 NEED_RESIZE_TAG = True 10 SMALL_SIZE = (126,126) 11 12 13 def isWhite(color): 14 r, g, b = color[0], color[1], color[2] 15 if r == 255 and g == 255 and b==255: 16 return True 17 return False 18 19 def getImgFileList(folderPath): 20 modelFileNames = [] 21 for dirpath, dirnames, filenames in os.walk(folderPath): 22 for filename in filenames: 23 sufix = os.path.splitext(filename)[1][1:] 24 if sufix in SUFIX_LIST: 25 modelFileNames.append(filename) 26 modelFileNames.sort() 27 return modelFileNames 28 29 def getFileName(fileFullName): 30 return fileFullName[:fileFullName.rindex(".")] 31 32 def checkImgSize(sizeDict, widthSum, heightSum, imgCnt): 33 # imgCnt = len(sizeDict.keys()) 34 averWidth, averHeight = widthSum/imgCnt, heightSum/imgCnt 35 for sizeKey, sizeValue in sizeDict.items(): 36 if sizeValue[‘width‘] != averWidth: 37 print "[ERROE],{IMG} width is wrong! please check it again!".format(IMG=sizeKey) 38 return False 39 if sizeValue[‘height‘] != averHeight: 40 print "[ERROE, ]{IMG} height is wrong!please check it again!".format(IMG=sizeKey) 41 return False 42 return True 43 44 45 def test(): 46 folderPath = ‘./model/‘ 47 srcPath = ‘./src/‘ 48 srcBackupPath = ‘./srcBackup/‘ 49 targetPath = ‘./done/‘ 50 currPath = ‘.‘ 51 # check model &src folder 52 if not os.path.exists(folderPath) or not os.path.exists(srcPath): 53 print ‘[ERROR], dir [model] or [src] does not exist‘ 54 return 55 56 # creat the target folder 57 if not os.path.exists(targetPath): 58 os.mkdir(targetPath) 59 60 partImgNames = getImgFileList(folderPath) 61 srcImgNames = getImgFileList(srcPath) 62 63 partDict = {} 64 srcDict = {} 65 sizeDict = {} 66 imgCnt = 0 67 widthSum, heightSum = 0, 0 68 69 # change src img file sufix 把之前的png原图改成jpeg格式 70 # 需不需要改格式 71 # for _, srcImgName in enumerate(srcImgNames): 72 # if srcImgName.endswith(SUFIX_PNG): 73 # im = Image.open(srcPath+srcImgName) 74 # bg = Image.new("RGB", im.size, (255,255,255)) 75 # newSrcImgName = srcImgName.replace(SUFIX_PNG, SUFIX_JPEG) 76 # bg.paste(im, im) 77 # bg.save(srcPath+newSrcImgName) 78 # if os.path.exists(srcPath+srcImgName): 79 # if not os.path.exists(srcBackupPath): 80 # os.mkdir(srcBackupPath) 81 # shutil.move(srcPath+srcImgName, srcBackupPath) 82 83 srcImgNames = getImgFileList(srcPath) 84 for index, partImgName in enumerate(partImgNames): 85 partDict[index] = Image.open(folderPath+partImgName) 86 width, height = partDict[index].size 87 sizeDict[partImgName] = {} 88 sizeDict[partImgName][‘width‘] = width 89 sizeDict[partImgName][‘height‘] = height 90 widthSum += width 91 heightSum += height 92 imgCnt += 1 93 94 for index, srcImgName in enumerate(srcImgNames): 95 srcDict[index] = Image.open(srcPath+srcImgName) 96 width, height = srcDict[index].size 97 sizeDict[srcImgName] = {} 98 sizeDict[srcImgName][‘width‘] = width 99 sizeDict[srcImgName][‘height‘] = height 100 widthSum += width 101 heightSum += height 102 imgCnt += 1 103 104 # img size check, 检查图片尺寸 105 if not checkImgSize(sizeDict, widthSum, heightSum, imgCnt): 106 return 107 108 for srcIndex, srcImgName in enumerate(srcImgNames): 109 tempSrcImg = srcDict[srcIndex].copy() 110 colorDataSrc1 = tempSrcImg.getdata() 111 112 for modelIndex, partImgName in enumerate(partImgNames): 113 tempImg = partDict[modelIndex].copy() # copy img , 复制图片 114 colorData2 = tempImg.getdata() 115 colorStore = [] # to save colors 116 for index, color2 in enumerate (colorData2): 117 if not isWhite(color2): 118 colorStore.append(colorDataSrc1[index]) 119 else: 120 colorStore.append((0,0,0,0)) 121 122 tempImg.putdata(colorStore) 123 # make target files names 124 newFileName = "{TARGET}{NAME}-{INDEX}.{SUFIX}".format( 125 TARGET=targetPath, 126 NAME=getFileName(srcImgName), 127 INDEX=modelIndex+1, 128 SUFIX=SUFIX_PNG) 129 tempImg.save(newFileName, SUFIX_PNG) 130 131 if NEED_RESIZE_TAG: 132 smallTargetPath = ‘./smalldone/‘ 133 if not os.path.exists(smallTargetPath): 134 os.mkdir(smallTargetPath) 135 smallImg = tempImg.resize(SMALL_SIZE) 136 newFileName = "{TARGET}{NAME}-{INDEX}.{SUFIX}".format( 137 TARGET=smallTargetPath, 138 NAME=getFileName(srcImgName), 139 INDEX=modelIndex+1, 140 SUFIX=SUFIX_PNG) 141 smallImg.save(newFileName, SUFIX_PNG) 142 print ‘------create {NAME} done-----‘.format(NAME=newFileName) 143 print ‘>>>>>>>>>>>>>>>>>Job Done<<<<<<<<<<<<<<<<‘ 144 145 146 if __name__ == "__main__": 147 test()
目录组织结构如图五所示:
图五
最终done文件夹的结果如图六所示:
图六
Note:
- 原图放在src文件夹下,原图可以有很多张,脚本对图片的宽高尺寸有检查,如果批量处理的话,尺寸必须保持一致,不然的话需要注掉尺寸检查的代码。
- 碎片模版图放在model文件夹下,所有碎片模版的尺寸必须跟原图尺寸一致。
- 生成的碎片会存放到done文件夹里。
- 支持resize功能,将resize后的新碎片存到smalldone文件夹下。
时间: 2024-12-20 21:17:08