Shrink large box art down to the normal size by changing sample size

This commit is contained in:
Cameron Gutman 2017-12-27 21:28:38 -08:00
parent 31e1fb743e
commit e3a2e40043
2 changed files with 60 additions and 24 deletions

View File

@ -13,7 +13,11 @@ import java.io.OutputStream;
public class DiskAssetLoader { public class DiskAssetLoader {
// 5 MB // 5 MB
private final long MAX_ASSET_SIZE = 5 * 1024 * 1024; private static final long MAX_ASSET_SIZE = 5 * 1024 * 1024;
// Standard box art is 300x400
private static final int STANDARD_ASSET_WIDTH = 300;
private static final int STANDARD_ASSET_HEIGHT = 400;
private final File cacheDir; private final File cacheDir;
@ -25,33 +29,65 @@ public class DiskAssetLoader {
return CacheHelper.cacheFileExists(cacheDir, "boxart", tuple.computer.uuid.toString(), tuple.app.getAppId() + ".png"); return CacheHelper.cacheFileExists(cacheDir, "boxart", tuple.computer.uuid.toString(), tuple.app.getAppId() + ".png");
} }
public Bitmap loadBitmapFromCache(CachedAppAssetLoader.LoaderTuple tuple, int sampleSize) { // https://developer.android.com/topic/performance/graphics/load-bitmap.html
InputStream in = null; public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
Bitmap bmp = null; // Raw height and width of image
try { final int height = options.outHeight;
// Make sure the cached asset doesn't exceed the maximum size final int width = options.outWidth;
if (CacheHelper.getFileSize(cacheDir, "boxart", tuple.computer.uuid.toString(), tuple.app.getAppId() + ".png") > MAX_ASSET_SIZE) { int inSampleSize = 1;
LimeLog.warning("Removing cached tuple exceeding size threshold: "+tuple);
CacheHelper.deleteCacheFile(cacheDir, "boxart", tuple.computer.uuid.toString(), tuple.app.getAppId() + ".png");
return null;
}
in = CacheHelper.openCacheFileForInput(cacheDir, "boxart", tuple.computer.uuid.toString(), tuple.app.getAppId() + ".png"); if (height > reqHeight || width > reqWidth) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = sampleSize; final int halfHeight = height / 2;
options.inPreferredConfig = Bitmap.Config.RGB_565; final int halfWidth = width / 2;
bmp = BitmapFactory.decodeStream(in, null, options);
} catch (IOException ignored) { // Calculates the largest inSampleSize value that is a power of 2 and keeps both
} finally { // height and width larger than the requested height and width.
if (in != null) { while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) {
try { inSampleSize *= 2;
in.close();
} catch (IOException ignored) {}
} }
} }
return inSampleSize;
}
public Bitmap loadBitmapFromCache(CachedAppAssetLoader.LoaderTuple tuple, int sampleSize) {
File file = CacheHelper.openPath(false, cacheDir, "boxart", tuple.computer.uuid.toString(), tuple.app.getAppId() + ".png");
// Don't bother with anything if it doesn't exist
if (!file.exists()) {
return null;
}
// Make sure the cached asset doesn't exceed the maximum size
if (file.length() > MAX_ASSET_SIZE) {
LimeLog.warning("Removing cached tuple exceeding size threshold: "+tuple);
file.delete();
return null;
}
// Lookup bounds of the downloaded image
BitmapFactory.Options decodeOnlyOptions = new BitmapFactory.Options();
decodeOnlyOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(file.getAbsolutePath(), decodeOnlyOptions);
if (decodeOnlyOptions.outWidth <= 0 || decodeOnlyOptions.outHeight <= 0) {
// Dimensions set to -1 on error. Return value always null.
return null;
}
LimeLog.info("Tuple "+tuple+" has cached art of size: "+decodeOnlyOptions.outWidth+"x"+decodeOnlyOptions.outHeight);
// Load the image scaled to the appropriate size
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = calculateInSampleSize(decodeOnlyOptions,
STANDARD_ASSET_WIDTH / sampleSize,
STANDARD_ASSET_HEIGHT / sampleSize);
options.inPreferredConfig = Bitmap.Config.RGB_565;
options.inDither = true;
Bitmap bmp = BitmapFactory.decodeFile(file.getAbsolutePath(), options);
if (bmp != null) { if (bmp != null) {
LimeLog.info("Disk cache hit for tuple: "+tuple); LimeLog.info("Tuple "+tuple+" decoded from disk cache with sample size: "+options.inSampleSize);
} }
return bmp; return bmp;

View File

@ -13,7 +13,7 @@ import java.io.OutputStream;
import java.io.Reader; import java.io.Reader;
public class CacheHelper { public class CacheHelper {
private static File openPath(boolean createPath, File root, String... path) { public static File openPath(boolean createPath, File root, String... path) {
File f = root; File f = root;
for (int i = 0; i < path.length; i++) { for (int i = 0; i < path.length; i++) {
String component = path[i]; String component = path[i];