com.exzogeni.dk.graphics.Bitmaps.java Source code

Java tutorial

Introduction

Here is the source code for com.exzogeni.dk.graphics.Bitmaps.java

Source

/*
 * Copyright (c) 2012-2014 Daniel Serdyukov
 *
 * 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.exzogeni.dk.graphics;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.media.ExifInterface;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.exzogeni.dk.io.BufferPoolInputStream;
import com.exzogeni.dk.log.Logger;

import org.apache.commons.io.IOUtils;

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

/**
 * @author Daniel Serdyukov
 */
public final class Bitmaps {

    private static final int BITMAP_HEAD = 1024;

    private static final double LN_2 = Math.log(2);

    private Bitmaps() {
    }

    @Nullable
    public static Bitmap decodeFile(@NonNull String filePath, int hwSize) {
        return decodeFile(filePath, hwSize, true);
    }

    @Nullable
    public static Bitmap decodeFile(@NonNull String filePath, int hwSize, boolean exif) {
        final Bitmap bitmap = decodeFileInternal(filePath, hwSize);
        if (bitmap != null && exif) {
            return applyExif(bitmap, filePath);
        }
        return bitmap;
    }

    @Nullable
    public static Bitmap decodeStream(@NonNull InputStream stream, int hwSize) {
        return decodeStream(stream, null, hwSize);
    }

    @Nullable
    public static Bitmap decodeStream(@NonNull InputStream stream, Rect outPadding, int hwSize) {
        if (hwSize > 0) {
            final InputStream localIn = new BufferPoolInputStream(stream);
            try {
                final BitmapFactory.Options ops = new BitmapFactory.Options();
                ops.inJustDecodeBounds = true;
                localIn.mark(BITMAP_HEAD);
                BitmapFactory.decodeStream(localIn, outPadding, ops);
                ops.inSampleSize = calculateInSampleSize(ops, hwSize);
                ops.inJustDecodeBounds = false;
                localIn.reset();
                return BitmapFactory.decodeStream(localIn, outPadding, ops);
            } catch (IOException e) {
                Logger.error(e);
            } finally {
                IOUtils.closeQuietly(localIn);
            }
            return null;
        }
        return BitmapFactory.decodeStream(stream);
    }

    public static int calculateInSampleSize(BitmapFactory.Options ops, int hwSize) {
        final int outHeight = ops.outHeight;
        final int outWidth = ops.outWidth;
        if (outWidth > hwSize || outHeight > hwSize) {
            final double ratio = Math.max(Math.round((double) outWidth / (double) hwSize),
                    Math.round((double) outHeight / (double) hwSize));
            return ratio > 0 ? (int) Math.pow(2, Math.floor(Math.log(ratio) / LN_2)) : 1;
        }
        return 1;
    }

    @Nullable
    private static Bitmap decodeFileInternal(String filePath, int hwSize) {
        if (hwSize > 0) {
            final BitmapFactory.Options ops = new BitmapFactory.Options();
            ops.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(filePath, ops);
            ops.inSampleSize = calculateInSampleSize(ops, hwSize);
            ops.inJustDecodeBounds = false;
            return BitmapFactory.decodeFile(filePath, ops);
        }
        return BitmapFactory.decodeFile(filePath);
    }

    @Nullable
    private static Bitmap applyExif(@NonNull Bitmap bitmap, String exifFilePath) {
        final int orientation = getExifOrientation(exifFilePath);
        if (orientation == ExifInterface.ORIENTATION_NORMAL || orientation == ExifInterface.ORIENTATION_UNDEFINED) {
            return bitmap;
        }
        try {
            return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),
                    getExifMatrix(orientation), true);
        } finally {
            bitmap.recycle();
        }
    }

    private static int getExifOrientation(String filePath) {
        try {
            return new ExifInterface(filePath).getAttributeInt(ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
        } catch (IOException e) {
            Logger.error(e);
        }
        return ExifInterface.ORIENTATION_UNDEFINED;
    }

    @NonNull
    private static Matrix getExifMatrix(int orientation) {
        final Matrix matrix = new Matrix();
        if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
            matrix.setRotate(180);
        } else if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
            matrix.setRotate(90);
        } else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
            matrix.setRotate(-90);
        }
        return matrix;
    }

}