public void renderFrame ( int frameNumber , Bitmap bitmap ) { Canvas canvas = new Canvas ( bitmap ) ; canvas . drawColor ( Color . TRANSPARENT , PorterDuff . Mode . SRC ) ; // If blending is required, prepare the canvas with the nearest cached frame. int nextIndex ; if ( ! isKeyFrame ( frameNumber ) ) { // Blending is required. nextIndex points to the next index to render onto the canvas. nextIndex = prepareCanvasWithClosestCachedFrame ( frameNumber - 1 , canvas ) ; } else { // Blending isn't required. Start at the frame we're trying to render. nextIndex = frameNumber ; } // Iterate from nextIndex to the frame number just preceding the one we're trying to render // and composite them in order according to the Disposal Method. for ( int index = nextIndex ; index < frameNumber ; index ++ ) { AnimatedDrawableFrameInfo frameInfo = mAnimatedDrawableBackend . getFrameInfo ( index ) ; DisposalMethod disposalMethod = frameInfo . disposalMethod ; if ( disposalMethod == DisposalMethod . DISPOSE_TO_PREVIOUS ) { continue ; } if ( frameInfo . blendOperation == BlendOperation . NO_BLEND ) { disposeToBackground ( canvas , frameInfo ) ; } mAnimatedDrawableBackend . renderFrame ( index , canvas ) ; mCallback . onIntermediateResult ( index , bitmap ) ; if ( disposalMethod == DisposalMethod . DISPOSE_TO_BACKGROUND ) { disposeToBackground ( canvas , frameInfo ) ; } } AnimatedDrawableFrameInfo frameInfo = mAnimatedDrawableBackend . getFrameInfo ( frameNumber ) ; if ( frameInfo . blendOperation == BlendOperation . NO_BLEND ) { disposeToBackground ( canvas , frameInfo ) ; } // Finally, we render the current frame. We don't dispose it. mAnimatedDrawableBackend . renderFrame ( frameNumber , canvas ) ; }
Renders the specified frame . Only should be called on the rendering thread .