We can create an atlas with many images.
This way we don't have to load a lot of small images. An atlas image will have a text file indicating the names of the individual images and their positions and sizes.
In Python 2.7 Kivy, there is a file called atlas.py. It can be used to create atlas files. The reason it is version 2.7 and not Python 3 versions is because of an old library, PIL, which stands for Python Imaging Library. The Kivy developers are correcting this, for future versions, so it does not depend on PIL.
Assuming you have installed both Python 2.7 and also PIL, the slightly modified file atlas.py file can be used, and which is on blogspot. You can have different python versions installed in your system. When Python 2.7 is installed, it will be installed to C:\\Python27. During the PIL setup, make sure it indicates the correct directory.
# atlas.py import os, json from os.path import basename, dirname, join, splitext import Image def create(outname, filenames, size, padding=2): if isinstance(size, (tuple, list)): size_w, size_h = map(int, size) else: size_w = size_h = int(size) # open all of the images ims = [(f, Image.open(f)) for f in filenames] # sort by image area ims = sorted(ims, key=lambda im: im[1].size[0] * im[1].size[1], reverse=True) # free boxes are empty space in our output image set # the freebox tuple format is: outidx, x, y, w, h freeboxes = [(0, 0, 0, size_w, size_h)] numoutimages = 1 # full boxes are areas where we have placed images in the atlas # the full box tuple format is: image, outidx, x, y, w, h, filename fullboxes = [] # do the actual atlasing by sticking the largest images we can # have into the smallest valid free boxes for imageinfo in ims: im = imageinfo[1] imw, imh = im.size imw += padding imh += padding if imw > size_w or imh > size_h: print( 'Atlas: image %s is larger than the atlas size!' % imageinfo[0]) return inserted = False while not inserted: for idx, fb in enumerate(freeboxes): # find the smallest free box that will contain this image if fb[3] >= imw and fb[4] >= imh: # we found a valid spot! Remove the current # freebox, and split the leftover space into (up to) # two new freeboxes del freeboxes[idx] if fb[3] > imw: freeboxes.append(( fb[0], fb[1] + imw, fb[2], fb[3] - imw, imh)) if fb[4] > imh: freeboxes.append(( fb[0], fb[1], fb[2] + imh, fb[3], fb[4] - imh)) # keep this sorted! freeboxes = sorted(freeboxes, key=lambda fb: fb[3] * fb[4]) fullboxes.append((im, fb[0], fb[1] + padding, fb[2] + padding, imw - padding, imh - padding, imageinfo[0])) inserted = True break if not inserted: # oh crap - there isn't room in any of our free # boxes, so we have to add a new output image freeboxes.append((numoutimages, 0, 0, size_w, size_h)) numoutimages += 1 # now that we've figured out where everything goes, make the output # images and blit the source images to the approriate locations print('Atlas: create an {0}x{1} rgba image'.format(size_w, size_h)) outimages = [Image.new('RGBA', (size_w, size_h)) for i in range(0, int(numoutimages))] for fb in fullboxes: x, y = fb[2], fb[3] out = outimages[fb[1]] out.paste(fb[0], (fb[2], fb[3])) w, h = fb[0].size if padding > 1: out.paste(fb[0].crop((0, 0, w, 1)), (x, y - 1)) out.paste(fb[0].crop((0, h - 1, w, h)), (x, y + h)) out.paste(fb[0].crop((0, 0, 1, h)), (x - 1, y)) out.paste(fb[0].crop((w - 1, 0, w, h)), (x + w, y)) # save the output images for idx, outimage in enumerate(outimages): outimage.save('%s-%d.png' % (outname, idx)) # write out an json file that says where everything ended up meta = {} for fb in fullboxes: fn = '%s-%d.png' % (basename(outname), fb[1]) if fn not in meta: d = meta[fn] = {} else: d = meta[fn] # fb[6] contain the filename # for example, '../data/tiles/green_grass.png' # just get only 'green_grass' as the uniq id. uid = splitext(basename(fb[6]))[0] x, y, w, h = fb[2:6] d[uid] = x, size_h - y - h, w, h outfn = '%s.atlas' % outname with open(outfn, 'w') as fd: json.dump(meta, fd) return outfn, meta
A file, create_atlas.py, uses the file atlas.py to create atlases. These are the imports. The __future__ import is only for the print statements. Beside atlas.py module, the sys and os modules are needed, for system and operating system functions.
We require 3 parameters, in this python program. The outname indicates the name, of the atlas file. The variable im_ext, indicates what kind of image files, we have. Finally the size, indicates the size, of the resulting image files. Here, you could also have put in 256, and that would be understood to be 256, 256.
In the list fils, we have the names of all the files in current directory. This will include both image and non-image files. Next in filenames, only the elements that are actually images, with correct extension, are retained.
The only function, in the modified atlas module, is create() and, which requires 3 parameters. The default padding, which is 2 pixels, between images was used.
Finally, there are printouts, indicating the name of the main atlas file, which is the text file in json format. It also indicates how many images are in the atlas. If the size is large enough, it should be only 1 file.
# create_atlas.py from __future__ import print_function import atlas import sys, os outname = 'abc' im_ext = '.png' size = 256, 256 fils = os.listdir(os.getcwd()) filenames = [fil for fil in fils if fil.endswith(im_ext)] ret = atlas.create(outname, filenames, size) if not ret: print('Error while creating atlas!') sys.exit(1) fn, meta = ret print('Atlas created at', fn) print('%d image%s created' % (len(meta), 's' if len(meta) > 1 else ''))
Here, we can see the text file, abc.atlas has been created, as well as the image file, abc-0.png. This image contains the original three images.
This shows a part of abc.atlas. First, we have the image filename, and then the images and bounding boxes. Note, this bounding box is 64 by 64, the size of the image.
Python:
ReplyDeleteGood Post! Thank you so much for sharing this pretty post, it was so good to read and useful to improve my knowledge as updated one, keep blogging.
https://www.emexotechnologies.com/online-courses/python-training-in-electronic-city/
Good Post! Thank you so much for sharing this pretty post, it was so good to read and useful to improve my knowledge as updated one, keep blogging.
ReplyDeletePython Training in electronic city
nice information for beginners.thank you.
ReplyDeletejavacodegeeks
welookups python
Quickbooks Multi user mode not working
ReplyDeleteQuickbooks Diagnostic tool
QuickBooks error code 15106
Quickbooks accounting software
QuickBooks Password Reset Tool