package com.boardgamegeek.util;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.support.v7.graphics.Palette;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.boardgamegeek.R;
import com.squareup.picasso.Picasso;
import java.util.LinkedList;
import java.util.Queue;
/**
* Loading images? This is your huckleberry.
*/
public class ImageUtils {
private static final String IMAGE_URL_PREFIX = "https://cf.geekdo-images.com/images/pic";
//public static final String SUFFIX_SMALL_THUMBNAIL = "_mt";
public static final String SUFFIX_THUMBNAIL = "_t";
//private static final String SUFFIX_SQUARE = "_sq";
public static final String SUFFIX_SMALL = "_t";
public static final String SUFFIX_MEDIUM = "_md";
//private static final String SUFFIX_LARGE = "_lg";
private static final float IMAGE_ASPECT_RATIO = 1.6777777f;
private ImageUtils() {
}
/**
* Create a URL for a thumbnail image as a JPG.
*/
public static String createThumbnailJpgUrl(int imageId) {
return IMAGE_URL_PREFIX + imageId + SUFFIX_SMALL + ".jpg";
}
/**
* Create a URL for a thumbnail image as a PNG.
*/
public static String createThumbnailPngUrl(int imageId) {
return IMAGE_URL_PREFIX + imageId + SUFFIX_SMALL + ".png";
}
/**
* Loads an image into the {@link android.widget.ImageView} by attempting various sizes and image formats. Applies
* fit/center crop and will load a {@link android.support.v7.graphics.Palette}.
*/
public static void safelyLoadImage(ImageView imageView, int imageId, Callback callback) {
Queue<String> imageUrls = new LinkedList<>();
String imageUrl = IMAGE_URL_PREFIX + imageId + ".jpg";
imageUrls.add(appendImageUrl(imageUrl, SUFFIX_MEDIUM));
imageUrls.add(appendImageUrl(imageUrl, SUFFIX_SMALL));
imageUrls.add(imageUrl);
imageUrl = IMAGE_URL_PREFIX + imageId + ".png";
imageUrls.add(appendImageUrl(imageUrl, SUFFIX_MEDIUM));
imageUrls.add(appendImageUrl(imageUrl, SUFFIX_SMALL));
imageUrls.add(imageUrl);
safelyLoadImage(imageView, imageUrls, callback);
}
/**
* Loads an image into the {@link android.widget.ImageView} by attempting various sizes. Applies fit/center crop.
*/
public static void safelyLoadImage(ImageView imageView, String imageUrl) {
safelyLoadImage(imageView, imageUrl, null);
}
/**
* Loads an image into the {@link android.widget.ImageView} by attempting various sizes. Applies fit/center crop and
* will load a {@link android.support.v7.graphics.Palette}.
*/
public static void safelyLoadImage(ImageView imageView, String imageUrl, Callback callback) {
Queue<String> imageUrls = new LinkedList<>();
imageUrls.add(appendImageUrl(imageUrl, SUFFIX_MEDIUM));
imageUrls.add(appendImageUrl(imageUrl, SUFFIX_SMALL));
imageUrls.add(imageUrl);
safelyLoadImage(imageView, imageUrls, callback);
}
/**
* Loads an image into the {@link android.widget.ImageView} by attempting each URL in the {@link java.util.Queue}
* until one is successful. Applies fit/center crop and will load a {@link android.support.v7.graphics.Palette}.
*/
private static void safelyLoadImage(final ImageView imageView,
final Queue<String> imageUrls,
final Callback callback) {
String imageUrl = imageUrls.poll();
if (TextUtils.isEmpty(imageUrl)) {
if (callback != null) {
callback.onFailedImageLoad();
}
return;
}
Picasso
.with(imageView.getContext())
.load(HttpUtils.ensureScheme(imageUrl))
.transform(PaletteTransformation.instance())
.into(imageView, new com.squareup.picasso.Callback() {
@Override
public void onSuccess() {
Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
Palette palette = PaletteTransformation.getPalette(bitmap);
if (callback != null) {
callback.onSuccessfulImageLoad(palette);
}
}
@Override
public void onError() {
safelyLoadImage(imageView, imageUrls, callback);
}
});
}
/**
* Append a suffix to an image URL. Assumes the URL has no suffix (but may have an extension or not.
*/
public static String appendImageUrl(String imageUrl, String suffix) {
if (TextUtils.isEmpty(imageUrl)) {
return "";
}
if (TextUtils.isEmpty(suffix)) {
return imageUrl;
}
int dot = imageUrl.lastIndexOf('.');
if (dot == -1) {
return imageUrl + suffix;
} else {
return imageUrl.substring(0, dot) + suffix + imageUrl.substring(dot, imageUrl.length());
}
}
/**
* Resize the resizableView based on a standard aspect ratio, up to a maximum height
*/
public static void resizeImagePerAspectRatio(View image, int maxHeight, View resizableView) {
if (image == null) return;
if (resizableView == null) return;
int height = (int) (image.getWidth() / IMAGE_ASPECT_RATIO);
height = Math.min(height, maxHeight);
ViewGroup.LayoutParams lp;
lp = resizableView.getLayoutParams();
if (lp.height != height) {
lp.height = height;
resizableView.setLayoutParams(lp);
}
}
/**
* Call back from loading an image.
*/
public interface Callback {
void onSuccessfulImageLoad(Palette palette);
void onFailedImageLoad();
}
public static void loadThumbnail(int imageId, ImageView target) {
Queue<String> queue = new LinkedList<>();
queue.add(ImageUtils.createThumbnailJpgUrl(imageId));
queue.add(ImageUtils.createThumbnailPngUrl(imageId));
safelyLoadThumbnail(target, queue);
}
public static void loadThumbnail(String path, ImageView target) {
Queue<String> queue = new LinkedList<>();
queue.add(path);
safelyLoadThumbnail(target, queue);
}
private static void safelyLoadThumbnail(final ImageView imageView, final Queue<String> imageUrls) {
final String imageUrl = imageUrls.poll();
if (TextUtils.isEmpty(imageUrl)) {
return;
}
Picasso.with(imageView.getContext())
.load(HttpUtils.ensureScheme(imageUrl))
.placeholder(R.drawable.thumbnail_image_empty)
.error(R.drawable.thumbnail_image_empty)
.resizeDimen(R.dimen.thumbnail_list_size, R.dimen.thumbnail_list_size)
.centerCrop()
.into(imageView, new com.squareup.picasso.Callback() {
@Override
public void onSuccess() {
}
@Override
public void onError() {
safelyLoadThumbnail(imageView, imageUrls);
}
});
}
}