aboutsummaryrefslogtreecommitdiff
path: root/subsonic-android/src/net/sourceforge/subsonic/androidapp/util/ImageLoader.java
diff options
context:
space:
mode:
authorScott Jackson <daneren2005@gmail.com>2012-07-07 08:29:52 -0700
committerScott Jackson <daneren2005@gmail.com>2012-07-07 08:29:52 -0700
commit6ebae86dfbb7fa79d81e6b2485f395eeab7267ef (patch)
treebc26b39df3c6a666bcac960042f2ac8cb06ad202 /subsonic-android/src/net/sourceforge/subsonic/androidapp/util/ImageLoader.java
parent8a7bb33f73d4fab1e380adf972efc2f3a7ee8b3e (diff)
downloaddsub-6ebae86dfbb7fa79d81e6b2485f395eeab7267ef.tar.gz
dsub-6ebae86dfbb7fa79d81e6b2485f395eeab7267ef.tar.bz2
dsub-6ebae86dfbb7fa79d81e6b2485f395eeab7267ef.zip
Changed project package to github.daneren2005.subphonic
Diffstat (limited to 'subsonic-android/src/net/sourceforge/subsonic/androidapp/util/ImageLoader.java')
-rw-r--r--subsonic-android/src/net/sourceforge/subsonic/androidapp/util/ImageLoader.java252
1 files changed, 0 insertions, 252 deletions
diff --git a/subsonic-android/src/net/sourceforge/subsonic/androidapp/util/ImageLoader.java b/subsonic-android/src/net/sourceforge/subsonic/androidapp/util/ImageLoader.java
deleted file mode 100644
index 5cbd8c9f..00000000
--- a/subsonic-android/src/net/sourceforge/subsonic/androidapp/util/ImageLoader.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic 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.
-
- Subsonic 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.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.androidapp.util;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.LinearGradient;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.Shader;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.TransitionDrawable;
-import android.os.Handler;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-import net.sourceforge.subsonic.androidapp.R;
-import net.sourceforge.subsonic.androidapp.domain.MusicDirectory;
-import net.sourceforge.subsonic.androidapp.service.MusicService;
-import net.sourceforge.subsonic.androidapp.service.MusicServiceFactory;
-
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-
-/**
- * Asynchronous loading of images, with caching.
- * <p/>
- * There should normally be only one instance of this class.
- *
- * @author Sindre Mehus
- */
-public class ImageLoader implements Runnable {
-
- private static final String TAG = ImageLoader.class.getSimpleName();
- private static final int CONCURRENCY = 5;
-
- private final LRUCache<String, Drawable> cache = new LRUCache<String, Drawable>(100);
- private final BlockingQueue<Task> queue;
- private final int imageSizeDefault;
- private final int imageSizeLarge;
- private Drawable largeUnknownImage;
-
- public ImageLoader(Context context) {
- queue = new LinkedBlockingQueue<Task>(500);
-
- // Determine the density-dependent image sizes.
- imageSizeDefault = context.getResources().getDrawable(R.drawable.unknown_album).getIntrinsicHeight();
- DisplayMetrics metrics = context.getResources().getDisplayMetrics();
- imageSizeLarge = (int) Math.round(Math.min(metrics.widthPixels, metrics.heightPixels) * 0.6);
-
- for (int i = 0; i < CONCURRENCY; i++) {
- new Thread(this, "ImageLoader").start();
- }
-
- createLargeUnknownImage(context);
- }
-
- private void createLargeUnknownImage(Context context) {
- BitmapDrawable drawable = (BitmapDrawable) context.getResources().getDrawable(R.drawable.unknown_album_large);
- Bitmap bitmap = Bitmap.createScaledBitmap(drawable.getBitmap(), imageSizeLarge, imageSizeLarge, true);
- bitmap = createReflection(bitmap);
- largeUnknownImage = Util.createDrawableFromBitmap(context, bitmap);
- }
-
- public void loadImage(View view, MusicDirectory.Entry entry, boolean large, boolean crossfade) {
- if (entry == null || entry.getCoverArt() == null) {
- setUnknownImage(view, large);
- return;
- }
-
- int size = large ? imageSizeLarge : imageSizeDefault;
- Drawable drawable = cache.get(getKey(entry.getCoverArt(), size));
- if (drawable != null) {
- setImage(view, drawable, large);
- return;
- }
-
- if (!large) {
- setUnknownImage(view, large);
- }
- queue.offer(new Task(view, entry, size, large, large, crossfade));
- }
-
- private String getKey(String coverArtId, int size) {
- return coverArtId + size;
- }
-
- private void setImage(View view, Drawable drawable, boolean crossfade) {
- if (view instanceof TextView) {
- // Cross-fading is not implemented for TextView since it's not in use. It would be easy to add it, though.
- TextView textView = (TextView) view;
- textView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);
- } else if (view instanceof ImageView) {
- ImageView imageView = (ImageView) view;
- if (crossfade) {
-
- Drawable existingDrawable = imageView.getDrawable();
- if (existingDrawable == null) {
- Bitmap emptyImage = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
- existingDrawable = new BitmapDrawable(emptyImage);
- }
-
- Drawable[] layers = new Drawable[]{existingDrawable, drawable};
-
- TransitionDrawable transitionDrawable = new TransitionDrawable(layers);
- imageView.setImageDrawable(transitionDrawable);
- transitionDrawable.startTransition(250);
- } else {
- imageView.setImageDrawable(drawable);
- }
- }
- }
-
- private void setUnknownImage(View view, boolean large) {
- if (large) {
- setImage(view, largeUnknownImage, false);
- } else {
- if (view instanceof TextView) {
- ((TextView) view).setCompoundDrawablesWithIntrinsicBounds(R.drawable.unknown_album, 0, 0, 0);
- } else if (view instanceof ImageView) {
- ((ImageView) view).setImageResource(R.drawable.unknown_album);
- }
- }
- }
-
- public void clear() {
- queue.clear();
- }
-
- @Override
- public void run() {
- while (true) {
- try {
- Task task = queue.take();
- task.execute();
- } catch (Throwable x) {
- Log.e(TAG, "Unexpected exception in ImageLoader.", x);
- }
- }
- }
-
- private Bitmap createReflection(Bitmap originalImage) {
-
- int width = originalImage.getWidth();
- int height = originalImage.getHeight();
-
- // The gap we want between the reflection and the original image
- final int reflectionGap = 4;
-
- // This will not scale but will flip on the Y axis
- Matrix matrix = new Matrix();
- matrix.preScale(1, -1);
-
- // Create a Bitmap with the flip matix applied to it.
- // We only want the bottom half of the image
- Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0, height / 2, width, height / 2, matrix, false);
-
- // Create a new bitmap with same width but taller to fit reflection
- Bitmap bitmapWithReflection = Bitmap.createBitmap(width, (height + height / 2), Bitmap.Config.ARGB_8888);
-
- // Create a new Canvas with the bitmap that's big enough for
- // the image plus gap plus reflection
- Canvas canvas = new Canvas(bitmapWithReflection);
-
- // Draw in the original image
- canvas.drawBitmap(originalImage, 0, 0, null);
-
- // Draw in the gap
- Paint defaultPaint = new Paint();
- canvas.drawRect(0, height, width, height + reflectionGap, defaultPaint);
-
- // Draw in the reflection
- canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
-
- // Create a shader that is a linear gradient that covers the reflection
- Paint paint = new Paint();
- LinearGradient shader = new LinearGradient(0, originalImage.getHeight(), 0,
- bitmapWithReflection.getHeight() + reflectionGap, 0x70000000, 0xff000000,
- Shader.TileMode.CLAMP);
-
- // Set the paint to use this shader (linear gradient)
- paint.setShader(shader);
-
- // Draw a rectangle using the paint with our linear gradient
- canvas.drawRect(0, height, width, bitmapWithReflection.getHeight() + reflectionGap, paint);
-
- return bitmapWithReflection;
- }
-
- private class Task {
- private final View view;
- private final MusicDirectory.Entry entry;
- private final Handler handler;
- private final int size;
- private final boolean reflection;
- private final boolean saveToFile;
- private final boolean crossfade;
-
- public Task(View view, MusicDirectory.Entry entry, int size, boolean reflection, boolean saveToFile, boolean crossfade) {
- this.view = view;
- this.entry = entry;
- this.size = size;
- this.reflection = reflection;
- this.saveToFile = saveToFile;
- this.crossfade = crossfade;
- handler = new Handler();
- }
-
- public void execute() {
- try {
- MusicService musicService = MusicServiceFactory.getMusicService(view.getContext());
- Bitmap bitmap = musicService.getCoverArt(view.getContext(), entry, size, saveToFile, null);
-
- if (reflection) {
- bitmap = createReflection(bitmap);
- }
-
- final Drawable drawable = Util.createDrawableFromBitmap(view.getContext(), bitmap);
- cache.put(getKey(entry.getCoverArt(), size), drawable);
-
- handler.post(new Runnable() {
- @Override
- public void run() {
- setImage(view, drawable, crossfade);
- }
- });
- } catch (Throwable x) {
- Log.e(TAG, "Failed to download album art.", x);
- }
- }
- }
-}