Android Open Source - Muzei Bitmap Region Loader






From Project

Back to project page Muzei.

License

The source code is released under:

Apache License

If you think the Android project Muzei listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright 2014 Google Inc./* w  ww.j av a  2  s. c o m*/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.apps.muzei.render;

import android.graphics.Bitmap;
import android.graphics.BitmapRegionDecoder;
import android.graphics.Matrix;
import android.graphics.Rect;

import java.io.IOException;
import java.io.InputStream;

import static android.graphics.BitmapFactory.Options;

/**
 * Wrapper for {@link BitmapRegionDecoder} with some extra functionality.
 */
public class BitmapRegionLoader {
    private boolean mValid = false;
    private int mRotation = 0;
    private int mOriginalWidth;
    private int mOriginalHeight;
    private Rect mTempRect = new Rect();
    private InputStream mInputStream;
    private volatile BitmapRegionDecoder mBitmapRegionDecoder;
    private Matrix mRotateMatrix;

    public static BitmapRegionLoader newInstance(InputStream in) throws IOException {
        return newInstance(in, 0);
    }

    public static BitmapRegionLoader newInstance(InputStream in, int rotation) throws IOException {
        if (in == null) {
            return null;
        }

        BitmapRegionLoader loader = new BitmapRegionLoader(in);
        if (loader.mValid) {
            loader.mRotation = rotation;
            if (loader.mRotation != 0) {
                loader.mRotateMatrix = new Matrix();
                loader.mRotateMatrix.postRotate(rotation);
            }
            return loader;
        }

        return null;
    }

    private BitmapRegionLoader(InputStream in) throws IOException {
        mInputStream = in;
        mBitmapRegionDecoder = BitmapRegionDecoder.newInstance(in, false);
        if (mBitmapRegionDecoder != null) {
            mOriginalWidth = mBitmapRegionDecoder.getWidth();
            mOriginalHeight = mBitmapRegionDecoder.getHeight();
            mValid = true;
        }
    }

    /**
     * Key difference, aside from support for rotation, from
     * {@link BitmapRegionDecoder#decodeRegion(Rect, Options)} in this implementation is that even
     * if <code>inBitmap</code> is given, a sub-bitmap might be returned.
     */
    public synchronized Bitmap decodeRegion(Rect rect, Options options) {
        int unsampledInBitmapWidth = -1;
        int unsampledInBitmapHeight = -1;
        int sampleSize = Math.max(1, options != null ? options.inSampleSize : 1);
        if (options != null && options.inBitmap != null) {
            unsampledInBitmapWidth = options.inBitmap.getWidth() * sampleSize;
            unsampledInBitmapHeight = options.inBitmap.getHeight() * sampleSize;
        }

        // Decode with rotation
        switch (mRotation) {
            case 90:
                mTempRect.set(
                        rect.top, mOriginalHeight - rect.right,
                        rect.bottom, mOriginalHeight - rect.left);
                break;

            case 180:
                mTempRect.set(
                        mOriginalWidth - rect.right, mOriginalHeight - rect.bottom,
                        mOriginalWidth - rect.left, mOriginalHeight - rect.top);
                break;

            case 270:
                mTempRect.set(
                        mOriginalWidth - rect.bottom, rect.left,
                        mOriginalWidth - rect.top, rect.right);
                break;

            default:
                mTempRect.set(rect);
        }

        Bitmap bitmap = mBitmapRegionDecoder.decodeRegion(mTempRect, options);
        if (bitmap == null) {
            return null;
        }

        if (options != null && options.inBitmap != null &&
                ((mTempRect.width() != unsampledInBitmapWidth
                        || mTempRect.height() != unsampledInBitmapHeight))) {
            // Need to extract the sub-bitmap
            Bitmap subBitmap = Bitmap.createBitmap(
                    bitmap, 0, 0,
                    mTempRect.width() / sampleSize,
                    mTempRect.height() / sampleSize);
            if (bitmap != options.inBitmap && bitmap != subBitmap) {
                bitmap.recycle();
            }
            bitmap = subBitmap;
        }

        if (mRotateMatrix != null) {
            // Rotate decoded bitmap
            Bitmap rotatedBitmap = Bitmap.createBitmap(
                    bitmap, 0, 0,
                    bitmap.getWidth(), bitmap.getHeight(),
                    mRotateMatrix, true);
            if ((options == null || bitmap != options.inBitmap) && bitmap != rotatedBitmap) {
                bitmap.recycle();
            }
            bitmap = rotatedBitmap;
        }

        return bitmap;
    }

