Skip to content

Commit

Permalink
Restored matrix tile rotation using setPolyToPoly to eliminate roundi…
Browse files Browse the repository at this point in the history
…ng errors that caused apps. Fixed a few leftover bits from recent refactoring.
  • Loading branch information
davemorrissey committed Mar 24, 2015
1 parent 4f6ee1c commit 83203e9
Showing 1 changed file with 47 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ public class SubsamplingScaleImageView extends View {
private ScaleAndTranslate satTemp;
private Matrix matrix;
private RectF sRect;
private float[] srcArray = new float[8];
private float[] dstArray = new float[8];

public SubsamplingScaleImageView(Context context, AttributeSet attr) {
super(context, attr);
Expand Down Expand Up @@ -347,7 +349,7 @@ public final void setImage(ImageSource imageSource, ImageSource previewSource, I
reset(true);
if (state != null) { restoreState(state); }

if (previewSource != null && imageSource.getSWidth() > 0 && imageSource.getSHeight() > 0) {
if (previewSource != null) {
if (imageSource.getBitmap() != null) {
throw new IllegalArgumentException("Preview image cannot be used when a bitmap is provided for the main image");
}
Expand Down Expand Up @@ -886,7 +888,20 @@ protected void onDraw(Canvas canvas) {
if (tileBgPaint != null) {
canvas.drawRect(tile.vRect, tileBgPaint);
}
canvas.drawBitmap(tile.bitmap, null, tile.vRect, bitmapPaint);
if (matrix == null) { matrix = new Matrix(); }
matrix.reset();
setMatrixArray(srcArray, 0, 0, tile.bitmap.getWidth(), 0, tile.bitmap.getWidth(), tile.bitmap.getHeight(), 0, tile.bitmap.getHeight());
if (getRequiredRotation() == ORIENTATION_0) {
setMatrixArray(dstArray, tile.vRect.left, tile.vRect.top, tile.vRect.right, tile.vRect.top, tile.vRect.right, tile.vRect.bottom, tile.vRect.left, tile.vRect.bottom);
} else if (getRequiredRotation() == ORIENTATION_90) {
setMatrixArray(dstArray, tile.vRect.right, tile.vRect.top, tile.vRect.right, tile.vRect.bottom, tile.vRect.left, tile.vRect.bottom, tile.vRect.left, tile.vRect.top);
} else if (getRequiredRotation() == ORIENTATION_180) {
setMatrixArray(dstArray, tile.vRect.right, tile.vRect.bottom, tile.vRect.left, tile.vRect.bottom, tile.vRect.left, tile.vRect.top, tile.vRect.right, tile.vRect.top);
} else if (getRequiredRotation() == ORIENTATION_270) {
setMatrixArray(dstArray, tile.vRect.left, tile.vRect.bottom, tile.vRect.left, tile.vRect.top, tile.vRect.right, tile.vRect.top, tile.vRect.right, tile.vRect.bottom);
}
matrix.setPolyToPoly(srcArray, 0, dstArray, 0, 4);
canvas.drawBitmap(tile.bitmap, matrix, bitmapPaint);
if (debug) {
canvas.drawRect(tile.vRect, debugPaint);
}
Expand Down Expand Up @@ -950,6 +965,20 @@ protected void onDraw(Canvas canvas) {
}
}

/**
* Helper method for setting the values of a tile matrix array.
*/
private void setMatrixArray(float[] array, float f0, float f1, float f2, float f3, float f4, float f5, float f6, float f7) {
array[0] = f0;
array[1] = f1;
array[2] = f2;
array[3] = f3;
array[4] = f4;
array[5] = f5;
array[6] = f6;
array[7] = f7;
}

/**
* Checks whether the base layer of tiles or full size bitmap is ready.
*/
Expand Down Expand Up @@ -1401,14 +1430,7 @@ protected Bitmap doInBackground(Void... params) {
if (view.sRegion != null) {
tile.fileSRect.offset(view.sRegion.left, view.sRegion.top);
}
Bitmap bitmap = decoder.decodeRegion(tile.fileSRect, tile.sampleSize);
int rotation = view.getRequiredRotation();
if (rotation != 0) {
Matrix matrix = new Matrix();
matrix.postRotate(rotation);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
return bitmap;
return decoder.decodeRegion(tile.fileSRect, tile.sampleSize);
}
} else if (tile != null) {
tile.loading = false;
Expand Down Expand Up @@ -1484,14 +1506,6 @@ protected Integer doInBackground(Void... params) {
} catch (Exception e) {
Log.e(TAG, "Failed to load bitmap", e);
this.exception = e;
final SubsamplingScaleImageView subsamplingScaleImageView = viewRef.get();
if (subsamplingScaleImageView != null && subsamplingScaleImageView.onImageEventListener != null) {
if (preview) {
subsamplingScaleImageView.onImageEventListener.onPreviewLoadError(e);
} else {
subsamplingScaleImageView.onImageEventListener.onImageLoadError(e);
}
}
}
return null;
}
Expand Down Expand Up @@ -1646,7 +1660,7 @@ private Point getMaxBitmapDimensions(Canvas canvas) {
try {
int maxWidth = (Integer)Canvas.class.getMethod("getMaximumBitmapWidth").invoke(canvas);
int maxHeight = (Integer)Canvas.class.getMethod("getMaximumBitmapHeight").invoke(canvas);
return new Point(Math.min(2048, maxWidth), Math.min(2048, maxHeight));
return new Point(maxWidth, maxHeight);
} catch (Exception e) {
// Return default
}
Expand Down Expand Up @@ -1945,7 +1959,7 @@ private float easeInOutQuad(long time, float from, float change, long duration)
}

/**
* Swap the default decoder implementation for one of your own. You must do this before setting the image file or
* Swap the default region decoder implementation for one of your own. You must do this before setting the image file or
* asset, and you cannot use a custom decoder when using layout XML to set an asset name. Your class must have a
* public default constructor.
* @param regionDecoderClass The {@link ImageRegionDecoder} implementation to use.
Expand All @@ -1957,6 +1971,19 @@ public final void setRegionDecoderClass(Class<? extends ImageRegionDecoder> regi
this.regionDecoderClass = regionDecoderClass;
}

/**
* Swap the default bitmap decoder implementation for one of your own. You must do this before setting the image file or
* asset, and you cannot use a custom decoder when using layout XML to set an asset name. Your class must have a
* public default constructor.
* @param bitmapDecoderClass The {@link ImageDecoder} implementation to use.
*/
public final void setBitmapDecoderClass(Class<? extends ImageDecoder> bitmapDecoderClass) {
if (bitmapDecoderClass == null) {
throw new IllegalArgumentException("Decoder class cannot be set to null");
}
this.bitmapDecoderClass = bitmapDecoderClass;
}

/**
* Set the pan limiting style. See static fields. Normally {@link #PAN_LIMIT_INSIDE} is best, for image galleries.
*/
Expand Down

0 comments on commit 83203e9

Please sign in to comment.