@ -18,19 +18,10 @@ package com.davemorrissey.labs.subscaleview;
import android.content.Context ;
import android.content.res.AssetManager ;
import android.graphics.Bitmap ;
import android.content.res.TypedArray ;
import android.graphics.* ;
import android.graphics.Bitmap.Config ;
import android.graphics.BitmapFactory ;
import android.graphics.BitmapRegionDecoder ;
import android.graphics.Canvas ;
import android.graphics.Color ;
import android.graphics.Matrix ;
import android.graphics.Paint ;
import android.graphics.Paint.Style ;
import android.graphics.Point ;
import android.graphics.PointF ;
import android.graphics.Rect ;
import android.graphics.RectF ;
import android.media.ExifInterface ;
import android.os.AsyncTask ;
import android.os.Build.VERSION ;
@ -45,11 +36,7 @@ import android.view.MotionEvent;
import android.view.View ;
import java.lang.ref.WeakReference ;
import java.util.ArrayList ;
import java.util.Arrays ;
import java.util.LinkedHashMap ;
import java.util.List ;
import java.util.Map ;
import java.util.* ;
/ * *
* Displays an image subsampled as necessary to avoid loading too much image data into memory . After a pinch to zoom in ,
@ -104,6 +91,13 @@ public class SubsamplingScaleImageView extends View {
private static final List < Integer > VALID_PAN_LIMITS = Arrays . asList ( PAN_LIMIT_INSIDE , PAN_LIMIT_OUTSIDE , PAN_LIMIT_CENTER ) ;
/** Scale the image so that both dimensions of the image will be equal to or less than the corresponding dimension of the view. The image is then centered in the view. This is the default behaviour and best for galleries. */
public static final int SCALE_TYPE_CENTER_INSIDE = 1 ;
/** Scale the image uniformly so that both dimensions of the image will be equal to or larger than the corresponding dimension of the view. The image is then centered in the view. */
public static final int SCALE_TYPE_CENTER_CROP = 2 ;
private static final List < Integer > VALID_SCALE_TYPES = Arrays . asList ( SCALE_TYPE_CENTER_CROP , SCALE_TYPE_CENTER_INSIDE ) ;
// Overlay tile boundaries and other info
private boolean debug = false ;
@ -119,6 +113,9 @@ public class SubsamplingScaleImageView extends View {
// Pan limiting style
private int panLimit = PAN_LIMIT_INSIDE ;
// Minimum scale type
private int minimumScaleType = SCALE_TYPE_CENTER_INSIDE ;
// Gesture detection settings
private boolean panEnabled = true ;
private boolean zoomEnabled = true ;
@ -897,12 +894,17 @@ public class SubsamplingScaleImageView extends View {
* @param center Whether the image should be centered in the dimension it ' s too small to fill . While animating this can be false to avoid changes in direction as bounds are reached .
* /
private void fitToBounds ( boolean center ) {
boolean init = false ;
if ( vTranslate = = null ) {
init = true ;
vTranslate = new PointF ( 0 , 0 ) ;
}
ScaleAndTranslate input = new ScaleAndTranslate ( scale , vTranslate ) ;
fitToBounds ( center , input ) ;
scale = input . scale ;
if ( init ) {
vTranslate = vTranslateForSCenter ( new PointF ( sWidth ( ) / 2 , sHeight ( ) / 2 ) , scale ) ;
}
}
/ * *
@ -1002,7 +1004,7 @@ public class SubsamplingScaleImageView extends View {
try {
ExifInterface exifInterface = new ExifInterface ( source ) ;
int orientationAttr = exifInterface . getAttributeInt ( ExifInterface . TAG_ORIENTATION , ExifInterface . ORIENTATION_NORMAL ) ;
if ( orientationAttr = = ExifInterface . ORIENTATION_NORMAL | | orientationAttr = = ExifInterface . ORIENTATION_UNDEFINED ) { // added undefined
if ( orientationAttr = = ExifInterface . ORIENTATION_NORMAL | | orientationAttr = = ExifInterface . ORIENTATION_UNDEFINED ) {
exifOrientation = ORIENTATION_0 ;
} else if ( orientationAttr = = ExifInterface . ORIENTATION_ROTATE_90 ) {
exifOrientation = ORIENTATION_90 ;
@ -1330,7 +1332,11 @@ public class SubsamplingScaleImageView extends View {
* Returns the minimum allowed scale .
* /
private float minScale ( ) {
if ( minimumScaleType = = SCALE_TYPE_CENTER_INSIDE ) {
return Math . min ( getWidth ( ) / ( float ) sWidth ( ) , getHeight ( ) / ( float ) sHeight ( ) ) ;
} else {
return Math . max ( getWidth ( ) / ( float ) sWidth ( ) , getHeight ( ) / ( float ) sHeight ( ) ) ;
}
}
/ * *
@ -1407,6 +1413,20 @@ public class SubsamplingScaleImageView extends View {
}
}
/ * *
* Set the minimum scale type . See static fields . Normally { @link # SCALE_TYPE_CENTER_INSIDE } is best , for image galleries .
* /
public final void setMinimumScaleType ( int scaleType ) {
if ( ! VALID_SCALE_TYPES . contains ( scaleType ) ) {
throw new IllegalArgumentException ( "Invalid scale type: " + scaleType ) ;
}
this . minimumScaleType = scaleType ;
if ( isImageReady ( ) ) {
fitToBounds ( true ) ;
invalidate ( ) ;
}
}
/ * *
* Set the maximum scale allowed . A value of 1 means 1 : 1 pixels at maximum scale . You may wish to set this according
* to screen density - on a retina screen , 1 : 1 may still be too small . Consider using { @link # setMinimumDpi ( int ) } ,