So I've been slowly learning the ways of the "snake" and trying to create THE script that will remove all duplicate images after one has appended, shall we say, an entire library of characters, buildings, vehicles, etc.
I have seen the topics of going into the Outliner and remapping the duplicates, but imagine having hundreds of these one needs to Box-Select, then try to find the beginning of this list of
eyemask.png.xxx. I have also seen scripts where one would match the name and remap to the name without the extra numbers. However, things get a little complicated when one's library of objects have the same named texture file (like
body.png.xxx) but have their differences. And maybe the names got changed somehow so the first part doesn't quite match, yet they are exactly the same image (ever found duplicate textures in a game?).
I figured, why not remap the images to the first match Per Pixel? Yeah, that is definitely a lengthy process if the image is 4K... I have gone about the iteration in two ways:
# Purely based on if the images are sorted alphabetally and follow the .xxx pattern import bpy lastimg = False lastpix =  curpix =  imgcnt = 0 for img in bpy.data.images: curimg = img curpix = curimg.pixels thesame = True if len(curpix) > 0 and len(lastpix) > 0 and len(curpix) == len(lastpix): for i in range(len(curpix)): if i % (len(curpix) / 4096) < 1: print(imgcnt,"/",len(bpy.data.images),"-",curimg.name,"-",((i/len(curpix)*100)),"%") if curpix[i] != lastpix[i]: thesame = False break else: thesame = False if thesame == True: curimg.user_remap(lastimg) else: lastimg = curimg lastpix = lastimg.pixels imgcnt = imgcnt + 1 print("DONE!")
# Double the iteration, making sure there are no other named textures that look the same import bpy imgcnt = 0 for img1 in bpy.data.images: for img2 in bpy.data.images: if img1.users > 0 and img2.users > 0 and img1.name != img2.name pix1 = img1.pixels pix2 = img2.pixels thesame = True if len(pix1) > 0 and len(pix2) > 0 and len(pix1) == len(pix2): for i in range(len(pix1)): if i % (len(pix1) / 4096) < 1: print(imgcnt,"/",len(bpy.data.images),"-",img2.name,"-",((i/len(curpix)*100)),"%") if pix1[i] != pix2[i]: thesame = False break else: thesame = False if thesame == True: img2.user_remap(img1) imgcnt = imgcnt + 1 print("DONE!")
I have also attempted to
hashlib the array of pixels to see if it is any quicker, but I keep getting errors. I have also attempted to convert the array of pixels to a string, but that seems just as slow. Who knew python couldn't handle 67MB in one second? :P
Is there any quicker way you guys could suggest to compare two images? Thinking that further down the line I could do the same for the materials (compare the nodes and their values and reduce duplicates).