Skip to content

Instantly share code, notes, and snippets.

@agasiev
Created October 11, 2012 21:50
Show Gist options
  • Save agasiev/3875736 to your computer and use it in GitHub Desktop.
Save agasiev/3875736 to your computer and use it in GitHub Desktop.
libGdx atlas crop tool.
#import <Foundation/Foundation.h>
#import <iostream>
#import <string>
#import <list>
#import <fstream>
#import <tr1/unordered_map>
#import <Cocoa/Cocoa.h>
#import <AppKit/AppKit.h>
#import <vector>
// Add AppKit framevork to targets.
typedef struct {
int x, y;
} coord;
typedef struct {
bool rotate;
coord xy;
coord size;
coord orig;
coord offset;
int index;
} AtlasItem;
@interface AtlasLoader : NSObject {
std::string atlas_name;
std::string atlas_image_name;
std::tr1::unordered_map<std::string, AtlasItem> items;
}
- (std::vector<std::string>) getThemAll;
- (bool) LoadItems:(std::string)filename_;
- (std::string) getTextureName;
- (AtlasItem) getItemParams:(std::string)name;
- (bool) textureExists:(std::string)name;
- (int) to_int:(std::string)value;
- (std::string) trim:(std::string) value;
- (void) clearAll;
@end
@implementation AtlasLoader
- (std::vector<std::string>) getThemAll {
std::vector<std::string> result;
std::tr1::unordered_map<std::string, AtlasItem>::iterator it = items.begin();
for (; it != items.end(); it++) {
result.push_back(it->first);
}
return result;
}
- (void) clearAll {
items.clear();
}
- (bool) LoadItems:(std::string)filename_ {
atlas_name = filename_;
char buf[64];
std::ifstream in_file(atlas_name.c_str());
if (!in_file.is_open()) {
return false;
}
std::list<std::string> file_content;
while (in_file.getline(buf, sizeof(buf))) {
if (strlen(buf) > 0)
file_content.push_back(buf);
}
in_file.close();
atlas_image_name = file_content.front();
for (int i = 0; i < 4; i++)
file_content.pop_front();
std::list<std::string>::iterator it;
AtlasItem item;
std::string temp, item_name = "";
for (it = file_content.begin(); it != file_content.end(); it++) {
if ((*it).find(':') == std::string::npos) {
item_name = *it;
it++;
// xy
it++;
temp = [self trim:(*it).substr((*it).find(':')+1, (*it).length())];
item.xy.x = [self to_int:[self trim:temp.substr(0, temp.find(","))]];
item.xy.y = [self to_int:[self trim:temp.substr(temp.find(",")+1, temp.length())]];
// size
it++;
temp = [self trim:((*it).substr((*it).find(':')+1, (*it).length()))];
item.size.x = [self to_int:[self trim:temp.substr(0, temp.find(","))]];
item.size.y = [self to_int:[self trim:temp.substr(temp.find(",")+1, temp.length())]];
it++;
it++;
it++;
items[item_name] = item;
}
}
return true;
}
- (std::string) getTextureName {
return atlas_image_name;
}
- (AtlasItem) getItemParams:(std::string)name {
return items[name];
}
- (bool) textureExists:(std::string)name {
std::tr1::unordered_map<std::string, AtlasItem>::iterator it = items.find(name);
return (it != items.end());
}
- (int) to_int:(std::string)value {
int result = 0;
sscanf(value.c_str(), "%d", &result);
return result;
};
- (std::string) trim:(std::string) value {
std::string str(value);
int i = 0;
while (i < str.length()) {
if (str[i] == ' ' || str[i] == '\t') i++;
else {
if (i != 0)
str = str.substr(i, str.length());
break;
}
}
i = str.length()-1;
while (i >= 0) {
if (str[i] == ' ' || str[i] == '\t') i++;
else {
if (i != str.length()-1)
str = str.substr(0, i-1);
break;
}
}
return str;
}
@end
void cropImage(NSImage * source, std::string savename, std::string spritename, AtlasItem info) {
//Init target image
NSImage *target = [[NSImage alloc]initWithSize:NSMakeSize(info.size.x,info.size.y)];
//start drawing on target
[target lockFocus];
//draw the portion of the source image on target image
[source drawInRect:NSMakeRect(0,0,info.size.x,info.size.y)
fromRect:NSMakeRect(info.xy.x, source.size.height - info.xy.y-info.size.y, info.size.x, info.size.y)
operation:NSCompositeCopy
fraction:1.0];
//end drawing
[target unlockFocus];
//create a NSBitmapImageRep
NSBitmapImageRep *bmpImageRep = [[NSBitmapImageRep alloc]initWithData:[target TIFFRepresentation]];
//add the NSBitmapImage to the representation list of the target
[target addRepresentation:bmpImageRep];
//get the data from the representation
NSData *data = [bmpImageRep representationUsingType:NSPNGFileType properties: nil];
//write the data to a file
[data writeToFile:[NSString stringWithFormat:@"%s@2x/%s", savename.c_str(), spritename.c_str(), nil] atomically: NO];
target = [[NSImage alloc]initWithSize:NSMakeSize(info.size.x/2,info.size.y/2)];
//start drawing on target
[target lockFocus];
//draw the portion of the source image on target image
[source drawInRect:NSMakeRect(0,0,info.size.x/2,info.size.y/2)
fromRect:NSMakeRect(info.xy.x, source.size.height - info.xy.y-info.size.y, info.size.x, info.size.y)
operation:NSCompositeCopy
fraction:1.0];
//end drawing
[target unlockFocus];
//create a NSBitmapImageRep
bmpImageRep = [[NSBitmapImageRep alloc]initWithData:[target TIFFRepresentation]];
//add the NSBitmapImage to the representation list of the target
[target addRepresentation:bmpImageRep];
//get the data from the representation
data = [bmpImageRep representationUsingType:NSPNGFileType properties: nil];
//write the data to a file
[data writeToFile:[NSString stringWithFormat:@"%s/%s", savename.c_str(), spritename.c_str(), nil] atomically: NO];
}
int main(int argc, const char * argv[])
{
@autoreleasepool {
if (argc == 1)
return 0;
for (int i = 1; i < argc; i++) {
std::string atlasName = argv[i];
AtlasLoader * loader = [[AtlasLoader alloc] init];
std::string atlasPath = atlasName.substr(0, atlasName.find_last_of('/')+1);
std::string saveto = atlasPath + "result/" + atlasName.substr(atlasName.find_last_of('/'), atlasName.length());
[loader LoadItems:atlasName];
NSImage *source = [[NSImage alloc]initWithContentsOfFile:[NSString stringWithFormat:@"%s%s", atlasPath.c_str(),[loader getTextureName].c_str(), nil]];
std::vector<std::string> allSprites = [loader getThemAll];
NSFileManager *fileManager= [NSFileManager defaultManager];
NSString * directory = [NSString stringWithFormat:@"%s", saveto.c_str(), nil];
if(![fileManager createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:nil error:NULL])
NSLog(@"Error: Create folder failed %@", directory);
directory = [NSString stringWithFormat:@"%s@2x", saveto.c_str(), nil];
if(![fileManager createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:nil error:NULL])
NSLog(@"Error: Create folder failed %@", directory);
for (int j = 0; j < allSprites.size(); j++) {
cropImage(source, saveto, allSprites[j]+".png", [loader getItemParams:allSprites[j]]);
}
printf("%s - done.\n", atlasName.substr(atlasName.find_last_of('/'), atlasName.length()).c_str());
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment