Home Technical Talk

[Css] - Layergroups to Spritesheet?

polycounter lvl 11
Offline / Send Message
Alphavader polycounter lvl 11
//edit: didnt mention that, but the sprite sheet is for animations,
so the images have to go from left to right - top-down



Hey all,

iam just wondering how a good spritesheet workflow would be.
My curently workflow is
1. Render Animation
2. Put all in one Css file on top of each other and Crop
3. Save them out via script
4. Make a Spritesheet out of it.

I think this could be improved, a little tool "unchaos" helped me
alot - but i think it could be possible, to build a spritesheet out of the photoshop file.

There a few scricts out there, but they dont support layer groups, only layers.. so if i have different animations in groups, i cant put them into one sheet.
Has someone a good code, or a hint for me ?

Thanks

Btw. here the code, i googled :
// Put this file in Program Files\Adobe\Photoshop\Presets\Scripts\layersToSprite.js
    // Run in PhotoShop: File > Scripts > Browse: locate layersToSprite.js and run
 
    // Arrange layers into a sprite sheet. (Vertical)
 
    if (documents.length > 0)
    {
        var cols = 1;
 
        // --------------------------
        docRef = activeDocument;
        var activeLayer = docRef.activeLayer;
 
        numLayers = docRef.artLayers.length;
 
        var rows = Math.ceil(numLayers/cols);
 
         var spriteX = docRef.width;
         var spriteY = docRef.height;
 
        // put things in order
        app.preferences.rulerUnits = Units.PIXELS;
 
        // resize the canvas
         newX = spriteX * cols;
         newY = spriteY * rows;
 
         docRef.resizeCanvas( newX, newY, AnchorPosition.TOPLEFT );
 
        // move the layers around
         var rowi = 0;
         var coli = 0;
 
         for (i=(numLayers - 1); i >= 0; i--)
         {
             docRef.artLayers[i].visible = 1;
 
              var movX = spriteX*coli;
              var movY = spriteY*rowi;
 
             docRef.artLayers[i].translate(movX, movY);
 
             coli++;
             if (coli > (cols - 1))
             {
                 rowi++;
                 coli = 0;
             }
         }
    }
//$.writeln("log.txt");

Doesnt support layer groups..

