#!BPY """ Released under the Blender Artistic Licence (BAL) Name: 'AnimTex Assembler' Blender: 240 Group: 'Misc' Tooltip: 'Converts a series of images to a single one to be used as a tiled texture.' """ __author__ = "pat" __version__ = "1.2 - 20060122 -" __email__ = ('Author, pat:psycho3d*de') __url__ = ("Author's website, www.psycho3d.de") __bpydoc__ ="""\ This script reads a series of images and creates one single output image you can use as a tiled texture, e.g. in the Blender Game Engine. Set 'Tiles X' and 'Tiles Y' to the number of tiles you want. Set 'Source' to the name of the first image in the sequence, the others will be loaded automatically. You will be notified if there's a gap in the sequence of numbers and the script cannot continue. """ ### changelog ### # 20060103 v1: release # 20060104 v1.1: improved foolproofness :) # now it' hard to do anything wrong: # -all you have to do is set the number of tiles and the name of the first image in sequence # -images are searched automatically (numbering and extension) # -size is set automatically # 20060122 v1.2: 'bug'fix # Image.save() always saves targa, so I check the filename and change the extension if it's not tga #import Blender from Blender import Image as I, BGL as gl, Window, sys from Blender.Draw import Create, Button, Number, String, Text, Register, Exit, Redraw, PupMenu ### gui defines ### partsX = Create(3) partsY = Create(2) destName = Create("assembledImage.tga") sourceName = Create("") msg = "" def pad(x, p): return (p - len(str(x))) * "0" + str(x) def assemble(): global msg msg = "Error" #analyse source image name pathname, ext = sys.splitext(sourceName.val) p = 1 while pathname[-p:].isdigit(): print pathname[-p:] p += 1 p -= 1 if p==0: print "\nNo numbering found in the source image name.\nTry to rename your images to something like 'image01.tga' or 'img_0003.png'." return imgCounter = int(pathname[-p:]) #number of the first image to load pathname = pathname[:-p] # loop all pics curY = 0 while curY < partsY.val: curX = 0 while curX < partsX.val: try: simg = I.Load("%s%s%s" % (pathname, pad(imgCounter, p), ext)) except IOError: print "\nAn error occured while trying to load '%s'." % ("%s%s%s" % (pathname, pad(imgCounter, p), ext)) print "Try to reduce the number of tiles or check if there is a gap in the number sequence." return imgCounter += 1 if curX == curY == 0: #first image loaded, now i can create the result img = I.New("assembled", simg.size[0] * partsX.val, simg.size[1] * partsY.val, 32) # loop all pixels x = 0 startX = curX * simg.size[0] # set startpos X while x < simg.size[0]: y = 0 startY = curY * simg.size[1] # set startpos Y while y < simg.size[1]: img.setPixelI(x + startX, y + startY, simg.getPixelI(x, y)) # alpha should be preserved y += 1 x += 1 #next one, please :) curX += 1 curY += 1 curX = 0 if (destName.val != ""): img.setFilename(destName.val) else: img.setFilename("assembledImage.tga") img.save() msg = "Success" def draw(): global partsX, partsY, destName, sourceName, msg col = Window.Theme.Get()[0].get("buts").back gl.glClearColor(col[0]/255., col[1]/255., col[2]/255., col[3]/255.) gl.glClear(gl.GL_COLOR_BUFFER_BIT) col = Window.Theme.Get()[0].get("buts").text_hi gl.glColor3f(col[0]/255., col[1]/255., col[2]/255.) partsX = Number("Tiles X: ", 0, 20, 150, 80, 20, partsX.val, 1, 256, "Number of tiles in x-direction.") partsY = Number("Tiles Y: ", 0, 120, 150, 80, 20, partsY.val, 1, 256, "Number of tiles in y-direction.") destName = String("Filename: ", 0, 20, 110, 180, 20, destName.val, 255, "Filename of the assembled image.") sourceName = String("Source: ", 0, 20, 80, 180, 20, sourceName.val, 255, "Prefix of the source images.") Button("FS", 3,210,110,20,20,"Show fileselector for Filename.") Button("FS", 4,210,80,20,20,"Show fileselector for Source.") Button ("Exit", 1, 20, 40, 80, 20) Button ("Assemble", 2, 120, 40, 80, 20) gl.glRasterPos2f(20, 23) Text(msg) def event(evt,val): pass def callbackD(filename): global destName f = sys.splitext(filename) if t[1] != ".tga": filename = f[0] + ".tga" destName.val=filename def callbackS(filename): global sourceName sourceName.val=filename def bevent(evt): if evt==1: Exit() elif evt==2: assemble() elif evt==3: Window.FileSelector(callbackD) elif evt==4: Window.FileSelector(callbackS) Redraw() Register(draw, event, bevent)