233 lines
7 KiB
Java
233 lines
7 KiB
Java
package com.davemorrissey.labs.subscaleview;
|
|
|
|
import android.graphics.Bitmap;
|
|
import android.graphics.Rect;
|
|
import android.net.Uri;
|
|
|
|
import java.io.File;
|
|
import java.io.UnsupportedEncodingException;
|
|
import java.net.URLDecoder;
|
|
|
|
/**
|
|
* Helper class used to set the source and additional attributes from a variety of sources. Supports
|
|
* use of a bitmap, asset, resource, external file or any other URI.
|
|
*
|
|
* When you are using a preview image, you must set the dimensions of the full size image on the
|
|
* ImageSource object for the full size image using the {@link #dimensions(int, int)} method.
|
|
*/
|
|
public final class ImageSource {
|
|
|
|
static final String FILE_SCHEME = "file:///";
|
|
static final String ASSET_SCHEME = "file:///android_asset/";
|
|
|
|
private final Uri uri;
|
|
private final Bitmap bitmap;
|
|
private final Integer resource;
|
|
private boolean tile;
|
|
private int sWidth;
|
|
private int sHeight;
|
|
private Rect sRegion;
|
|
private boolean cached;
|
|
|
|
private ImageSource(Bitmap bitmap, boolean cached) {
|
|
this.bitmap = bitmap;
|
|
this.uri = null;
|
|
this.resource = null;
|
|
this.tile = false;
|
|
this.sWidth = bitmap.getWidth();
|
|
this.sHeight = bitmap.getHeight();
|
|
this.cached = cached;
|
|
}
|
|
|
|
private ImageSource(Uri uri) {
|
|
// #114 If file doesn't exist, attempt to url decode the URI and try again
|
|
String uriString = uri.toString();
|
|
if (uriString.startsWith(FILE_SCHEME)) {
|
|
File uriFile = new File(uriString.substring(FILE_SCHEME.length() - 1));
|
|
if (!uriFile.exists()) {
|
|
try {
|
|
uri = Uri.parse(URLDecoder.decode(uriString, "UTF-8"));
|
|
} catch (UnsupportedEncodingException e) {
|
|
// Fallback to encoded URI. This exception is not expected.
|
|
}
|
|
}
|
|
}
|
|
this.bitmap = null;
|
|
this.uri = uri;
|
|
this.resource = null;
|
|
this.tile = true;
|
|
}
|
|
|
|
private ImageSource(int resource) {
|
|
this.bitmap = null;
|
|
this.uri = null;
|
|
this.resource = resource;
|
|
this.tile = true;
|
|
}
|
|
|
|
/**
|
|
* Create an instance from a resource. The correct resource for the device screen resolution will be used.
|
|
* @param resId resource ID.
|
|
*/
|
|
public static ImageSource resource(int resId) {
|
|
return new ImageSource(resId);
|
|
}
|
|
|
|
/**
|
|
* Create an instance from an asset name.
|
|
* @param assetName asset name.
|
|
*/
|
|
public static ImageSource asset(String assetName) {
|
|
if (assetName == null) {
|
|
throw new NullPointerException("Asset name must not be null");
|
|
}
|
|
return uri(ASSET_SCHEME + assetName);
|
|
}
|
|
|
|
/**
|
|
* Create an instance from a URI. If the URI does not start with a scheme, it's assumed to be the URI
|
|
* of a file.
|
|
* @param uri image URI.
|
|
*/
|
|
public static ImageSource uri(String uri) {
|
|
if (uri == null) {
|
|
throw new NullPointerException("Uri must not be null");
|
|
}
|
|
if (!uri.contains("://")) {
|
|
if (uri.startsWith("/")) {
|
|
uri = uri.substring(1);
|
|
}
|
|
uri = FILE_SCHEME + uri;
|
|
}
|
|
return new ImageSource(Uri.parse(uri));
|
|
}
|
|
|
|
/**
|
|
* Create an instance from a URI.
|
|
* @param uri image URI.
|
|
*/
|
|
public static ImageSource uri(Uri uri) {
|
|
if (uri == null) {
|
|
throw new NullPointerException("Uri must not be null");
|
|
}
|
|
return new ImageSource(uri);
|
|
}
|
|
|
|
/**
|
|
* Provide a loaded bitmap for display.
|
|
* @param bitmap bitmap to be displayed.
|
|
*/
|
|
public static ImageSource bitmap(Bitmap bitmap) {
|
|
if (bitmap == null) {
|
|
throw new NullPointerException("Bitmap must not be null");
|
|
}
|
|
return new ImageSource(bitmap, false);
|
|
}
|
|
|
|
/**
|
|
* Provide a loaded and cached bitmap for display. This bitmap will not be recycled when it is no
|
|
* longer needed. Use this method if you loaded the bitmap with an image loader such as Picasso
|
|
* or Volley.
|
|
* @param bitmap bitmap to be displayed.
|
|
*/
|
|
public static ImageSource cachedBitmap(Bitmap bitmap) {
|
|
if (bitmap == null) {
|
|
throw new NullPointerException("Bitmap must not be null");
|
|
}
|
|
return new ImageSource(bitmap, true);
|
|
}
|
|
|
|
/**
|
|
* Enable tiling of the image. This does not apply to preview images which are always loaded as a single bitmap.,
|
|
* and tiling cannot be disabled when displaying a region of the source image.
|
|
* @return this instance for chaining.
|
|
*/
|
|
public ImageSource tilingEnabled() {
|
|
return tiling(true);
|
|
}
|
|
|
|
/**
|
|
* Disable tiling of the image. This does not apply to preview images which are always loaded as a single bitmap,
|
|
* and tiling cannot be disabled when displaying a region of the source image.
|
|
* @return this instance for chaining.
|
|
*/
|
|
public ImageSource tilingDisabled() {
|
|
return tiling(false);
|
|
}
|
|
|
|
/**
|
|
* Enable or disable tiling of the image. This does not apply to preview images which are always loaded as a single bitmap,
|
|
* and tiling cannot be disabled when displaying a region of the source image.
|
|
* @return this instance for chaining.
|
|
*/
|
|
public ImageSource tiling(boolean tile) {
|
|
this.tile = tile;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Use a region of the source image. Region must be set independently for the full size image and the preview if
|
|
* you are using one.
|
|
* @return this instance for chaining.
|
|
*/
|
|
public ImageSource region(Rect sRegion) {
|
|
this.sRegion = sRegion;
|
|
setInvariants();
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Declare the dimensions of the image. This is only required for a full size image, when you are specifying a URI
|
|
* and also a preview image. When displaying a bitmap object, or not using a preview, you do not need to declare
|
|
* the image dimensions. Note if the declared dimensions are found to be incorrect, the view will reset.
|
|
* @return this instance for chaining.
|
|
*/
|
|
public ImageSource dimensions(int sWidth, int sHeight) {
|
|
if (bitmap == null) {
|
|
this.sWidth = sWidth;
|
|
this.sHeight = sHeight;
|
|
}
|
|
setInvariants();
|
|
return this;
|
|
}
|
|
|
|
private void setInvariants() {
|
|
if (this.sRegion != null) {
|
|
this.tile = true;
|
|
this.sWidth = this.sRegion.width();
|
|
this.sHeight = this.sRegion.height();
|
|
}
|
|
}
|
|
|
|
protected final Uri getUri() {
|
|
return uri;
|
|
}
|
|
|
|
protected final Bitmap getBitmap() {
|
|
return bitmap;
|
|
}
|
|
|
|
protected final Integer getResource() {
|
|
return resource;
|
|
}
|
|
|
|
protected final boolean getTile() {
|
|
return tile;
|
|
}
|
|
|
|
protected final int getSWidth() {
|
|
return sWidth;
|
|
}
|
|
|
|
protected final int getSHeight() {
|
|
return sHeight;
|
|
}
|
|
|
|
protected final Rect getSRegion() {
|
|
return sRegion;
|
|
}
|
|
|
|
protected final boolean isCached() {
|
|
return cached;
|
|
}
|
|
}
|