Replies

  • monster
    Options
    Offline / Send Message
    monster polycounter
    Maybe you can skip photoshop altogether and use a tool like Shoebox?
    http://renderhjs.net/shoebox/

    But in case you can't I modified your script. Select a layer group, then run the script. It will create a new document, and modify that one. I find this better than modifying the original. You should keep the original version in case you have a file that doesn't have groups.
    // Put this file in Program Files\Adobe\Photoshop\Presets\Scripts\layerGroupToSprite.js
        // Run in PhotoShop: File > Scripts > Browse: locate layersToSprite.js and run
     
        // Arrange layers into a sprite sheet. (Vertical)
     
        if (documents.length > 0)
        {
            var cols = 1;
     
            // --------------------------
            docRef = activeDocument;
            var activeLayer = docRef.activeLayer;
            
           if(activeLayer.typename=="LayerSet")
           {
               
                //CREATE A TEMP DOCUMENT THAT IS THE SAME SIZE AS THE CURRENT DOCUEMENT
                var newDoc = documents.add( docRef.width, docRef.height, docRef.resolution, activeLayer.name, NewDocumentMode.RGB, DocumentFill.TRANSPARENT, docRef.pixelAspectRatio,  BitsPerChannelType.EIGHT );
                
               
                //SWITCH TO ORIGINAL IMAGE TO DUPE THE LAYER TO THE TEMP DOCUMENT
                app.activeDocument = docRef;
                docRef.activeLayer.duplicate(newDoc,ElementPlacement.PLACEATBEGINNING);
            
                //SWITCH BACK TO THE NEW DOCUMENT
                app.activeDocument = newDoc;    
    
                //REMOVE THE LAYER THAT WAS CREATED WITH THE DOCUMENT
                newDoc.artLayers[0].remove()
                
                //GET THE GROUP COUNT
                var numLayers = newDoc.activeLayer.artLayers.length;
         
                var rows = Math.ceil(numLayers/cols);
         
                 var spriteX = newDoc.width;
                 var spriteY = newDoc.height;
         
                // put things in order
                app.preferences.rulerUnits = Units.PIXELS;
         
                // resize the canvas
                 newX = spriteX * cols;
                 newY = spriteY * rows;
         
                 newDoc.resizeCanvas( newX, newY, AnchorPosition.TOPLEFT );
         
                // move the layers around
                 var rowi = 0;
                 var coli = 0;
         
                 for (i=(numLayers - 1); i >= 0; i--)
                 {
                     newDoc.activeLayer.artLayers[i].visible = 1;
         
                      var movX = spriteX*coli;
                      var movY = spriteY*rowi;
         
                     newDoc.activeLayer.artLayers[i].translate(movX, movY);
         
                     coli++;
                     if (coli > (cols - 1))
                     {
                         rowi++;
                         coli = 0;
                     }
                 }
             }
        }
    
  • Alphavader
    Options
    Offline / Send Message
    Alphavader polycounter lvl 11
    Thanks monster, you helped me alot.
    Shoebox is a nice tool, ill try it out.
    - maybe the solution for me, but i have to do a few tests - thanks ;)

    The code is nice - can you do a few changes for me ?
    0. do the changes in the same document, with all groups selected ? ;)
    1. Move all layers in the group horizontal
    2. the next group under the first one (horizontal)
    3. and so on..
    4. Is it possible,that the script is able to manage
    the image size for it self ?
    (no padding, all images horizontal, groups under groups ? )



    Greetz
  • renderhjs
    Options
    Offline / Send Message
    renderhjs sublime tool
    Hi Alphavader
    Yes there is already such a functionality in Shoebox its within the "Ani 2 sheet" tool
    icon_aniSheet.png

    here is an example of a sequence of sprites, with and without the crop alpha groups setting. There is also a setup for multi rows and columns have a look at at that setting as well as it will try to make the end result a bit more square like.

    8029266274_562d2570de_o.jpg

    More info on this tool can be found here
    http://renderhjs.net/shoebox/aniSheet.htm
  • LoTekK
    Options
    Offline / Send Message
    LoTekK polycounter lvl 17
    ShoeBox is definitely the way to go, though if for some reason you'd still prefer a Photoshop script:
    #target photoshop
    app.bringToFront();
    
    if(app.documents.length > 0)
    {
    	var sourceDoc = app.activeDocument;
    	var oldUnits = app.preferences.rulerUnits;
    	app.preferences.rulerUnits = Units.PIXELS;
    	if(sourceDoc.layerSets.length > 0)
    	{
    		var spriteX = sourceDoc.width;
    		var spriteY = sourceDoc.height;
    		var rows = sourceDoc.layerSets.length;
    		var cols = 0;
    		for(i = 0; i < rows; i++)
    		{
    			var count = sourceDoc.layerSets[i].artLayers.length;
    			if(count > cols)
    			{
    				cols = count;
    			}
    		}
    		var spriteSheetName = "SpriteSheet_" + parseInt(spriteX * cols) + "x" + parseInt(spriteY * rows);
    		var spriteSheet = app.documents.add(spriteX * cols, spriteY * rows, sourceDoc.resolution, spriteSheetName);
    		app.activeDocument = sourceDoc;
    		for(i = 0; i < rows; i++)
    		{
    			sourceDoc.layerSets[i].duplicate(spriteSheet, ElementPlacement.PLACEATEND);
    		}
    		app.activeDocument = spriteSheet;
    		spriteSheet.artLayers[0].remove();
    		for(i = 0; i < rows; i++)
    		{
    			spriteSheet.layerSets[i].translate(0, i * spriteY);
    			for(j = 0; j < spriteSheet.layerSets[i].artLayers.length; j++)
    			{
    				spriteSheet.layerSets[i].artLayers[j].translate(j * spriteX, 0);
    			}
    		}
    		spriteSheet.mergeVisibleLayers();
    		spriteSheet.artLayers[0].name = spriteSheet.name;
    	}
    	else
    	{
    		alert("No layersets found!", "ERROR");
    	}
    	app.preferences.rulerUnits = oldUnits;
    }
    else
    {
    	alert("This script requires an open document!", "ERROR");
    }
    
  • Alphavader
    Options
    Offline / Send Message
    Alphavader polycounter lvl 11
    Ah thanks renderhjs,
    i still have some issues with the row thing, is
    it possible to put more then 4 uncropped image in a line ?
    (multi row ) ?
    row.png


    @ LoTekK: Yes - the script is what iam looking for.. thank you so much, dude!
    You didnt know how much this improves my workflow ! ;)


    But iam still inerested in a ShoeBox solution ;) too - cause its a mighty tool..
  • renderhjs
    Options
    Offline / Send Message
    renderhjs sublime tool
    @Alphavader
    To be honest frame sheets are very plain and personally I don't really use them. If you can I would recommend using a real sprite sheet as in a sheet where all the sprites are packed in their most memory efficient way.

    Not sure if you knew this already, but ShoeBox has also an CSS export option inside the Pack Sprites tool. Just open the settings and choose CSS sprites. The sprite packer has also an crop option if you want to keep your images cropped- maybe give it a shot.

    more here:
    http://renderhjs.net/shoebox/packSprites.htm

    example_packCss.jpg
  • Alphavader
    Options
    Offline / Send Message
    Alphavader polycounter lvl 11
    @ renderhjs
    in our engine, unfortunately every image has to have the same size ;(
    But thanks with the CSS Export, nice to know - ill try it out for another projekt
  • renderhjs
    Options
    Offline / Send Message
    renderhjs sublime tool
    XnView has a contact sheet tool, might be what you want
    8029933839_f938d7aef9_o.jpg

    its the most bare bone thing I can think of, you need to do some math though to make it all go in the right amount of columns and rows.

    http://www.xnview.com/wiki/index.php/Contact_Sheet

    edit: I don't think that it does PNG 8bit-alphas nice
  • Alphavader
    Options
    Offline / Send Message
    Alphavader polycounter lvl 11
    Thanks ill give it a try - but the script from LoTekK
    is working very well
    so thank you guys ;)

    Dragon_ani%5Bmeskarts.com%5D.gif
Sign In or Register to comment.