Created
October 11, 2012 21:50
-
-
Save agasiev/3875736 to your computer and use it in GitHub Desktop.
libGdx atlas crop tool.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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