    public synchronized int getWidth() {
        return (mRotation == 90 || mRotation == 270) ? mOriginalHeight : mOriginalWidth;
    }

    public synchronized int getHeight() {
        return (mRotation == 90 || mRotation == 270) ? mOriginalWidth : mOriginalHeight;
    }

    public synchronized void destroy() {
        mBitmapRegionDecoder.recycle();
        mBitmapRegionDecoder = null;
        try {
            mInputStream.close();
        } catch (IOException ignored) {
        }
    }
}




Java Source Code List

com.example.muzei.examplecontractwidget.ArtworkUpdateReceiver.java
com.example.muzei.examplecontractwidget.ArtworkUpdateService.java
com.example.muzei.examplecontractwidget.MuzeiAppWidgetProvider.java
com.example.muzei.examplesource500px.Config.java
com.example.muzei.examplesource500px.FiveHundredPxExampleArtSource.java
com.example.muzei.examplesource500px.FiveHundredPxService.java
com.example.muzei.watchface.ArtworkImageLoader.java
com.example.muzei.watchface.MuzeiExampleWatchface.java
com.example.muzei.watchface.WatchfaceArtworkImageLoader.java
com.google.android.apps.muzei.ActivateMuzeiIntentService.java
com.google.android.apps.muzei.ArtDetailViewport.java
com.google.android.apps.muzei.ArtworkCacheIntentService.java
com.google.android.apps.muzei.ArtworkCache.java
com.google.android.apps.muzei.FullScreenActivity.java
com.google.android.apps.muzei.LockScreenVisibleReceiver.java
com.google.android.apps.muzei.MuzeiActivity.java
com.google.android.apps.muzei.MuzeiApplication.java
com.google.android.apps.muzei.MuzeiWallpaperService.java
com.google.android.apps.muzei.MuzeiWatchFace.java
com.google.android.apps.muzei.MuzeiWearableListenerService.java
com.google.android.apps.muzei.MuzeiWearableListenerService.java
com.google.android.apps.muzei.NetworkChangeReceiver.java
com.google.android.apps.muzei.NewWallpaperNotificationReceiver.java
com.google.android.apps.muzei.PhotoSetAsTargetActivity.java
com.google.android.apps.muzei.SourceManager.java
com.google.android.apps.muzei.SourcePackageChangeReceiver.java
com.google.android.apps.muzei.SourceSubscriberService.java
com.google.android.apps.muzei.TaskQueueService.java
com.google.android.apps.muzei.WearableController.java
com.google.android.apps.muzei.api.Artwork.java
com.google.android.apps.muzei.api.MuzeiArtSource.java
com.google.android.apps.muzei.api.MuzeiContract.java
com.google.android.apps.muzei.api.RemoteMuzeiArtSource.java
com.google.android.apps.muzei.api.UserCommand.java
com.google.android.apps.muzei.api.internal.ProtocolConstants.java
com.google.android.apps.muzei.api.internal.SourceState.java
com.google.android.apps.muzei.event.ArtDetailOpenedClosedEvent.java
com.google.android.apps.muzei.event.ArtworkLoadingStateChangedEvent.java
com.google.android.apps.muzei.event.ArtworkSizeChangedEvent.java
com.google.android.apps.muzei.event.BlurAmountChangedEvent.java
com.google.android.apps.muzei.event.CurrentArtworkDownloadedEvent.java
com.google.android.apps.muzei.event.DimAmountChangedEvent.java
com.google.android.apps.muzei.event.GainedNetworkConnectivityEvent.java
com.google.android.apps.muzei.event.GalleryChosenUrisChangedEvent.java
com.google.android.apps.muzei.event.GreyAmountChangedEvent.java
com.google.android.apps.muzei.event.LockScreenVisibleChangedEvent.java
com.google.android.apps.muzei.event.SelectedSourceChangedEvent.java
com.google.android.apps.muzei.event.SelectedSourceStateChangedEvent.java
com.google.android.apps.muzei.event.SwitchingPhotosStateChangedEvent.java
com.google.android.apps.muzei.event.WallpaperActiveStateChangedEvent.java
com.google.android.apps.muzei.event.WallpaperSizeChangedEvent.java
com.google.android.apps.muzei.featuredart.FeaturedArtSource.java
com.google.android.apps.muzei.gallery.GalleryArtSource.java
com.google.android.apps.muzei.gallery.GalleryDatabase.java
com.google.android.apps.muzei.gallery.GalleryEmptyStateGraphicView.java
com.google.android.apps.muzei.gallery.GallerySettingsActivity.java
com.google.android.apps.muzei.gallery.GalleryStore.java
com.google.android.apps.muzei.provider.MuzeiProvider.java
com.google.android.apps.muzei.render.BitmapRegionLoader.java
com.google.android.apps.muzei.render.DemoRenderController.java
com.google.android.apps.muzei.render.GLColorOverlay.java
com.google.android.apps.muzei.render.GLPicture.java
com.google.android.apps.muzei.render.GLTextureView.java
com.google.android.apps.muzei.render.GLUtil.java
com.google.android.apps.muzei.render.ImageUtil.java
com.google.android.apps.muzei.render.MuzeiBlurRenderer.java
com.google.android.apps.muzei.render.MuzeiRendererFragment.java
com.google.android.apps.muzei.render.RealRenderController.java
com.google.android.apps.muzei.render.RenderController.java
com.google.android.apps.muzei.settings.AboutActivity.java
com.google.android.apps.muzei.settings.Prefs.java
com.google.android.apps.muzei.settings.SettingsActivity.java
com.google.android.apps.muzei.settings.SettingsAdvancedFragment.java
com.google.android.apps.muzei.settings.SettingsChooseSourceFragment.java
com.google.android.apps.muzei.util.AnimatedMuzeiLoadingSpinnerView.java
com.google.android.apps.muzei.util.AnimatedMuzeiLogoFragment.java
com.google.android.apps.muzei.util.AnimatedMuzeiLogoView.java
com.google.android.apps.muzei.util.CheatSheet.java
com.google.android.apps.muzei.util.DrawInsetsFrameLayout.java
com.google.android.apps.muzei.util.IOUtil.java
com.google.android.apps.muzei.util.ImageBlurrer.java
com.google.android.apps.muzei.util.LogUtil.java
com.google.android.apps.muzei.util.LogoPaths.java
com.google.android.apps.muzei.util.MathUtil.java
com.google.android.apps.muzei.util.MultiSelectionController.java
com.google.android.apps.muzei.util.ObservableHorizontalScrollView.java
com.google.android.apps.muzei.util.PanScaleProxyView.java
com.google.android.apps.muzei.util.PanView.java
com.google.android.apps.muzei.util.ScrimUtil.java
com.google.android.apps.muzei.util.Scrollbar.java
com.google.android.apps.muzei.util.SelectionBuilder.java
com.google.android.apps.muzei.util.ShadowDipsTextView.java
com.google.android.apps.muzei.util.SvgPathParser.java
com.google.android.apps.muzei.util.TickingFloatAnimator.java
com.google.android.apps.muzei.util.TypefaceUtil.java
com.google.android.apps.muzei.util.Zoomer.java
net.rbgrn.android.glwallpaperservice.BaseConfigChooser.java
net.rbgrn.android.glwallpaperservice.GLWallpaperService.java