/* * Copyright (C) 2015 Naman Dwivedi * * Licensed under the GNU General Public License v3 * * This is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. */ package com.wm.remusic.uitl; import android.content.ContentResolver; import android.content.ContentUris; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.ParcelFileDescriptor; import android.provider.MediaStore; import android.support.v8.renderscript.RenderScript; import android.util.Log; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; public class ImageUtils { private static final BitmapFactory.Options sBitmapOptionsCache = new BitmapFactory.Options(); private static final BitmapFactory.Options sBitmapOptions = new BitmapFactory.Options(); private static final Uri sArtworkUri = Uri .parse("content://media/external/audio/albumart"); static { // for the cache, // 565 is faster to decode and display // and we don't want to dither here because the image will be scaled // down later sBitmapOptionsCache.inPreferredConfig = Bitmap.Config.RGB_565; sBitmapOptionsCache.inDither = false; sBitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565; sBitmapOptions.inDither = false; } public static Drawable createBlurredImageFromBitmap(Bitmap bitmap, Context context, int inSampleSize) { RenderScript rs = RenderScript.create(context); final BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = inSampleSize; ByteArrayOutputStream stream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream); byte[] imageInByte = stream.toByteArray(); ByteArrayInputStream bis = new ByteArrayInputStream(imageInByte); Bitmap blurTemplate = BitmapFactory.decodeStream(bis, null, options); final android.support.v8.renderscript.Allocation input = android.support.v8.renderscript.Allocation.createFromBitmap(rs, blurTemplate); final android.support.v8.renderscript.Allocation output = android.support.v8.renderscript.Allocation.createTyped(rs, input.getType()); final android.support.v8.renderscript.ScriptIntrinsicBlur script = android.support.v8.renderscript.ScriptIntrinsicBlur.create(rs, android.support.v8.renderscript.Element.U8_4(rs)); script.setRadius(8f); script.setInput(input); script.forEach(output); output.copyTo(blurTemplate); return new BitmapDrawable(context.getResources(), blurTemplate); } public static Bitmap getBitmapFromDrawable(Drawable drawable) { final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888; final int COLORDRAWABLE_DIMENSION = 2; if (drawable == null) { return null; } if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable) drawable).getBitmap(); } try { Bitmap bitmap; if (drawable instanceof ColorDrawable) { bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG); } else { bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG); } Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } catch (OutOfMemoryError e) { return null; } } public static Bitmap getArtworkQuick(File file, int w, int h) { // NOTE: There is in fact a 1 pixel border on the right side in the // ImageView // used to display this drawable. Take it into account now, so we don't // have to // scale later. w -= 1; try { int sampleSize = 1; // Compute the closest power-of-two scale factor // and pass that to sBitmapOptionsCache.inSampleSize, which will // result in faster decoding and better quality sBitmapOptionsCache.inJustDecodeBounds = true; BitmapFactory.decodeFile(file.getAbsolutePath(), sBitmapOptionsCache); int nextWidth = sBitmapOptionsCache.outWidth >> 1; int nextHeight = sBitmapOptionsCache.outHeight >> 1; while (nextWidth > w && nextHeight > h) { sampleSize <<= 1; nextWidth >>= 1; nextHeight >>= 1; } sBitmapOptionsCache.inSampleSize = sampleSize; sBitmapOptionsCache.inJustDecodeBounds = false; Bitmap b = BitmapFactory.decodeFile(file.getAbsolutePath(), sBitmapOptionsCache); if (b != null) { // finally rescale to exactly the size we need if (sBitmapOptionsCache.outWidth != w || sBitmapOptionsCache.outHeight != h) { Bitmap tmp = Bitmap.createScaledBitmap(b, w, h, true); // Bitmap.createScaledBitmap() can return the same // bitmap if (tmp != b) b.recycle(); b = tmp; } } return b; } catch (Exception e) { e.printStackTrace(); } return null; } public static boolean isAlbumUri(Context context, Uri uri) { // NOTE: There is in fact a 1 pixel border on the right side in the // ImageView // used to display this drawable. Take it into account now, so we don't // have to // scale later. ContentResolver res = context.getContentResolver(); // Cursor cursor = res.query(uri, new String[]{}, null, null, null); // if(cursor == null){ // return null; // }else { if (uri != null) { ParcelFileDescriptor fd = null; try { fd = res.openFileDescriptor(uri, "r"); if (fd == null) { return false; } Log.e("album", "is true"); return true; } catch (FileNotFoundException e) { } finally { if (fd == null) { return false; } try { if (fd != null) fd.close(); } catch (IOException e) { } } } return false; } public static Bitmap getArtworkQuick(Context context, Uri uri, int w, int h) { // NOTE: There is in fact a 1 pixel border on the right side in the // ImageView // used to display this drawable. Take it into account now, so we don't // have to // scale later. w -= 1; ContentResolver res = context.getContentResolver(); // Cursor cursor = res.query(uri, new String[]{}, null, null, null); // if(cursor == null){ // return null; // }else { if (uri != null) { ParcelFileDescriptor fd = null; try { fd = res.openFileDescriptor(uri, "r"); if (fd == null) { return null; } int sampleSize = 1; // Compute the closest power-of-two scale factor // and pass that to sBitmapOptionsCache.inSampleSize, which will // result in faster decoding and better quality sBitmapOptionsCache.inJustDecodeBounds = true; BitmapFactory.decodeFileDescriptor(fd.getFileDescriptor(), null, sBitmapOptionsCache); int nextWidth = sBitmapOptionsCache.outWidth >> 1; int nextHeight = sBitmapOptionsCache.outHeight >> 1; while (nextWidth > w && nextHeight > h) { sampleSize <<= 1; nextWidth >>= 1; nextHeight >>= 1; } sBitmapOptionsCache.inSampleSize = sampleSize; sBitmapOptionsCache.inJustDecodeBounds = false; Bitmap b = BitmapFactory.decodeFileDescriptor( fd.getFileDescriptor(), null, sBitmapOptionsCache); if (b != null) { // finally rescale to exactly the size we need if (sBitmapOptionsCache.outWidth != w || sBitmapOptionsCache.outHeight != h) { Bitmap tmp = Bitmap.createScaledBitmap(b, w, h, true); // Bitmap.createScaledBitmap() can return the same // bitmap if (tmp != b) b.recycle(); b = tmp; } } return b; } catch (FileNotFoundException e) { } finally { try { if (fd != null) fd.close(); } catch (IOException e) { } } } return null; } /* * private static class FastBitmapDrawable extends Drawable { private Bitmap * mBitmap; public FastBitmapDrawable(Bitmap b) { mBitmap = b; } * * @Override public void draw(Canvas canvas) { canvas.drawBitmap(mBitmap, 0, * 0, null); } * * @Override public int getOpacity() { return PixelFormat.OPAQUE; } * * @Override public void setAlpha(int alpha) { } * * @Override public void setColorFilter(ColorFilter cf) { } } */ private static String[] proj_album = new String[]{MediaStore.Audio.Albums._ID, MediaStore.Audio.Albums.ALBUM_ART, MediaStore.Audio.Albums.ALBUM, MediaStore.Audio.Albums.NUMBER_OF_SONGS, MediaStore.Audio.Albums.ARTIST}; // Get album art for specified album. This method will not try to // fall back to getting artwork directly from the file, nor will // it attempt to repair the database. public static Bitmap getArtworkQuick(Context context, long album_id, int w, int h) { // NOTE: There is in fact a 1 pixel border on the right side in the // ImageView // used to display this drawable. Take it into account now, so we don't // have to // scale later. w -= 1; ContentResolver res = context.getContentResolver(); Uri uri = ContentUris.withAppendedId(sArtworkUri, album_id); // Cursor cursor = res.query(uri, new String[]{}, null, null, null); // if(cursor == null){ // return null; // }else { if (uri != null) { ParcelFileDescriptor fd = null; try { fd = res.openFileDescriptor(uri, "r"); if (fd == null) { return null; } int sampleSize = 1; // Compute the closest power-of-two scale factor // and pass that to sBitmapOptionsCache.inSampleSize, which will // result in faster decoding and better quality sBitmapOptionsCache.inJustDecodeBounds = true; BitmapFactory.decodeFileDescriptor(fd.getFileDescriptor(), null, sBitmapOptionsCache); int nextWidth = sBitmapOptionsCache.outWidth >> 1; int nextHeight = sBitmapOptionsCache.outHeight >> 1; while (nextWidth > w && nextHeight > h) { sampleSize <<= 1; nextWidth >>= 1; nextHeight >>= 1; } sBitmapOptionsCache.inSampleSize = sampleSize; sBitmapOptionsCache.inJustDecodeBounds = false; Bitmap b = BitmapFactory.decodeFileDescriptor( fd.getFileDescriptor(), null, sBitmapOptionsCache); if (b != null) { // finally rescale to exactly the size we need if (sBitmapOptionsCache.outWidth != w || sBitmapOptionsCache.outHeight != h) { Bitmap tmp = Bitmap.createScaledBitmap(b, w, h, true); // Bitmap.createScaledBitmap() can return the same // bitmap if (tmp != b) b.recycle(); b = tmp; } } return b; } catch (Exception e) { e.printStackTrace(); } finally { try { if (fd != null) fd.close(); } catch (IOException e) { } } } return null; } }