extracting a selection of Textures from a Texture Atlas - objective-c

I'm trying to write a method to do the above. My Texture Atlas contains more than 500 Textures. When i store my extracted Textures in a new Array and log its description the Array contains my correct named 3 Textures PLUS all of the Textures the original Atlas contained. Everyone of these is referred to " 'MissingResource.png' (128 x 128)".
My Question is: How can i ONLY store the 3 textures i want in the new Array? Here is the code:
-(void)createSelectedTexturesWith:(NSString*)ImageName;
{
int bgCount = 1;
NSMutableString *tempstring = [NSMutableString stringWithString:ImageName];
SKTextureAtlas *atlas = [SKTextureAtlas atlasNamed:#"textures"];
NSMutableArray *Leveltextures = [[NSMutableArray alloc]init];
NSUInteger numImages = atlas.textureNames.count;
for (int i=1;i <= numImages; i++) {
[tempstring appendFormat:#"_%02d.png",bgCount];
NSString *textureName = [NSString stringWithString:tempstring];
SKTexture *temp = [atlas textureNamed:textureName];
[Leveltextures addObject:temp];
[tempstring setString:ImageName];
bgCount++;
}
NSLog(#"Leveltextures Content: %#",[Leveltextures description]);
}

Not sure I understand what you want. But if I do understand it correctly, why can't you just check if the textureName's prefix matches your imageName and only create the texture and add to the array in that case only ?

Thank you prototypical, that did it for me. Though the code is maybe not too elegant, here it is. Maybe it helps somebody else.
-(void)createSelectedTexturesWith:(NSString*)ImageName;
{
bgCount=1;
NSMutableString *tempstring = [NSMutableString stringWithString:ImageName];
SKTextureAtlas *atlas = [SKTextureAtlas atlasNamed:#"textures"];
NSMutableArray *Leveltextures = [[NSMutableArray alloc]init];
NSArray *atlasArray = [atlas textureNames];
for (NSString *string in atlasArray) {
if ([string hasPrefix:ImageName]){
[tempstring appendFormat:#"%02d.png",bgCount];
NSString *textureName = [NSString stringWithString:tempstring];
SKTexture *temp = [atlas textureNamed:textureName];
[Leveltextures addObject:temp];
[tempstring setString:ImageName];
bgCount++;
}
}
NSLog(#"Leveltextures Content: %#",[Leveltextures description]);
}

Related

All objects in array (interpreted from csv) being returned as the same object (the last object)

What I am trying to achieve, is to convert a csv file into an array of custom objects, however, my attempts at this seem to result in all of the objects in the array being returned as the same object (the last object in the array).
Before I explain further, here is the code:
- (NSArray *)arrayFromCSVFileName:(NSString *)csvFileName fileType:(NSString *)fileType {
// Convert the file into an NSData object
NSString *studentFilePath = [[NSBundle mainBundle] pathForResource:csvFileName ofType:fileType];
NSData *studentData = [NSData dataWithContentsOfFile:studentFilePath];
// Convert the NSData into an NSString
NSString *csvString = [[NSString alloc] initWithData:studentData encoding:NSUTF8StringEncoding];
// Split each record (line) in the csvDataString into an individual array element (split on the newline character \n)
NSArray *csvArray = [csvString componentsSeparatedByString:#"\n"];
// Create an array to hold the parsed CSV data
NSMutableArray *parsedCSVArray = [[NSMutableArray alloc] init];
NSMutableArray *elementArray = [[NSMutableArray alloc] init];
CGSElement *elementToAdd = [[CGSElement alloc] init];
// Loop through each line of the file
for (int i = 0; i < [csvArray count]; i++) {
// Get a reference to this record (line) as a string, and remove any extranous new lines or alike
NSString *csvRecordString = [[csvArray objectAtIndex:i] stringByReplacingOccurrencesOfString:#"\r" withString:#""];
// Split the line by the comma delimeter
NSArray *csvRecordArray = [csvRecordString componentsSeparatedByString:#","];
// Check that there are actually fields (i.e. this is not a blank line)
if ( ([csvRecordArray count] > 0) && ([[csvRecordArray objectAtIndex:0] length] > 0) ) {
elementToAdd.mass = [[csvRecordArray objectAtIndex:1] floatValue];
elementToAdd.atomicNumber = [[csvRecordArray objectAtIndex:0] intValue];
elementToAdd.name = [csvRecordArray objectAtIndex:2];
elementToAdd.symbol = [csvRecordArray objectAtIndex:3];
elementToAdd.period = [[csvRecordArray objectAtIndex:4] intValue];
[elementArray addObject:elementToAdd];
}
}
for (int i = 0; i < [elementArray count]; i++) {
NSLog(#"%i", i);
CGSElement *current = [elementArray objectAtIndex:i];
NSLog(#"Name = %#", current.name);
}
// Return the parsed array
return elementArray;
}
The custom object in question is the CGSElement object, which I am attempting to fill the elementArray with. However, my debug code (the following section of code):
for (int i = 0; i < [elementArray count]; i++) {
NSLog(#"%i", i);
CGSElement *current = [elementArray objectAtIndex:i];
NSLog(#"Name = %#", current.name);
}
Is resulting, rather than in the return of all of the correct element names, it is returning the last element (to put this in context, ununoctium), 118 times.
After some testing, I can safely say that up until after this point:
elementToAdd.mass = [[csvRecordArray objectAtIndex:1] floatValue];
elementToAdd.atomicNumber = [[csvRecordArray objectAtIndex:0] intValue];
elementToAdd.name = [csvRecordArray objectAtIndex:2];
elementToAdd.symbol = [csvRecordArray objectAtIndex:3];
elementToAdd.period = [[csvRecordArray objectAtIndex:4] intValue];
All of the elements are being correctly defined, rather than just the same element over and over.
Needless to say, I'm stumped as to why it would be returning the same object over and over. Any help would be appreciated.
This line:
CGSElement *elementToAdd = [[CGSElement alloc] init];
Should be inside your loop, just before you try to edit the object and add it to the array. Currently you are repeatedly mutating the same object instead of creating new objects for each record.
You add the same entity all the time. It is crated once before the loop and within the loop it values are changed again and angan and it is added to the array. Naturally all items in the aray carry the same values because it is the same object.
If you want then change the array with an NSSet. To a set an object can only added once and you will end up with a set of 1. That is not the solution of couse, it would just visualize what is happening.
To solve it move this line
CGSElement *elementToAdd = [[CGSElement alloc] init];
to the beginning of the body of the for i loop, so that a new instance is created for every iteration and therefore for every index of the array.

How to view the entire content of an array in a label (xcode 4.1)

i'm programming in Obj-c with xcode4.1, i have an array with numbers in it, and i want to visualize all of them in a label...can anyone help me around this please?
thanks!
this is the code:
combinedString=[[NSMutableArray alloc] init];
NSString *finalStringLabel=#"";
for (i=0; i<=textLength; i++) {
//character coding
char myChar = [myString characterAtIndex:i];
NSString *myCharS=[NSString stringWithFormat:#"%c", myChar];
int asciiCode=[myCharS characterAtIndex:0];
NSString *asciiS=[NSString stringWithFormat:#"%i", asciiCode];
[combinedString addObject:asciiS];
}
finalStringLabel=[NSString stringWithFormat:#"", [combinedString componentsJoinedByString:#"."]];
myLabel.text=finalStringLabel;
[combinedString release];
}
You can use this
NSArray *yourArray;
NSString *createdString = [yourArray componentsJoinedByString:#" "];
myLabel.text = createdString;
As your array is combinedString,
combinedString=[[NSMutableArray alloc] init];
looks like you are providing values after this line or this is not a property (this is a local as you are releasing it later), and your code in not complete.
Anyways,
You don't need to create an empty string and then assign new object to it, need to do as :
myLabel.text=[combinedString componentsJoinedByString:#"."];
[combinedString release];
}

replace an object inside nsmutablearray

I have a NSMutableArray where i want to replace the sign | into a ; how can i do that?
NSMutableArray *paths = [dic valueForKey:#"PATH"];
NSLog(#"pathArr ", paths)
pathArr (
(
"29858,39812;29858,39812;29925,39804;29936,39803;29949,39802;29961,39801;30146,39782;30173,39779;30220,39774;30222,39774|30215,39775;30173,39779;30146,39782;29961,39801;29949,39802;29936,39803;29925,39804;29858,39812;29858,39812;29856,39812;29800,39819;29668,39843;29650,39847;29613,39855;29613,39855;29613,39856;29605,39857;29603,39867;29603,39867;29599,39892;29596,39909;29587,39957;29571,40018;29563,40038;29560,40043"
)
)
Update
This is where i got my path from
NSArray *BusRoute = alightDesc;
int i;
int count = [BusRoute count];
for (i = 0; i < count; i++)
{
NSLog (#"BusRoute = %#", [BusRoute objectAtIndex: i]);
NSDictionary *dic = [BusRoute objectAtIndex: i];
NSMutableArray *paths = [dic valueForKey:#"PATH"];
}
Provide that your object in the array path is string, you can do this
NSMutableArray *path2=[[NSMutableArray alloc]initWithArray:nil];
for (NSObject *obect in path) {
for (NSString *string in (NSArray*)obect) {
[path2 addObject:[string stringByReplacingOccurrencesOfString:#"|" withString:#","]];
}
}
NSLog(#"pathArr %# ", path2);
your array paths contains an another array which has string as object.
Hope this helps
//Copy the Array into a String
NSString *str = [paths componentsJoinedByString: #""];
//then replace the "|"
str = [str stringByReplacingOccurrencesOfString:#"|" withString:#";"];
i did this to replace a string in a .plist so it might work for you
array1 = [NSMutableArray arrayWithContentsOfFile:Path1];
NSString *item = [#"dfdfDF"];
[array1 replaceObjectAtIndex:1 withObject:item];
[array1 writeToFile:Path1 atomically:YES];
NSLog(#"count: %#", [array1 objectAtIndex:1]);
you may cast or convert paths to NSString and then do:
paths = (NSString *) [paths stringByReplacingOccurrencesOfString:#"|" withString:#";"];
if this does't work, create new NSString instance that containing pathArr text, invoke replaceOccurrences method and do invert conversion
NSMutableString *tempStr = [[NSMutableString alloc] init];
for (int i = 0; i < [paths count]; i++)
{
[tempStr appendString:[path objectAtIndex:i]];
}
then use this method for tempStr. And then try:
NSArray *newPaths = [tempStr componentsSeparatedByString:#";"];
may be last method not completely correct, so try experiment with it.
Uh, why don't you just go:
NSString *cleanedString = [[[dic valueForKey:#"PATH"] objectAtIndex:0] stringByReplacingOccurrencesOfString:#";" withString:#"|"];
If there are more than one nested array, you can go
for(int i = 0; i < [[dic valueForKey:#"PATH"] count]; i++)
{
NSString *cleanedString = [[[dic valueForKey:#"PATH"] objectAtIndex:i] stringByReplacingOccurrencesOfString:#";" withString:#"|"];
// do something with cleanedString
}

opencv ios cvseq storage

I am intending to pre-load all the images that I have stored inside application. Pre-loading of images involves:
Read images from bundle.
Extract object descriptors using cvExtractSurf from opencv framework.
Store IPLImage with corresponding object descriptors and keypoints.
I am having an issue in creating a dictionary containing CvSeq* keys and CvSeq* descs.
Please suggest how to store these values in NSMutableDictionary.
-(void) preloadImages:(NSMutableDictionary *)dictionary{
NSArray *d = [[NSBundle mainBundle] pathsForResourcesOfType:#"png" inDirectory:nil];
CvSURFParams params = cvSURFParams(500, 1);
CvMemStorage* storage = cvCreateMemStorage(0);
for( int i=0;i<[d count];i++){
NSString *searchForMe = #"myapp.app/1";
NSString *s = [[NSString alloc] initWithString:[d objectAtIndex:i]];
NSRange range = [s rangeOfString:searchForMe];
if( range.location != NSNotFound ){
NSMutableDictionary *surfDict = [[NSMutableDictionary alloc] init];
NSString *substring = [s substringFromIndex:range.location];
substring = [substring stringByReplacingOccurrencesOfString:#"myapp.app/" withString:#""];
UIImage *testImage = [UIImage imageNamed:substring];
IplImage *iplTestImage = [OpenCVUtilities CreateGRAYIplImageFromUIImage:testImage];
CvSeq *keys = 0 ;
CvSeq *descs = 0;
cvExtractSURF( iplTestImage, 0, &keys, &descs, storage, params );
[surfDict setObject:(id)testImage forKey:#"uiImage"];
NSLog(#"Image name : %#", substring);
[dictionary setObject:surfDict forKey:[NSString stringWithFormat:#"%d",i]];
[dictionary setObject:(NSObject *)keys forKey:#"keys"]; // error here
[dictionary setObject:(NSObject *)descs forKey:#"descs"]; // error here
[surfDict release];
}
}
}
Create a class that has an instance variable of type cvseq, add your cvseq to the object, and add that class to the dictionary.

finding a number in array

I have an Array {-1,0,1,2,3,4...}
I am trying to find whether an element exist in these number or not, code is not working
NSInteger ind = [favArray indexOfObject:[NSNumber numberWithInt:3]];
in ind i am always getting 2147483647
I am filling my array like this
//Loading favArray from favs.plist
NSString* favPlistPath = [[NSBundle mainBundle] pathForResource:#"favs" ofType:#"plist"];
NSMutableDictionary* favPlistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:favPlistPath];
NSString *favString = [favPlistDict objectForKey:#"list"];
NSArray *favList = [favString componentsSeparatedByString:#","];
//int n = [[favList objectAtIndex:0] intValue];
favArray = [[NSMutableArray alloc] initWithCapacity:100];
if([favList count]>1)
{
for(int i=1; i<[favList count]; i++)
{
NSNumber *f = [favList objectAtIndex:i];
[favArray insertObject:f atIndex:(i-1)];
}
}
That's the value of NSNotFound, which means that favArray contains no object that isEqual: to [NSNumber numberWithInt:3]. Check your array.
After second edit:
Your favList array is filled with NSString objects. You should convert the string objects to NSNumber objects before inserting them in favArray:
NSNumber *f = [NSNumber numberWithInt:[[favList objectAtIndex:i] intValue]];