From 5c81265be07c6991761dcf5baae7e9464571eeb2 Mon Sep 17 00:00:00 2001 From: Scott Jackson Date: Mon, 6 Jan 2014 19:54:52 -0800 Subject: #192 Merge high quality artwork from archrival --- .../dsub/service/CachedMusicService.java | 4 +-- .../daneren2005/dsub/service/DownloadFile.java | 2 +- .../daneren2005/dsub/service/MusicService.java | 2 +- .../dsub/service/OfflineMusicService.java | 2 +- .../daneren2005/dsub/service/RESTMusicService.java | 13 +++----- src/github/daneren2005/dsub/util/FileUtil.java | 25 +++++++++++++-- src/github/daneren2005/dsub/util/ImageLoader.java | 2 +- src/github/daneren2005/dsub/util/Util.java | 37 ++++++++++++++++++++++ 8 files changed, 69 insertions(+), 18 deletions(-) diff --git a/src/github/daneren2005/dsub/service/CachedMusicService.java b/src/github/daneren2005/dsub/service/CachedMusicService.java index 21c2ae68..b8bdf94c 100644 --- a/src/github/daneren2005/dsub/service/CachedMusicService.java +++ b/src/github/daneren2005/dsub/service/CachedMusicService.java @@ -253,8 +253,8 @@ public class CachedMusicService implements MusicService { } @Override - public Bitmap getCoverArt(Context context, MusicDirectory.Entry entry, int size, int saveSize, ProgressListener progressListener) throws Exception { - return musicService.getCoverArt(context, entry, size, saveSize, progressListener); + public Bitmap getCoverArt(Context context, MusicDirectory.Entry entry, int size, ProgressListener progressListener) throws Exception { + return musicService.getCoverArt(context, entry, size, progressListener); } @Override diff --git a/src/github/daneren2005/dsub/service/DownloadFile.java b/src/github/daneren2005/dsub/service/DownloadFile.java index f0b3d802..27fc0708 100644 --- a/src/github/daneren2005/dsub/service/DownloadFile.java +++ b/src/github/daneren2005/dsub/service/DownloadFile.java @@ -399,7 +399,7 @@ public class DownloadFile { if (song.getCoverArt() != null) { DisplayMetrics metrics = context.getResources().getDisplayMetrics(); int size = Math.min(metrics.widthPixels, metrics.heightPixels); - musicService.getCoverArt(context, song, size, size, null); + musicService.getCoverArt(context, song, size, null); } } catch (Exception x) { Log.e(TAG, "Failed to get cover art.", x); diff --git a/src/github/daneren2005/dsub/service/MusicService.java b/src/github/daneren2005/dsub/service/MusicService.java index 7e19e49e..0946c4f7 100644 --- a/src/github/daneren2005/dsub/service/MusicService.java +++ b/src/github/daneren2005/dsub/service/MusicService.java @@ -87,7 +87,7 @@ public interface MusicService { MusicDirectory getRandomSongs(int size, String folder, String genre, String startYear, String endYear, Context context, ProgressListener progressListener) throws Exception; - Bitmap getCoverArt(Context context, MusicDirectory.Entry entry, int size, int saveSize, ProgressListener progressListener) throws Exception; + Bitmap getCoverArt(Context context, MusicDirectory.Entry entry, int size, ProgressListener progressListener) throws Exception; HttpResponse getDownloadInputStream(Context context, MusicDirectory.Entry song, long offset, int maxBitrate, CancellableTask task) throws Exception; diff --git a/src/github/daneren2005/dsub/service/OfflineMusicService.java b/src/github/daneren2005/dsub/service/OfflineMusicService.java index 0f6f0126..80ad375a 100644 --- a/src/github/daneren2005/dsub/service/OfflineMusicService.java +++ b/src/github/daneren2005/dsub/service/OfflineMusicService.java @@ -201,7 +201,7 @@ public class OfflineMusicService extends RESTMusicService { } @Override - public Bitmap getCoverArt(Context context, MusicDirectory.Entry entry, int size, int saveSize, ProgressListener progressListener) throws Exception { + public Bitmap getCoverArt(Context context, MusicDirectory.Entry entry, int size, ProgressListener progressListener) throws Exception { try { return FileUtil.getAlbumArtBitmap(context, entry, size); } catch(Exception e) { diff --git a/src/github/daneren2005/dsub/service/RESTMusicService.java b/src/github/daneren2005/dsub/service/RESTMusicService.java index c5438267..e220bf59 100644 --- a/src/github/daneren2005/dsub/service/RESTMusicService.java +++ b/src/github/daneren2005/dsub/service/RESTMusicService.java @@ -626,7 +626,7 @@ public class RESTMusicService implements MusicService { } @Override - public Bitmap getCoverArt(Context context, MusicDirectory.Entry entry, int size, int saveSize, ProgressListener progressListener) throws Exception { + public Bitmap getCoverArt(Context context, MusicDirectory.Entry entry, int size, ProgressListener progressListener) throws Exception { // Synchronize on the entry so that we don't download concurrently for the same song. synchronized (entry) { @@ -641,8 +641,8 @@ public class RESTMusicService implements MusicService { InputStream in = null; try { - List parameterNames = Arrays.asList("id", "size"); - List parameterValues = Arrays.asList(entry.getCoverArt(), saveSize); + List parameterNames = Arrays.asList("id"); + List parameterValues = Arrays.asList(entry.getCoverArt()); HttpEntity entity = getEntityForURL(context, url, null, parameterNames, parameterValues, progressListener); in = entity.getContent(); @@ -662,12 +662,7 @@ public class RESTMusicService implements MusicService { Util.close(out); } - bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); - if(size != saveSize) { - bitmap = Bitmap.createScaledBitmap(bitmap, size, size, true); - } - return bitmap; - + return FileUtil.getSampledBitmap(bytes, size); } finally { Util.close(in); } diff --git a/src/github/daneren2005/dsub/util/FileUtil.java b/src/github/daneren2005/dsub/util/FileUtil.java index ebd2e8b9..8ee8d0ba 100644 --- a/src/github/daneren2005/dsub/util/FileUtil.java +++ b/src/github/daneren2005/dsub/util/FileUtil.java @@ -162,13 +162,32 @@ public class FileUtil { public static Bitmap getAlbumArtBitmap(Context context, MusicDirectory.Entry entry, int size) { File albumArtFile = getAlbumArtFile(context, entry); - Log.d(TAG, albumArtFile.toString()); if (albumArtFile.exists()) { - Bitmap bitmap = BitmapFactory.decodeFile(albumArtFile.getPath()); - return (bitmap == null) ? null : Bitmap.createScaledBitmap(bitmap, size, size, true); + final BitmapFactory.Options opt = new BitmapFactory.Options(); + opt.inJustDecodeBounds = true; + BitmapFactory.decodeFile(albumArtFile.getPath(), opt); + opt.inPurgeable = true; + opt.inSampleSize = Util.calculateInSampleSize(opt, size, Util.getScaledHeight(opt.outHeight, opt.outWidth, size)); + opt.inJustDecodeBounds = false; + + Bitmap bitmap = BitmapFactory.decodeFile(albumArtFile.getPath(), opt); + return bitmap == null ? null : getScaledBitmap(bitmap, size); } return null; } + public static Bitmap getSampledBitmap(byte[] bytes, int size) { + final BitmapFactory.Options opt = new BitmapFactory.Options(); + opt.inJustDecodeBounds = true; + BitmapFactory.decodeByteArray(bytes, 0, bytes.length, opt); + opt.inPurgeable = true; + opt.inSampleSize = Util.calculateInSampleSize(opt, size, Util.getScaledHeight(opt.outHeight, opt.outWidth, size)); + opt.inJustDecodeBounds = false; + Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, opt); + return getScaledBitmap(bitmap, size); + } + public static Bitmap getScaledBitmap(Bitmap bitmap, int size) { + return Bitmap.createScaledBitmap(bitmap, size, Util.getScaledHeight(bitmap, size), true); + } public static File getAlbumArtDirectory() { File albumArtDir = new File(getSubsonicDirectory(), "artwork"); diff --git a/src/github/daneren2005/dsub/util/ImageLoader.java b/src/github/daneren2005/dsub/util/ImageLoader.java index e7323176..82c4c5d0 100644 --- a/src/github/daneren2005/dsub/util/ImageLoader.java +++ b/src/github/daneren2005/dsub/util/ImageLoader.java @@ -278,7 +278,7 @@ public class ImageLoader implements Runnable { public void loadImage() { try { MusicService musicService = MusicServiceFactory.getMusicService(mContext); - Bitmap bitmap = musicService.getCoverArt(mContext, mEntry, mSize, mSaveSize, null); + Bitmap bitmap = musicService.getCoverArt(mContext, mEntry, mSize, null); String key = getKey(mEntry.getCoverArt(), mSize); cache.put(key, bitmap); // Make sure key is the most recently "used" diff --git a/src/github/daneren2005/dsub/util/Util.java b/src/github/daneren2005/dsub/util/Util.java index b0a2c3b1..51e64686 100644 --- a/src/github/daneren2005/dsub/util/Util.java +++ b/src/github/daneren2005/dsub/util/Util.java @@ -31,6 +31,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Resources; import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.media.AudioManager; @@ -794,6 +795,42 @@ public final class Util { return string == null || "".equals(string) || "".equals(string.trim()); } + public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { + // Raw height and width of image + final int height = options.outHeight; + final int width = options.outWidth; + int inSampleSize = 1; + + if (height > reqHeight || width > reqWidth) { + + // Calculate ratios of height and width to requested height and + // width + final int heightRatio = Math.round((float) height / (float) reqHeight); + final int widthRatio = Math.round((float) width / (float) reqWidth); + + // Choose the smallest ratio as inSampleSize value, this will + // guarantee + // a final image with both dimensions larger than or equal to the + // requested height and width. + inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; + } + + return inSampleSize; + } + + public static int getScaledHeight(double height, double width, int newWidth) { + // Try to keep correct aspect ratio of the original image, do not force a square + double aspectRatio = height / width; + + // Assume the size given refers to the width of the image, so calculate the new height using + // the previously determined aspect ratio + return (int) Math.round(newWidth * aspectRatio); + } + + public static int getScaledHeight(Bitmap bitmap, int width) { + return Util.getScaledHeight((double) bitmap.getHeight(), (double) bitmap.getWidth(), width); + } + public static boolean isNetworkConnected(Context context) { ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = manager.getActiveNetworkInfo(); -- cgit v1.2.3