public void setAndConsumeBitmapRegionLoader(final BitmapRegionLoader bitmapRegionLoader) { if (!mSurfaceCreated) { mQueuedNextBitmapRegionLoader = bitmapRegionLoader; return; } if (mCrossfadeAnimator.isRunning()) { if (mQueuedNextBitmapRegionLoader != null) { mQueuedNextBitmapRegionLoader.destroy(); } mQueuedNextBitmapRegionLoader = bitmapRegionLoader; return; } mNextGLPictureSet.load(bitmapRegionLoader); mCrossfadeAnimator .from(0) .to(1) .withDuration(CROSSFADE_ANIMATION_DURATION) .withEndListener( new Runnable() { @Override public void run() { // swap current and next picturesets final GLPictureSet oldGLPictureSet = mCurrentGLPictureSet; mCurrentGLPictureSet = mNextGLPictureSet; mNextGLPictureSet = new GLPictureSet(oldGLPictureSet.mId); mCallbacks.requestRender(); oldGLPictureSet.destroyPictures(); System.gc(); if (mQueuedNextBitmapRegionLoader != null) { BitmapRegionLoader queuedNextBitmapRegionLoader = mQueuedNextBitmapRegionLoader; mQueuedNextBitmapRegionLoader = null; setAndConsumeBitmapRegionLoader(queuedNextBitmapRegionLoader); } } }) .start(); mCallbacks.requestRender(); }
public void load(BitmapRegionLoader bitmapRegionLoader) { mHasBitmap = (bitmapRegionLoader != null); mBitmapAspectRatio = mHasBitmap ? bitmapRegionLoader.getWidth() * 1f / bitmapRegionLoader.getHeight() : 1f; mDimAmount = DEFAULT_MAX_DIM; destroyPictures(); if (bitmapRegionLoader != null) { BitmapFactory.Options options = new BitmapFactory.Options(); Rect rect = new Rect(); int originalWidth = bitmapRegionLoader.getWidth(); int originalHeight = bitmapRegionLoader.getHeight(); // Calculate image darkness to determine dim amount rect.set(0, 0, originalWidth, originalHeight); options.inSampleSize = ImageUtil.calculateSampleSize(originalHeight, 64); Bitmap tempBitmap = bitmapRegionLoader.decodeRegion(rect, options); float darkness = ImageUtil.calculateDarkness(tempBitmap); mDimAmount = mDemoMode ? DEMO_DIM : (int) (mMaxDim * ((1 - DIM_RANGE) + DIM_RANGE * Math.sqrt(darkness))); tempBitmap.recycle(); // Create the GLPicture objects mPictures[0] = new GLPicture(bitmapRegionLoader, mHeight); if (mMaxPrescaledBlurPixels == 0) { for (int f = 1; f <= mBlurKeyframes; f++) { mPictures[f] = mPictures[0]; } } else { ImageBlurrer blurrer = new ImageBlurrer(mContext); // To blur, first load the entire bitmap region, but at a very large // sample size that's appropriate for the final blurred image options.inSampleSize = ImageUtil.calculateSampleSize(originalHeight, mHeight / mBlurredSampleSize); rect.set(0, 0, originalWidth, originalHeight); tempBitmap = bitmapRegionLoader.decodeRegion(rect, options); // Next, create a scaled down version of the bitmap so that the blur radius // looks appropriate (tempBitmap will likely be bigger than the final blurred // bitmap, and thus the blur may look smaller if we just used tempBitmap as // the final blurred bitmap). // Note that image width should be a multiple of 4 to avoid // issues with RenderScript allocations. int scaledHeight = Math.max(2, MathUtil.floorEven(mHeight / mBlurredSampleSize)); int scaledWidth = Math.max(4, MathUtil.roundMult4((int) (scaledHeight * mBitmapAspectRatio))); Bitmap scaledBitmap = Bitmap.createScaledBitmap(tempBitmap, scaledWidth, scaledHeight, true); tempBitmap.recycle(); // And finally, create a blurred copy for each keyframe. for (int f = 1; f <= mBlurKeyframes; f++) { float desaturateAmount = mMaxGrey / 500f * f / mBlurKeyframes; Bitmap blurredBitmap = blurrer.blurBitmap(scaledBitmap, blurRadiusAtFrame(f), desaturateAmount); mPictures[f] = new GLPicture(blurredBitmap); blurredBitmap.recycle(); } scaledBitmap.recycle(); blurrer.destroy(); } } recomputeTransformMatrices(); mCallbacks.requestRender(); }