private Drawable createDrawableFromFetchedResult(Context context, CloseableImage image) { if (image instanceof CloseableStaticBitmap) { CloseableStaticBitmap closeableStaticBitmap = (CloseableStaticBitmap) image; BitmapDrawable bitmapDrawable = createBitmapDrawable(context, closeableStaticBitmap.getUnderlyingBitmap()); return (closeableStaticBitmap.getRotationAngle() != 0 && closeableStaticBitmap.getRotationAngle() != -1 ? new OrientedDrawable(bitmapDrawable, closeableStaticBitmap.getRotationAngle()) : bitmapDrawable); } else if (image instanceof CloseableAnimatedImage) { AnimatedDrawableFactory animatedDrawableFactory = Fresco.getImagePipelineFactory().getAnimatedFactory().getAnimatedDrawableFactory(context); if (animatedDrawableFactory != null) { AnimatedDrawable animatedDrawable = (AnimatedDrawable) animatedDrawableFactory.create(image); if (animatedDrawable != null) { return animatedDrawable; } } } throw new UnsupportedOperationException("Unrecognized image class: " + image); }
@Test public void testNonStaticBitmapIsPassedOn() { SingleUsePostprocessorConsumer postprocessorConsumer = produceResults(); CloseableAnimatedImage sourceCloseableAnimatedImage = mock(CloseableAnimatedImage.class); CloseableReference<CloseableImage> sourceCloseableImageRef = CloseableReference.<CloseableImage>of(sourceCloseableAnimatedImage); postprocessorConsumer.onNewResult(sourceCloseableImageRef, Consumer.IS_LAST); sourceCloseableImageRef.close(); mTestExecutorService.runUntilIdle(); mInOrder.verify(mConsumer).onNewResult(any(CloseableReference.class), eq(Consumer.IS_LAST)); mInOrder.verifyNoMoreInteractions(); assertEquals(1, mResults.size()); CloseableReference<CloseableImage> res0 = mResults.get(0); assertTrue(CloseableReference.isValid(res0)); assertSame(sourceCloseableAnimatedImage, res0.get()); res0.close(); verify(sourceCloseableAnimatedImage).close(); }
@Test public void testNonStaticBitmapIsPassedOn() { RepeatedPostprocessorConsumer postprocessorConsumer = produceResults(); RepeatedPostprocessorRunner repeatedPostprocessorRunner = getRunner(); CloseableAnimatedImage sourceCloseableAnimatedImage = mock(CloseableAnimatedImage.class); CloseableReference<CloseableImage> sourceCloseableImageRef = CloseableReference.<CloseableImage>of(sourceCloseableAnimatedImage); postprocessorConsumer.onNewResult(sourceCloseableImageRef, Consumer.IS_LAST); sourceCloseableImageRef.close(); mTestExecutorService.runUntilIdle(); mInOrder.verify(mConsumer).onNewResult(any(CloseableReference.class), eq(Consumer.NO_FLAGS)); mInOrder.verifyNoMoreInteractions(); assertEquals(1, mResults.size()); CloseableReference<CloseableImage> res0 = mResults.get(0); assertTrue(CloseableReference.isValid(res0)); assertSame(sourceCloseableAnimatedImage, res0.get()); res0.close(); performCancelAndVerifyOnCancellation(); verify(sourceCloseableAnimatedImage).close(); }
private CloseableImage getCloseableImage( ImageDecodeOptions options, AnimatedImage image, Bitmap.Config bitmapConfig) { List<CloseableReference<Bitmap>> decodedFrames = null; CloseableReference<Bitmap> previewBitmap = null; try { final int frameForPreview = options.useLastFrameForPreview ? image.getFrameCount() - 1 : 0; if (options.forceStaticImage) { return new CloseableStaticBitmap( createPreviewBitmap(image, bitmapConfig, frameForPreview), ImmutableQualityInfo.FULL_QUALITY, 0); } if (options.decodeAllFrames) { decodedFrames = decodeAllFrames(image, bitmapConfig); previewBitmap = CloseableReference.cloneOrNull(decodedFrames.get(frameForPreview)); } if (options.decodePreviewFrame && previewBitmap == null) { previewBitmap = createPreviewBitmap(image, bitmapConfig, frameForPreview); } AnimatedImageResult animatedImageResult = AnimatedImageResult.newBuilder(image) .setPreviewBitmap(previewBitmap) .setFrameForPreview(frameForPreview) .setDecodedFrames(decodedFrames) .build(); return new CloseableAnimatedImage(animatedImageResult); } finally { CloseableReference.closeSafely(previewBitmap); CloseableReference.closeSafely(decodedFrames); } }
@Test public void testCreateDefaults() { WebPImage mockWebPImage = mock(WebPImage.class); // Expect a call to WebPImage.create TrivialPooledByteBuffer byteBuffer = createByteBuffer(); when(mWebPImageMock.decode(byteBuffer.getNativePtr(), byteBuffer.size())) .thenReturn(mockWebPImage); EncodedImage encodedImage = new EncodedImage( CloseableReference.of(byteBuffer, FAKE_RESOURCE_RELEASER)); encodedImage.setImageFormat(ImageFormat.UNKNOWN); CloseableAnimatedImage closeableImage = (CloseableAnimatedImage) mAnimatedImageFactory.decodeWebP( encodedImage, ImageDecodeOptions.defaults(), DEFAULT_BITMAP_CONFIG); // Verify we got the right result AnimatedImageResult imageResult = closeableImage.getImageResult(); assertSame(mockWebPImage, imageResult.getImage()); assertNull(imageResult.getPreviewBitmap()); assertFalse(imageResult.hasDecodedFrame(0)); // Should not have interacted with these. verifyZeroInteractions(mMockAnimatedDrawableBackendProvider); verifyZeroInteractions(mMockBitmapFactory); }
@Test public void testCreateDefaults() { GifImage mockGifImage = mock(GifImage.class); // Expect a call to GifImage.create TrivialPooledByteBuffer byteBuffer = createByteBuffer(); when(mGifImageMock.decode(byteBuffer.getNativePtr(), byteBuffer.size())) .thenReturn(mockGifImage); EncodedImage encodedImage = new EncodedImage( CloseableReference.of(byteBuffer, FAKE_RESOURCE_RELEASER)); encodedImage.setImageFormat(ImageFormat.UNKNOWN); CloseableAnimatedImage closeableImage = (CloseableAnimatedImage) mAnimatedImageFactory.decodeGif( encodedImage, ImageDecodeOptions.defaults(), DEFAULT_BITMAP_CONFIG); // Verify we got the right result AnimatedImageResult imageResult = closeableImage.getImageResult(); assertSame(mockGifImage, imageResult.getImage()); assertNull(imageResult.getPreviewBitmap()); assertFalse(imageResult.hasDecodedFrame(0)); // Should not have interacted with these. verifyZeroInteractions(mMockAnimatedDrawableBackendProvider); verifyZeroInteractions(mMockBitmapFactory); }
@Override public boolean supportsImageType(CloseableImage image) { return image instanceof CloseableAnimatedImage; }
@Override public AnimatedDrawable2 createDrawable(CloseableImage image) { return new AnimatedDrawable2( createAnimationBackend( ((CloseableAnimatedImage) image).getImageResult())); }
@Test public void testCreateWithPreviewBitmap() throws Exception { WebPImage mockWebPImage = mock(WebPImage.class); Bitmap mockBitmap = MockBitmapFactory.create(50, 50, DEFAULT_BITMAP_CONFIG); // Expect a call to WebPImage.create TrivialPooledByteBuffer byteBuffer = createByteBuffer(); when(mWebPImageMock.decode(byteBuffer.getNativePtr(), byteBuffer.size())) .thenReturn(mockWebPImage); when(mockWebPImage.getWidth()).thenReturn(50); when(mockWebPImage.getHeight()).thenReturn(50); // For decoding preview frame, expect some calls. final AnimatedDrawableBackend mockAnimatedDrawableBackend = createAnimatedDrawableBackendMock(1); when(mMockAnimatedDrawableBackendProvider.get( any(AnimatedImageResult.class), isNull(Rect.class))) .thenReturn(mockAnimatedDrawableBackend); when(mMockBitmapFactory.createBitmapInternal(50, 50, DEFAULT_BITMAP_CONFIG)) .thenReturn(CloseableReference.of(mockBitmap, FAKE_BITMAP_RESOURCE_RELEASER)); AnimatedImageCompositor mockCompositor = mock(AnimatedImageCompositor.class); PowerMockito.whenNew(AnimatedImageCompositor.class) .withAnyArguments() .thenReturn(mockCompositor); ImageDecodeOptions imageDecodeOptions = ImageDecodeOptions.newBuilder() .setDecodePreviewFrame(true) .build(); EncodedImage encodedImage = new EncodedImage( CloseableReference.of(byteBuffer, FAKE_RESOURCE_RELEASER)); encodedImage.setImageFormat(ImageFormat.UNKNOWN); CloseableAnimatedImage closeableImage = (CloseableAnimatedImage) mAnimatedImageFactory.decodeWebP( encodedImage, imageDecodeOptions, DEFAULT_BITMAP_CONFIG); // Verify we got the right result AnimatedImageResult imageResult = closeableImage.getImageResult(); assertSame(mockWebPImage, imageResult.getImage()); assertNotNull(imageResult.getPreviewBitmap()); assertFalse(imageResult.hasDecodedFrame(0)); // Should not have interacted with these. verify(mMockAnimatedDrawableBackendProvider).get( any(AnimatedImageResult.class), isNull(Rect.class)); verifyNoMoreInteractions(mMockAnimatedDrawableBackendProvider); verify(mMockBitmapFactory).createBitmapInternal(50, 50, DEFAULT_BITMAP_CONFIG); verifyNoMoreInteractions(mMockBitmapFactory); verify(mockCompositor).renderFrame(0, mockBitmap); }
@Test public void testCreateWithDecodeAlFrames() throws Exception { WebPImage mockWebPImage = mock(WebPImage.class); Bitmap mockBitmap1 = MockBitmapFactory.create(50, 50, DEFAULT_BITMAP_CONFIG); Bitmap mockBitmap2 = MockBitmapFactory.create(50, 50, DEFAULT_BITMAP_CONFIG); // Expect a call to WebPImage.create TrivialPooledByteBuffer byteBuffer = createByteBuffer(); when(mWebPImageMock.decode(byteBuffer.getNativePtr(), byteBuffer.size())) .thenReturn(mockWebPImage); when(mockWebPImage.getWidth()).thenReturn(50); when(mockWebPImage.getHeight()).thenReturn(50); // For decoding preview frame, expect some calls. final AnimatedDrawableBackend mockAnimatedDrawableBackend = createAnimatedDrawableBackendMock(2); when( mMockAnimatedDrawableBackendProvider.get( any(AnimatedImageResult.class), isNull(Rect.class))) .thenReturn(mockAnimatedDrawableBackend); when(mMockBitmapFactory.createBitmapInternal(50, 50, DEFAULT_BITMAP_CONFIG)) .thenReturn(CloseableReference.of(mockBitmap1, FAKE_BITMAP_RESOURCE_RELEASER)) .thenReturn(CloseableReference.of(mockBitmap2, FAKE_BITMAP_RESOURCE_RELEASER)); AnimatedImageCompositor mockCompositor = mock(AnimatedImageCompositor.class); PowerMockito.whenNew(AnimatedImageCompositor.class) .withAnyArguments() .thenReturn(mockCompositor); ImageDecodeOptions imageDecodeOptions = ImageDecodeOptions.newBuilder() .setDecodePreviewFrame(true) .setDecodeAllFrames(true) .build(); EncodedImage encodedImage = new EncodedImage( CloseableReference.of(byteBuffer, FAKE_RESOURCE_RELEASER)); encodedImage.setImageFormat(ImageFormat.UNKNOWN); CloseableAnimatedImage closeableImage = (CloseableAnimatedImage) mAnimatedImageFactory.decodeWebP( encodedImage, imageDecodeOptions, DEFAULT_BITMAP_CONFIG); // Verify we got the right result AnimatedImageResult imageResult = closeableImage.getImageResult(); assertSame(mockWebPImage, imageResult.getImage()); assertNotNull(imageResult.getDecodedFrame(0)); assertNotNull(imageResult.getDecodedFrame(1)); assertNotNull(imageResult.getPreviewBitmap()); // Should not have interacted with these. verify(mMockAnimatedDrawableBackendProvider).get( any(AnimatedImageResult.class), isNull(Rect.class)); verifyNoMoreInteractions(mMockAnimatedDrawableBackendProvider); verify(mMockBitmapFactory, times(2)).createBitmapInternal(50, 50, DEFAULT_BITMAP_CONFIG); verifyNoMoreInteractions(mMockBitmapFactory); verify(mockCompositor).renderFrame(0, mockBitmap1); verify(mockCompositor).renderFrame(1, mockBitmap2); }
@Test public void testCreateWithPreviewBitmap() throws Exception { GifImage mockGifImage = mock(GifImage.class); Bitmap mockBitmap = MockBitmapFactory.create(50, 50, DEFAULT_BITMAP_CONFIG); // Expect a call to WebPImage.create TrivialPooledByteBuffer byteBuffer = createByteBuffer(); when(mGifImageMock.decode(byteBuffer.getNativePtr(), byteBuffer.size())) .thenReturn(mockGifImage); when(mockGifImage.getWidth()).thenReturn(50); when(mockGifImage.getHeight()).thenReturn(50); // For decoding preview frame, expect some calls. final AnimatedDrawableBackend mockAnimatedDrawableBackend = createAnimatedDrawableBackendMock(1); when(mMockAnimatedDrawableBackendProvider.get( any(AnimatedImageResult.class), isNull(Rect.class))) .thenReturn(mockAnimatedDrawableBackend); when(mMockBitmapFactory.createBitmapInternal(50, 50, DEFAULT_BITMAP_CONFIG)) .thenReturn(CloseableReference.of(mockBitmap, FAKE_BITMAP_RESOURCE_RELEASER)); AnimatedImageCompositor mockCompositor = mock(AnimatedImageCompositor.class); PowerMockito.whenNew(AnimatedImageCompositor.class) .withAnyArguments() .thenReturn(mockCompositor); ImageDecodeOptions imageDecodeOptions = ImageDecodeOptions.newBuilder() .setDecodePreviewFrame(true) .build(); EncodedImage encodedImage = new EncodedImage( CloseableReference.of(byteBuffer, FAKE_RESOURCE_RELEASER)); encodedImage.setImageFormat(ImageFormat.UNKNOWN); CloseableAnimatedImage closeableImage = (CloseableAnimatedImage) mAnimatedImageFactory.decodeGif( encodedImage, imageDecodeOptions, DEFAULT_BITMAP_CONFIG); // Verify we got the right result AnimatedImageResult imageResult = closeableImage.getImageResult(); assertSame(mockGifImage, imageResult.getImage()); assertNotNull(imageResult.getPreviewBitmap()); assertFalse(imageResult.hasDecodedFrame(0)); // Should not have interacted with these. verify(mMockAnimatedDrawableBackendProvider).get( any(AnimatedImageResult.class), isNull(Rect.class)); verifyNoMoreInteractions(mMockAnimatedDrawableBackendProvider); verify(mMockBitmapFactory).createBitmapInternal(50, 50, DEFAULT_BITMAP_CONFIG); verifyNoMoreInteractions(mMockBitmapFactory); verify(mockCompositor).renderFrame(0, mockBitmap); }
@Test public void testCreateWithDecodeAlFrames() throws Exception { GifImage mockGifImage = mock(GifImage.class); Bitmap mockBitmap1 = MockBitmapFactory.create(50, 50, DEFAULT_BITMAP_CONFIG); Bitmap mockBitmap2 = MockBitmapFactory.create(50, 50, DEFAULT_BITMAP_CONFIG); // Expect a call to GifImage.create TrivialPooledByteBuffer byteBuffer = createByteBuffer(); when(mGifImageMock.decode(byteBuffer.getNativePtr(), byteBuffer.size())) .thenReturn(mockGifImage); when(mockGifImage.getWidth()).thenReturn(50); when(mockGifImage.getHeight()).thenReturn(50); // For decoding preview frame, expect some calls. final AnimatedDrawableBackend mockAnimatedDrawableBackend = createAnimatedDrawableBackendMock(2); when( mMockAnimatedDrawableBackendProvider.get( any(AnimatedImageResult.class), isNull(Rect.class))) .thenReturn(mockAnimatedDrawableBackend); when(mMockBitmapFactory.createBitmapInternal(50, 50, DEFAULT_BITMAP_CONFIG)) .thenReturn(CloseableReference.of(mockBitmap1, FAKE_BITMAP_RESOURCE_RELEASER)) .thenReturn(CloseableReference.of(mockBitmap2, FAKE_BITMAP_RESOURCE_RELEASER)); AnimatedImageCompositor mockCompositor = mock(AnimatedImageCompositor.class); PowerMockito.whenNew(AnimatedImageCompositor.class) .withAnyArguments() .thenReturn(mockCompositor); ImageDecodeOptions imageDecodeOptions = ImageDecodeOptions.newBuilder() .setDecodePreviewFrame(true) .setDecodeAllFrames(true) .build(); EncodedImage encodedImage = new EncodedImage( CloseableReference.of(byteBuffer, FAKE_RESOURCE_RELEASER)); encodedImage.setImageFormat(ImageFormat.UNKNOWN); CloseableAnimatedImage closeableImage = (CloseableAnimatedImage) mAnimatedImageFactory.decodeGif( encodedImage, imageDecodeOptions, DEFAULT_BITMAP_CONFIG); // Verify we got the right result AnimatedImageResult imageResult = closeableImage.getImageResult(); assertSame(mockGifImage, imageResult.getImage()); assertNotNull(imageResult.getDecodedFrame(0)); assertNotNull(imageResult.getDecodedFrame(1)); assertNotNull(imageResult.getPreviewBitmap()); // Should not have interacted with these. verify(mMockAnimatedDrawableBackendProvider).get( any(AnimatedImageResult.class), isNull(Rect.class)); verifyNoMoreInteractions(mMockAnimatedDrawableBackendProvider); verify(mMockBitmapFactory, times(2)).createBitmapInternal(50, 50, DEFAULT_BITMAP_CONFIG); verifyNoMoreInteractions(mMockBitmapFactory); verify(mockCompositor).renderFrame(0, mockBitmap1); verify(mockCompositor).renderFrame(1, mockBitmap2); }
private void handleAnimateBitmap(CloseableAnimatedImage animatedImage, int position) { AnimatedDrawableFactory animatedDrawableFactory = Fresco.getImagePipelineFactory().getAnimatedDrawableFactory(); AnimatedDrawable drawable = animatedDrawableFactory.create(animatedImage.getImageResult()); Bitmap bitmap = drawable2Bitmap(drawable); map.put(position, bitmap); }