Fill empty space with blurred cover art
This commit is contained in:
parent
be1dc7d8c9
commit
b1d0e91b8a
|
@ -87,6 +87,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
|
||||||
private TextView emptyTextView;
|
private TextView emptyTextView;
|
||||||
private TextView songTitleTextView;
|
private TextView songTitleTextView;
|
||||||
private ImageView albumArtImageView;
|
private ImageView albumArtImageView;
|
||||||
|
private ImageView albumArtBackgroundView;
|
||||||
private RecyclerView playlistView;
|
private RecyclerView playlistView;
|
||||||
private TextView positionTextView;
|
private TextView positionTextView;
|
||||||
private TextView durationTextView;
|
private TextView durationTextView;
|
||||||
|
@ -151,6 +152,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
|
||||||
emptyTextView = rootView.findViewById(R.id.download_empty);
|
emptyTextView = rootView.findViewById(R.id.download_empty);
|
||||||
songTitleTextView = rootView.findViewById(R.id.download_song_title);
|
songTitleTextView = rootView.findViewById(R.id.download_song_title);
|
||||||
albumArtImageView = rootView.findViewById(R.id.download_album_art_image);
|
albumArtImageView = rootView.findViewById(R.id.download_album_art_image);
|
||||||
|
albumArtBackgroundView = rootView.findViewById(R.id.download_album_art_background);
|
||||||
positionTextView = rootView.findViewById(R.id.download_position);
|
positionTextView = rootView.findViewById(R.id.download_position);
|
||||||
durationTextView = rootView.findViewById(R.id.download_duration);
|
durationTextView = rootView.findViewById(R.id.download_duration);
|
||||||
statusTextView = rootView.findViewById(R.id.download_status);
|
statusTextView = rootView.findViewById(R.id.download_status);
|
||||||
|
@ -516,6 +518,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentPlaying == null && downloadService != null && currentPlaying == downloadService.getCurrentPlaying()) {
|
if (currentPlaying == null && downloadService != null && currentPlaying == downloadService.getCurrentPlaying()) {
|
||||||
|
getImageLoader().loadBlurImage(albumArtBackgroundView, null, true, false);
|
||||||
getImageLoader().loadImage(albumArtImageView, null, true, false);
|
getImageLoader().loadImage(albumArtImageView, null, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -804,6 +807,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
|
||||||
if (currentPlaying != null) {
|
if (currentPlaying != null) {
|
||||||
Entry song = currentPlaying.getSong();
|
Entry song = currentPlaying.getSong();
|
||||||
songTitleTextView.setText(song.getTitle());
|
songTitleTextView.setText(song.getTitle());
|
||||||
|
getImageLoader().loadBlurImage(albumArtBackgroundView, song, true, true);
|
||||||
getImageLoader().loadImage(albumArtImageView, song, true, true);
|
getImageLoader().loadImage(albumArtImageView, song, true, true);
|
||||||
|
|
||||||
DownloadService downloadService = getDownloadService();
|
DownloadService downloadService = getDownloadService();
|
||||||
|
@ -814,6 +818,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
songTitleTextView.setText(null);
|
songTitleTextView.setText(null);
|
||||||
|
getImageLoader().loadBlurImage(albumArtBackgroundView, null, true, false);
|
||||||
getImageLoader().loadImage(albumArtImageView, null, true, false);
|
getImageLoader().loadImage(albumArtImageView, null, true, false);
|
||||||
setSubtitle(null);
|
setSubtitle(null);
|
||||||
}
|
}
|
||||||
|
@ -939,6 +944,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
|
||||||
@Override
|
@Override
|
||||||
public void onMetadataUpdate(Entry song, int fieldChange) {
|
public void onMetadataUpdate(Entry song, int fieldChange) {
|
||||||
if (song != null && albumArtImageView != null && fieldChange == DownloadService.METADATA_UPDATED_COVER_ART) {
|
if (song != null && albumArtImageView != null && fieldChange == DownloadService.METADATA_UPDATED_COVER_ART) {
|
||||||
|
getImageLoader().loadBlurImage(albumArtBackgroundView, song, true, true);
|
||||||
getImageLoader().loadImage(albumArtImageView, song, true, true);
|
getImageLoader().loadImage(albumArtImageView, song, true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package net.nullsum.audinaut.util;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.renderscript.Allocation;
|
||||||
|
import android.renderscript.Element;
|
||||||
|
import android.renderscript.RenderScript;
|
||||||
|
import android.renderscript.ScriptIntrinsicBlur;
|
||||||
|
|
||||||
|
class BlurBuilder {
|
||||||
|
private static final float BITMAP_SCALE = 0.4f;
|
||||||
|
private static final float BLUR_RADIUS = 25f;
|
||||||
|
|
||||||
|
public static Bitmap blur(Context context, Bitmap image) {
|
||||||
|
int width = Math.round(image.getWidth() * BITMAP_SCALE);
|
||||||
|
int height = Math.round(image.getHeight() * BITMAP_SCALE);
|
||||||
|
|
||||||
|
Bitmap inputBitmap = Bitmap.createScaledBitmap(image, width, height, false);
|
||||||
|
Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap);
|
||||||
|
|
||||||
|
RenderScript rs = RenderScript.create(context);
|
||||||
|
ScriptIntrinsicBlur theIntrinsic = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
|
||||||
|
Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap);
|
||||||
|
Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap);
|
||||||
|
theIntrinsic.setRadius(BLUR_RADIUS);
|
||||||
|
theIntrinsic.setInput(tmpIn);
|
||||||
|
theIntrinsic.forEach(tmpOut);
|
||||||
|
tmpOut.copyTo(outputBitmap);
|
||||||
|
|
||||||
|
return outputBitmap;
|
||||||
|
}
|
||||||
|
}
|
|
@ -209,10 +209,19 @@ public class ImageLoader {
|
||||||
|
|
||||||
public SilentBackgroundTask loadImage(View view, MusicDirectory.Entry entry, boolean large, boolean crossfade) {
|
public SilentBackgroundTask loadImage(View view, MusicDirectory.Entry entry, boolean large, boolean crossfade) {
|
||||||
int size = large ? imageSizeLarge : imageSizeDefault;
|
int size = large ? imageSizeLarge : imageSizeDefault;
|
||||||
return loadImage(view, entry, large, size, crossfade);
|
return loadImage(view, entry, large, size, crossfade, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SilentBackgroundTask loadImage(View view, MusicDirectory.Entry entry, boolean large, int size, boolean crossfade) {
|
public void loadBlurImage(View view, MusicDirectory.Entry entry, boolean large, boolean crossfade) {
|
||||||
|
int size = large ? imageSizeLarge : imageSizeDefault;
|
||||||
|
loadImage(view, entry, large, size, crossfade, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadImage(View view, MusicDirectory.Entry entry, boolean large, int size, boolean crossfade) {
|
||||||
|
loadImage(view, entry, large, size, crossfade, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SilentBackgroundTask loadImage(View view, MusicDirectory.Entry entry, boolean large, int size, boolean crossfade, boolean blur) {
|
||||||
// If we know this a artist, try to load artist info instead
|
// If we know this a artist, try to load artist info instead
|
||||||
if (entry != null && !entry.isAlbum() && !Util.isOffline(context)) {
|
if (entry != null && !entry.isAlbum() && !Util.isOffline(context)) {
|
||||||
SilentBackgroundTask task = new ArtistImageTask(view.getContext(), entry, size, large, view, crossfade);
|
SilentBackgroundTask task = new ArtistImageTask(view.getContext(), entry, size, large, view, crossfade);
|
||||||
|
@ -229,12 +238,18 @@ public class ImageLoader {
|
||||||
Bitmap bitmap;
|
Bitmap bitmap;
|
||||||
if (entry == null || entry.getCoverArt() == null) {
|
if (entry == null || entry.getCoverArt() == null) {
|
||||||
bitmap = getUnknownImage(entry, size);
|
bitmap = getUnknownImage(entry, size);
|
||||||
|
if (blur) {
|
||||||
|
bitmap = BlurBuilder.blur(context, bitmap);
|
||||||
|
}
|
||||||
setImage(view, Util.createDrawableFromBitmap(context, bitmap), crossfade);
|
setImage(view, Util.createDrawableFromBitmap(context, bitmap), crossfade);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
bitmap = cache.get(getKey(entry.getCoverArt(), size));
|
bitmap = cache.get(getKey(entry.getCoverArt(), size));
|
||||||
if (bitmap != null && !bitmap.isRecycled()) {
|
if (bitmap != null && !bitmap.isRecycled()) {
|
||||||
|
if (blur) {
|
||||||
|
bitmap = BlurBuilder.blur(context, bitmap);
|
||||||
|
}
|
||||||
final Drawable drawable = Util.createDrawableFromBitmap(this.context, bitmap);
|
final Drawable drawable = Util.createDrawableFromBitmap(this.context, bitmap);
|
||||||
setImage(view, drawable, crossfade);
|
setImage(view, drawable, crossfade);
|
||||||
if (large) {
|
if (large) {
|
||||||
|
@ -246,7 +261,7 @@ public class ImageLoader {
|
||||||
if (!large) {
|
if (!large) {
|
||||||
setImage(view, null, false);
|
setImage(view, null, false);
|
||||||
}
|
}
|
||||||
ImageTask task = new ViewImageTask(view.getContext(), entry, size, large, view, crossfade);
|
ImageTask task = new ViewImageTask(view.getContext(), entry, size, large, view, crossfade, blur);
|
||||||
task.execute();
|
task.execute();
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
@ -322,14 +337,16 @@ public class ImageLoader {
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final int mSize;
|
private final int mSize;
|
||||||
private final boolean mIsNowPlaying;
|
private final boolean mIsNowPlaying;
|
||||||
|
private final boolean mBlur;
|
||||||
Drawable mDrawable;
|
Drawable mDrawable;
|
||||||
|
|
||||||
public ImageTask(Context context, MusicDirectory.Entry entry, int size, boolean isNowPlaying) {
|
public ImageTask(Context context, MusicDirectory.Entry entry, int size, boolean isNowPlaying, boolean blur) {
|
||||||
super(context);
|
super(context);
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mEntry = entry;
|
mEntry = entry;
|
||||||
mSize = size;
|
mSize = size;
|
||||||
mIsNowPlaying = isNowPlaying;
|
mIsNowPlaying = isNowPlaying;
|
||||||
|
mBlur = blur;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -348,7 +365,9 @@ public class ImageLoader {
|
||||||
} else {
|
} else {
|
||||||
bitmap = getUnknownImage(mEntry, mSize);
|
bitmap = getUnknownImage(mEntry, mSize);
|
||||||
}
|
}
|
||||||
|
if (mBlur) {
|
||||||
|
bitmap = BlurBuilder.blur(context, bitmap);
|
||||||
|
}
|
||||||
mDrawable = Util.createDrawableFromBitmap(mContext, bitmap);
|
mDrawable = Util.createDrawableFromBitmap(mContext, bitmap);
|
||||||
} catch (Throwable x) {
|
} catch (Throwable x) {
|
||||||
Log.e(TAG, "Failed to download album art.", x);
|
Log.e(TAG, "Failed to download album art.", x);
|
||||||
|
@ -363,8 +382,8 @@ public class ImageLoader {
|
||||||
final boolean mCrossfade;
|
final boolean mCrossfade;
|
||||||
private final View mView;
|
private final View mView;
|
||||||
|
|
||||||
public ViewImageTask(Context context, MusicDirectory.Entry entry, int size, boolean isNowPlaying, View view, boolean crossfade) {
|
public ViewImageTask(Context context, MusicDirectory.Entry entry, int size, boolean isNowPlaying, View view, boolean crossfade, boolean blur) {
|
||||||
super(context, entry, size, isNowPlaying);
|
super(context, entry, size, isNowPlaying, blur);
|
||||||
|
|
||||||
mView = view;
|
mView = view;
|
||||||
mCrossfade = crossfade;
|
mCrossfade = crossfade;
|
||||||
|
@ -409,7 +428,7 @@ public class ImageLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mEntry != null && mEntry.getCoverArt() != null) {
|
if (mEntry != null && mEntry.getCoverArt() != null) {
|
||||||
subTask = new ViewImageTask(mContext, mEntry, mSize, mIsNowPlaying, mView, mCrossfade);
|
subTask = new ViewImageTask(mContext, mEntry, mSize, mIsNowPlaying, mView, mCrossfade, false);
|
||||||
} else {
|
} else {
|
||||||
// If entry is null as well, we need to just set as a blank image
|
// If entry is null as well, we need to just set as a blank image
|
||||||
Bitmap bitmap = getUnknownImage(mEntry, mSize);
|
Bitmap bitmap = getUnknownImage(mEntry, mSize);
|
||||||
|
|
|
@ -20,33 +20,34 @@
|
||||||
android:background="@android:color/transparent"
|
android:background="@android:color/transparent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<FrameLayout
|
<RelativeLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_weight="1">
|
android:layout_weight="1">
|
||||||
|
|
||||||
<FrameLayout
|
<net.nullsum.audinaut.view.RecyclingImageView
|
||||||
|
android:id="@+id/download_album_art_background"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:scaleType="centerCrop" />
|
||||||
|
|
||||||
<net.nullsum.audinaut.view.RecyclingImageView
|
<net.nullsum.audinaut.view.RecyclingImageView
|
||||||
android:id="@+id/download_album_art_image"
|
android:id="@+id/download_album_art_image"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:scaleType="fitCenter" />
|
android:scaleType="fitCenter" />
|
||||||
|
|
||||||
<LinearLayout
|
</RelativeLayout>
|
||||||
android:id="@+id/download_overlay_buttons"
|
|
||||||
android:layout_width="match_parent"
|
<LinearLayout
|
||||||
android:layout_height="wrap_content"
|
android:id="@+id/download_overlay_buttons"
|
||||||
android:layout_gravity="center_horizontal|bottom"
|
android:layout_width="match_parent"
|
||||||
android:background="@color/overlayColor"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:layout_gravity="center_horizontal|bottom"
|
||||||
android:orientation="horizontal"
|
android:background="@color/overlayColor"
|
||||||
android:visibility="invisible" />
|
android:gravity="center"
|
||||||
</FrameLayout>
|
android:orientation="horizontal"
|
||||||
</FrameLayout>
|
android:visibility="invisible" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/download_status"
|
android:id="@+id/download_status"
|
||||||
|
|
Loading…
Reference in New Issue