Попытка программно обрезать UIImage для множества меньших. Должен ли этот раздел моего кода работать? - PullRequest
0 голосов
/ 23 марта 2012

Я уже несколько дней пытаюсь создать загрузчик спрайт-листов, и я написал то, что я считаю довольно солидным и довольно приличным алгоритмом для этого.Однако, когда дело доходит до рисования одного кадра, который я вырезал из большего листа спрайта, ничего не рисуется, и в данный момент я пытаюсь определить, в чем проблема.Я сильно подозреваю, что это метод, который я использую, чтобы вырезать кадр.Так и здесь.(Возможно, я немного аннотирую свой код)

- (UIImage*) cutOutFrame:(UIImage *)spriteSheet frameDimensions:(CGRect)frameRect 
{ 

//create a context to do our cropping within
UIGraphicsBeginImageContext(frameRect.size);
CGContextRef currentContext = UIGraphicsGetCurrentContext();

//now we create a CGRect to crop our new Context down to the size of the sprite we're about to place in it. Make the X&Ycoordinates 0,0 so that we clip at the beginning of the context. Then the height and width need to be the height and width of our sprite.
CGRect rectForContextClip = CGRectMake(0, 0, frameRect.size.width, frameRect.size.height);
//now clip the context to nothing but rectForContextClip
CGContextClipToRect(currentContext, rectForContextClip);

//create a rect the size of the spritesheet to draw out sprite sheet into. We will then put the sprite sheet ontop of our frame-sized context and make a UIImage out of JUST THAT. This CGRect however is mainly to control the offset
//This is important as we need to be drawing the right frame into our context below
CGRect drawRect = CGRectMake(frameRect.origin.x, 
                             frameRect.origin.y, 
                             spriteSheet.size.width, 
                             spriteSheet.size.height);

//draw the spritesheet to our clipped context
CGContextDrawImage(currentContext, drawRect, spriteSheet.CGImage);

//now we simply rip this clipped context with our Frame on it into its own UIImage :D
UIImage* ourFrame = UIGraphicsGetImageFromCurrentImageContext();


//I'm assuming this clears the context and makes it not the current context anymore. Probably doesn't do the memory any harm too.
UIGraphicsEndImageContext();

NSLog(@"ourFrame dimensions /nwidth = %f/nheight = %f",ourFrame.size.width, ourFrame.size.height);

return ourFrame;
}

Этот метод cutOutFrame затем используется в другой функции, которая перебирает лист спрайта и создает массив UIImages, каждое из которых содержит только одно из изображений, содержащихся вспрайт лист.Этот метод ниже, если кто-то считает, что он может помочь в решении этой проблемы.

- (void) chopSpriteSheet:(UIImage*) sheetToChop
{
    //create a dictionary to hold the dictionary "frames" we loaded in from the plist file
    if(!sheetFrameData)
    {
    sheetFrameData = [[NSDictionary alloc] initWithDictionary:[coordinates valueForKey:@"frames"]];
    }

    //create an array to hold all the keys in sheetFrameData for us to iterate through
    NSArray* framesKeysArray = [[NSArray alloc]initWithArray:[sheetFrameData allKeys]];

    //loop through the elements in framesKeyArray, get the info at that key within sheetFrame Data
    for (int i=0; i<[framesKeysArray count]; i++) 
    {
            //TODO cycle through, create the UIimages for each frame and load them into the NSArray sheetFrames//UPDATE load
            //TOBEDONE with the cutOutFrame function then into the frames dictionary

        //ensure the frames dictionary is not Nil and holds enough memory to accomodate for all the images in the sprite sheet 

        //not to be confused with the frames dictionary from the plist file
        if (!frames)
        {
            frames = [[NSMutableDictionary alloc] initWithCapacity:[framesKeysArray count]];
        }

        //Shove the values found in the dictionary at the location of the key given by the corresponding entry in the framesKeyArray into the cutOutFrame function
        UIImage* frameToArray = [self cutOutFrame:sheetToChop frameDimensions:CGRectMake(
            [[[sheetFrameData valueForKey:[framesKeysArray objectAtIndex:i]] valueForKey:@"x"] floatValue], 
            [[[sheetFrameData valueForKey:[framesKeysArray objectAtIndex:i]] valueForKey:@"y"] floatValue], 
            [[[sheetFrameData valueForKey:[framesKeysArray objectAtIndex:i]] valueForKey:@"width"] floatValue],
            [[[sheetFrameData valueForKey:[framesKeysArray objectAtIndex:i]] valueForKey:@"height"] floatValue])];


        we'll then stick it all into the frames dictionary, which stores all of them as GLTextures

        [frames setValue:[[GLTexture alloc] initWithImage:frameToArray] forKey:[NSString stringWithFormat:@"frame%i", i]];



    }
    //release framesKeyArray 
    [framesKeysArray release];



}

Так вот, что у меня есть.Можете ли вы увидеть здесь что-нибудь, что могло бы сделать UIImage пустым?

PS на случай, если вам интересно, GLTexture - это класс, который я использую для рисования UIImage с использованием openGL.Но, используя другие примеры, я уже доказал себе, что этот класс работает.

1 Ответ

0 голосов
/ 23 марта 2012

Я думаю, вы хотите сделать это:

CGRect drawRect = CGRectMake(-frameRect.origin.x, 
                             -frameRect.origin.y, 
                             spriteSheet.size.width, 
                             spriteSheet.size.height);

То есть нарисуйте полное смещение изображения вниз и влево, чтобы вырезанный фрагмент попал в текущий контекст.

(Кроме того, CGContextClipToRect не требуется, поскольку контекст автоматически обрезает свои границы)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...