/*
* 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;
}
}