Methods Summary |
---|
protected void | center(boolean vertical, boolean horizontal, boolean animate)
if (mBitmapDisplayed == null)
return;
Matrix m = getImageViewMatrix();
float [] topLeft = new float[] { 0, 0 };
float [] botRight = new float[] { mBitmapDisplayed.getWidth(), mBitmapDisplayed.getHeight() };
translatePoint(m, topLeft);
translatePoint(m, botRight);
float height = botRight[1] - topLeft[1];
float width = botRight[0] - topLeft[0];
float deltaX = 0, deltaY = 0;
if (vertical) {
int viewHeight = getHeight();
if (height < viewHeight) {
deltaY = (viewHeight - height)/2 - topLeft[1];
} else if (topLeft[1] > 0) {
deltaY = -topLeft[1];
} else if (botRight[1] < viewHeight) {
deltaY = getHeight() - botRight[1];
}
}
if (horizontal) {
int viewWidth = getWidth();
if (width < viewWidth) {
deltaX = (viewWidth - width)/2 - topLeft[0];
} else if (topLeft[0] > 0) {
deltaX = -topLeft[0];
} else if (botRight[0] < viewWidth) {
deltaX = viewWidth - botRight[0];
}
}
postTranslate(deltaX, deltaY);
if (animate) {
Animation a = new TranslateAnimation(-deltaX, 0, -deltaY, 0);
a.setStartTime(SystemClock.elapsedRealtime());
a.setDuration(250);
setAnimation(a);
}
setImageMatrix(getImageViewMatrix());
|
public void | clear()
mBitmapDisplayed = null;
recycleBitmaps();
|
public void | copyFrom(com.android.camera.ImageViewTouchBase other)
mSuppMatrix.set(other.mSuppMatrix);
mBaseMatrix.set(other.mBaseMatrix);
if (mThumbBitmap != null)
mThumbBitmap.recycle();
if (mFullBitmap != null)
mFullBitmap.recycle();
// copy the data
mThumbBitmap = other.mThumbBitmap;
mFullBitmap = null;
if (other.mFullBitmap != null)
other.mFullBitmap.recycle();
// transfer "ownership"
other.mThumbBitmap = null;
other.mFullBitmap = null;
other.mBitmapIsThumbnail = true;
setImageMatrix(other.getImageMatrix());
setScaleType(other.getScaleType());
setImageBitmapResetBase(mThumbBitmap, true, true);
|
private java.lang.String | describe(android.graphics.Bitmap b)
StringBuilder sb = new StringBuilder();
if (b == null) {
sb.append("NULL");
} else if (b.isRecycled()) {
sb.append(String.format("%08x: RECYCLED", b.hashCode()));
} else {
sb.append(String.format("%08x: LIVE", b.hashCode()));
sb.append(String.format("%d x %d (size == %d)", b.getWidth(), b.getHeight(), b.getWidth()*b.getHeight()*2));
}
return sb.toString();
|
protected boolean | doesScrolling()
return true;
|
public void | dump()
if (Config.LOGV) {
Log.v(TAG, "dump ImageViewTouchBase " + this);
Log.v(TAG, "... mBitmapDisplayed = " + describe(mBitmapDisplayed));
Log.v(TAG, "... mThumbBitmap = " + describe(mThumbBitmap));
Log.v(TAG, "... mFullBitmap = " + describe(mFullBitmap));
Log.v(TAG, "... mPerfectFitBitmap = " + describe(mPerfectFitBitmap));
Log.v(TAG, "... mIsThumb = " + mBitmapIsThumbnail);
}
|
protected android.graphics.Matrix | getImageViewMatrix()
mDisplayMatrix.set(mBaseMatrix);
mDisplayMatrix.postConcat(mSuppMatrix);
return mDisplayMatrix;
|
protected float | getScale(android.graphics.Matrix matrix)
return getValue(matrix, Matrix.MSCALE_X);
|
protected float | getScale()
return getScale(mSuppMatrix);
|
protected float | getTranslateX()
return getValue(mSuppMatrix, Matrix.MTRANS_X);
|
protected float | getTranslateY()
return getValue(mSuppMatrix, Matrix.MTRANS_Y);
|
protected float | getValue(android.graphics.Matrix matrix, int whichValue)
matrix.getValues(mMatrixValues);
return mMatrixValues[whichValue];
|
private void | init()
setScaleType(ImageView.ScaleType.MATRIX);
mPaint.setDither(true);
mPaint.setFilterBitmap(true);
|
static int | mapXPoint(android.graphics.Matrix matrix, int point)
// Matrix's mapPoints takes an array of x/y coordinates.
// That's why we have to allocte an array of length two
// even though we don't use the y coordinate.
float [] xy = new float[2];
xy[0] = point;
xy[1] = 0F;
matrix.mapPoints(xy);
return (int) xy[0];
|
protected float | maxZoom()
// Sets the maximum zoom, which is a scale relative to the base matrix. It is calculated to show
// the image at 400% zoom regardless of screen or image orientation. If in the future we decode
// the full 3 megapixel image, rather than the current 1024x768, this should be changed down to
// 200%.
if (mBitmapDisplayed == null)
return 1F;
float fw = (float) mBitmapDisplayed.getWidth() / (float)mThisWidth;
float fh = (float) mBitmapDisplayed.getHeight() / (float)mThisHeight;
float max = Math.max(fw, fh) * 4;
// Log.v(TAG, "Bitmap " + mBitmapDisplayed.getWidth() + "x" + mBitmapDisplayed.getHeight() +
// " view " + mThisWidth + "x" + mThisHeight + " max zoom " + max);
return max;
|
public boolean | onKeyDown(int keyCode, android.view.KeyEvent event)
if (keyCode == KeyEvent.KEYCODE_BACK && getScale() > 1.0f) {
// If we're zoomed in, pressing Back jumps out to show the entire image, otherwise Back
// returns the user to the gallery.
zoomTo(1.0f);
return true;
}
return super.onKeyDown(keyCode, event);
|
protected void | onLayout(boolean changed, int left, int top, int right, int bottom)
super.onLayout(changed, left, top, right, bottom);
mThisWidth = right - left;
mThisHeight = bottom - top;
Runnable r = mOnLayoutRunnable;
if (r != null) {
mOnLayoutRunnable = null;
r.run();
}
if (mBitmapDisplayed != null) {
setBaseMatrix(mBitmapDisplayed, mBaseMatrix);
setImageMatrix(getImageViewMatrix());
}
|
private void | onZoom()
mIsZooming = true;
if (mFullBitmap != null && mFullBitmap != mBitmapDisplayed) {
setImageBitmapResetBase(mFullBitmap, false, mBitmapIsThumbnail);
}
|
protected void | panBy(float dx, float dy)
postTranslate(dx, dy);
setImageMatrix(getImageViewMatrix());
|
protected void | postTranslate(float dx, float dy)
mSuppMatrix.postTranslate(dx, dy);
|
public void | recycleBitmaps()
if (mFullBitmap != null) {
if (Config.LOGV)
Log.v(TAG, "recycling mFullBitmap " + mFullBitmap + "; this == " + this.hashCode());
mFullBitmap.recycle();
mFullBitmap = null;
}
if (mThumbBitmap != null) {
if (Config.LOGV)
Log.v(TAG, "recycling mThumbBitmap" + mThumbBitmap + "; this == " + this.hashCode());
mThumbBitmap.recycle();
mThumbBitmap = null;
}
// mBitmapDisplayed is either mPerfectFitBitmap or mFullBitmap (in the case of zooming)
setImageBitmap(null, true);
|
private void | setBaseMatrix(android.graphics.Bitmap bitmap, android.graphics.Matrix matrix)
float viewWidth = getWidth();
float viewHeight = getHeight();
matrix.reset();
float widthScale = Math.min(viewWidth / (float)bitmap.getWidth(), 1.0f);
float heightScale = Math.min(viewHeight / (float)bitmap.getHeight(), 1.0f);
float scale;
if (widthScale > heightScale) {
scale = heightScale;
} else {
scale = widthScale;
}
matrix.setScale(scale, scale);
matrix.postTranslate(
(viewWidth - ((float)bitmap.getWidth() * scale))/2F,
(viewHeight - ((float)bitmap.getHeight() * scale))/2F);
|
public void | setImageBitmap(android.graphics.Bitmap bitmap)
throw new NullPointerException();
|
public void | setImageBitmap(android.graphics.Bitmap bitmap, boolean isThumbnail)
super.setImageBitmap(bitmap);
Drawable d = getDrawable();
if (d != null)
d.setDither(true);
mBitmapDisplayed = bitmap;
mBitmapIsThumbnail = isThumbnail;
|
public void | setImageBitmapResetBase(android.graphics.Bitmap bitmap, boolean resetSupp, boolean isThumb)
if ((bitmap != null) && (bitmap == mPerfectFitBitmap)) {
// TODO: this should be removed in production
throw new IllegalArgumentException("bitmap must not be mPerfectFitBitmap");
}
final int viewWidth = getWidth();
final int viewHeight = getHeight();
if (viewWidth <= 0) {
mOnLayoutRunnable = new Runnable() {
public void run() {
setImageBitmapResetBase(bitmap, resetSupp, isThumb);
}
};
return;
}
if (isThumb && mThumbBitmap != bitmap) {
if (mThumbBitmap != null) {
mThumbBitmap.recycle();
}
mThumbBitmap = bitmap;
} else if (!isThumb && mFullBitmap != bitmap) {
if (mFullBitmap != null) {
mFullBitmap.recycle();
}
mFullBitmap = bitmap;
}
mBitmapIsThumbnail = isThumb;
if (bitmap != null) {
if (!usePerfectFitBitmap()) {
setScaleType(ImageView.ScaleType.MATRIX);
setBaseMatrix(bitmap, mBaseMatrix);
setImageBitmap(bitmap, isThumb);
} else {
Matrix matrix = new Matrix();
setBaseMatrix(bitmap, matrix);
if ((mPerfectFitBitmap == null) ||
mPerfectFitBitmap.getWidth() != mThisWidth ||
mPerfectFitBitmap.getHeight() != mThisHeight) {
if (mPerfectFitBitmap != null) {
if (Config.LOGV)
Log.v(TAG, "recycling mPerfectFitBitmap " + mPerfectFitBitmap.hashCode());
mPerfectFitBitmap.recycle();
}
mPerfectFitBitmap = Bitmap.createBitmap(mThisWidth, mThisHeight, Bitmap.Config.RGB_565);
}
Canvas canvas = new Canvas(mPerfectFitBitmap);
// clear the bitmap which may be bigger than the image and
// contain the the previous image.
canvas.drawColor(0xFF000000);
final int bw = bitmap.getWidth();
final int bh = bitmap.getHeight();
final float widthScale = Math.min(viewWidth / (float)bw, 1.0f);
final float heightScale = Math.min(viewHeight/ (float)bh, 1.0f);
int translateX, translateY;
if (widthScale > heightScale) {
translateX = (int)((viewWidth -(float)bw*heightScale)*0.5f);
translateY = (int)((viewHeight-(float)bh*heightScale)*0.5f);
} else {
translateX = (int)((viewWidth -(float)bw*widthScale)*0.5f);
translateY = (int)((viewHeight-(float)bh*widthScale)*0.5f);
}
android.graphics.Rect src = new android.graphics.Rect(0, 0, bw, bh);
android.graphics.Rect dst = new android.graphics.Rect(
translateX, translateY,
mThisWidth - translateX, mThisHeight - translateY);
canvas.drawBitmap(bitmap, src, dst, mPaint);
setImageBitmap(mPerfectFitBitmap, isThumb);
setScaleType(ImageView.ScaleType.MATRIX);
setImageMatrix(null);
}
} else {
mBaseMatrix.reset();
setImageBitmap(null, isThumb);
}
if (resetSupp)
mSuppMatrix.reset();
setImageMatrix(getImageViewMatrix());
mMaxZoom = maxZoom();
|
public void | setImageDrawable(android.graphics.drawable.Drawable d)
super.setImageDrawable(d);
|
private static void | translatePoint(android.graphics.Matrix matrix, float[] xy)
matrix.mapPoints(xy);
|
protected boolean | usePerfectFitBitmap()
return USE_PERFECT_FIT_OPTIMIZATION && !mIsZooming;
|
protected void | zoomIn()
zoomIn(sScaleRate);
|
protected void | zoomIn(float rate)
if (getScale() >= mMaxZoom) {
return; // Don't let the user zoom into the molecular level.
}
if (mBitmapDisplayed == null) {
return;
}
float width = getWidth();
float height = getHeight();
mSuppMatrix.postScale(rate, rate, width/2F, height/2F);
setImageMatrix(getImageViewMatrix());
onZoom();
|
protected void | zoomOut()
zoomOut(sScaleRate);
|
protected void | zoomOut(float rate)
if (mBitmapDisplayed == null) {
return;
}
float width = getWidth();
float height = getHeight();
Matrix tmp = new Matrix(mSuppMatrix);
tmp.postScale(1F/sScaleRate, 1F/sScaleRate, width/2F, height/2F);
if (getScale(tmp) < 1F) {
mSuppMatrix.setScale(1F, 1F, width/2F, height/2F);
} else {
mSuppMatrix.postScale(1F/rate, 1F/rate, width/2F, height/2F);
}
setImageMatrix(getImageViewMatrix());
center(true, true, false);
onZoom();
|
protected void | zoomTo(float scale, float centerX, float centerY)
if (scale > mMaxZoom) {
scale = mMaxZoom;
}
onZoom();
float oldScale = getScale();
float deltaScale = scale / oldScale;
mSuppMatrix.postScale(deltaScale, deltaScale, centerX, centerY);
setImageMatrix(getImageViewMatrix());
center(true, true, false);
|
protected void | zoomTo(float scale, float centerX, float centerY, float durationMs)
final float incrementPerMs = (scale - getScale()) / durationMs;
final float oldScale = getScale();
final long startTime = System.currentTimeMillis();
mHandler.post(new Runnable() {
public void run() {
long now = System.currentTimeMillis();
float currentMs = Math.min(durationMs, (float)(now - startTime));
float target = oldScale + (incrementPerMs * currentMs);
zoomTo(target, centerX, centerY);
if (currentMs < durationMs) {
mHandler.post(this);
}
}
});
|
protected void | zoomTo(float scale)
float width = getWidth();
float height = getHeight();
zoomTo(scale, width/2F, height/2F);
|