下面列出了android.graphics.Matrix#setScale ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
this.mRect.set(0.0F, 0.0F, (float)bounds.width(), (float)bounds.height());
Matrix shaderMatrix = new Matrix();
float dx = 0.0F;
float dy = 0.0F;
int dwidth = this.mBitmapRect.width();
int dheight = this.mBitmapRect.height();
int vwidth = bounds.width();
int vheight = bounds.height();
float scale;
if(dwidth * vheight > vwidth * dheight) {
scale = (float)vheight / (float)dheight;
dx = ((float)vwidth - (float)dwidth * scale) * 0.5F;
} else {
scale = (float)vwidth / (float)dwidth;
dy = ((float)vheight - (float)dheight * scale) * 0.5F;
}
shaderMatrix.setScale(scale, scale);
shaderMatrix.postTranslate((float)((int)(dx + 0.5F)), (float)((int)(dy + 0.5F)));
this.bitmapShader.setLocalMatrix(shaderMatrix);
}
public Bitmap transform(Bitmap bitmap, int width, int height){
// Scale down the sampled bitmap if it's still larger than the desired dimension.
float scale = Math.min((float) width / bitmap.getWidth(),
(float) height / bitmap.getHeight());
scale = Math.max(scale, Math.min((float) height / bitmap.getWidth(),
(float) width / bitmap.getHeight()));
if (scale < 1) {
Matrix m = new Matrix();
m.setScale(scale, scale);
Bitmap transformed = createBitmap(
bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m);
bitmap.recycle();
return transformed;
}
return bitmap;
}
@Override
protected boolean setFrame(int l, int t, int r, int b) {
final Matrix matrix = getImageMatrix();
float scale;
final int viewWidth = getWidth() - getPaddingLeft() - getPaddingRight();
final int viewHeight = getHeight() - getPaddingTop() - getPaddingBottom();
final int drawableWidth = getDrawable().getIntrinsicWidth();
final int drawableHeight = getDrawable().getIntrinsicHeight();
if (drawableWidth * viewHeight > drawableHeight * viewWidth) {
scale = (float) viewHeight / (float) drawableHeight;
} else {
scale = (float) viewWidth / (float) drawableWidth;
}
matrix.setScale(scale, scale);
setImageMatrix(matrix);
return super.setFrame(l, t, r, b);
}
@NonNull
private static Matrix createShaderMatrix(@NonNull ImageView.ScaleType scaleType, int vWidth,
int vHeight, int bmWidth, int bmHeight) {
float scale, translateX = 0, translateY = 0;
if (bmWidth * vHeight > bmHeight * vWidth) {
scale = vHeight / (float) bmHeight;
translateX = (vWidth - bmWidth * scale) * 0.5f;
} else {
scale = vWidth / (float) bmWidth;
translateY = (vHeight - bmHeight * scale) * 0.5f;
}
Matrix mMatrix = new Matrix();
if (scaleType == ImageView.ScaleType.FIT_XY) {
mMatrix.setScale(vWidth / (float) bmWidth, vHeight / (float) bmHeight);
} else if (scaleType == ImageView.ScaleType.FIT_CENTER) {
RectF src = new RectF(0, 0, bmWidth, bmHeight);
RectF dist = new RectF(0, 0, vWidth, vHeight);
mMatrix.setRectToRect(src, dist, Matrix.ScaleToFit.CENTER);
} else if (scaleType == ImageView.ScaleType.CENTER_CROP) {
mMatrix.setScale(scale, scale);
mMatrix.postTranslate(translateX + 0.5f, translateY + 0.5f);
}
return mMatrix;
}
protected Bitmap considerExactScaleAndOrientaiton(Bitmap subsampledBitmap, ImageDecodingInfo decodingInfo,
int rotation, boolean flipHorizontal) {
Matrix m = new Matrix();
// Scale to exact size if need
ImageScaleType scaleType = decodingInfo.getImageScaleType();
if (scaleType == ImageScaleType.EXACTLY || scaleType == ImageScaleType.EXACTLY_STRETCHED) {
ImageSize srcSize = new ImageSize(subsampledBitmap.getWidth(), subsampledBitmap.getHeight(), rotation);
float scale = ImageSizeUtils.computeImageScale(srcSize, decodingInfo.getTargetSize(), decodingInfo
.getViewScaleType(), scaleType == ImageScaleType.EXACTLY_STRETCHED);
if (Float.compare(scale, 1f) != 0) {
m.setScale(scale, scale);
if (loggingEnabled) {
L.d(LOG_SCALE_IMAGE, srcSize, srcSize.scale(scale), scale, decodingInfo.getImageKey());
}
}
}
// Flip bitmap if need
if (flipHorizontal) {
m.postScale(-1, 1);
if (loggingEnabled) L.d(LOG_FLIP_IMAGE, decodingInfo.getImageKey());
}
// Rotate bitmap if need
if (rotation != 0) {
m.postRotate(rotation);
if (loggingEnabled) L.d(LOG_ROTATE_IMAGE, rotation, decodingInfo.getImageKey());
}
Bitmap finalBitmap = Bitmap.createBitmap(subsampledBitmap, 0, 0, subsampledBitmap.getWidth(), subsampledBitmap
.getHeight(), m, true);
if (finalBitmap != subsampledBitmap) {
subsampledBitmap.recycle();
}
return finalBitmap;
}
private void drawUnmirroredRotatedBitmap(final Bitmap src, final Bitmap dst, final int rotation) {
final Matrix matrix = new Matrix();
//matrix.postTranslate(-dst.getWidth() / 2.0f, -dst.getHeight() / 2.0f);
matrix.postRotate(rotation);
matrix.setScale(-1, 1);
matrix.postTranslate(dst.getWidth(), 0);
final Canvas canvas = new Canvas(dst);
canvas.drawBitmap(src, matrix, null);
}
@Override
public void initialize(Context c, ObjectSpec s, PointF objectSize) {
// Make a resource id out of the string of the file name
int resID = c.getResources().getIdentifier(s.getBitmapName(),
"drawable", c.getPackageName());
// Load the bitmap using the id
mBitmap = BitmapFactory.decodeResource(c.getResources(), resID);
// Resize the bitmap
mBitmap = Bitmap
.createScaledBitmap(mBitmap,
(int)objectSize.x,
(int)objectSize.y,
false);
// Create a mirror image of the bitmap
Matrix matrix = new Matrix();
matrix.setScale(-1, 1);
mBitmapReversed = Bitmap
.createBitmap(mBitmap,
0, 0,
mBitmap.getWidth(),
mBitmap.getHeight(),
matrix, true);
}
static void addBitmap(Context c,
String bitmapName,
PointF objectSize,
int pixelsPerMetre,
boolean needReversed) {
Bitmap bitmap;
Bitmap bitmapReversed;
// Make a resource id out of the string of the file name
int resID = c.getResources().getIdentifier(bitmapName,
"drawable", c.getPackageName());
// Load the bitmap using the id
bitmap = BitmapFactory
.decodeResource(c.getResources(), resID);
// Resize the bitmap
bitmap = Bitmap.createScaledBitmap(bitmap,
(int) objectSize.x * pixelsPerMetre,
(int) objectSize.y * pixelsPerMetre,
false);
mBitmapsMap.put(bitmapName, bitmap);
if (needReversed) {
// Create a mirror image of the bitmap
Matrix matrix = new Matrix();
matrix.setScale(-1, 1);
bitmapReversed = Bitmap.createBitmap(
bitmap,
0, 0,
bitmap.getWidth(),
bitmap.getHeight(),
matrix, true);
mBitmapsReversedMap.put(bitmapName, bitmapReversed);
}
}
/**
* Scales the paths to the given screen density. If the density matches the
* {@link DrawerArrowDrawable#PATH_GEN_DENSITY}, no scaling needs to be done.
*/
private static void scalePath(Path path, float density) {
if (density == PATH_GEN_DENSITY) return;
Matrix scaleMatrix = new Matrix();
scaleMatrix.setScale(density / PATH_GEN_DENSITY, density / PATH_GEN_DENSITY, 0, 0);
path.transform(scaleMatrix);
}
/**
* Underlying drawable's aspect ratio is smaller than view's, so it has to be slided vertically
* after scaling. Focus point is too much bottom, so it cannot be completely centered. Bottom-most
* part of the image is displayed.
*/
@Test
public void testConfigureBounds_FOCUS_CROP_VB() {
Rect bounds = new Rect(10, 10, 410, 310);
int width = 200;
int height = 300;
PointF focusPoint = new PointF(0.5f, 0.9f);
Matrix expectedMatrix = new Matrix();
expectedMatrix.setScale(2.0f, 2.0f);
expectedMatrix.postTranslate(10, -289);
testConfigureBounds(bounds, width, height, ScaleType.FOCUS_CROP, focusPoint, expectedMatrix);
}
/**
* Re-initializes the shader texture used to fill in
* the Circle upon drawing.
*/
public void updateBitmapShader() {
if (image == null)
return;
shader = new BitmapShader(image, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
if(canvasSize != image.getWidth() || canvasSize != image.getHeight()) {
Matrix matrix = new Matrix();
float scale = (float) canvasSize / (float) image.getWidth();
matrix.setScale(scale, scale);
shader.setLocalMatrix(matrix);
}
}
private Bitmap prepareBitmap() {
if (mBitmap == null) {
return null;
}
// 256 pixels wide is enough.
if (mBitmap.getWidth() > 256) {
mScale = 256.0F / mBitmap.getWidth(); // CR: F => f (or change
// all f to F).
}
Matrix matrix = new Matrix();
matrix.setScale(mScale, mScale);
Bitmap faceBitmap = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, true);
return faceBitmap;
}
protected Bitmap considerExactScaleAndOrientatiton(Bitmap subsampledBitmap, ImageDecodingInfo decodingInfo,
int rotation, boolean flipHorizontal) {
Matrix m = new Matrix();
// Scale to exact size if need
ImageScaleType scaleType = decodingInfo.getImageScaleType();
if (scaleType == ImageScaleType.EXACTLY || scaleType == ImageScaleType.EXACTLY_STRETCHED) {
ImageSize srcSize = new ImageSize(subsampledBitmap.getWidth(), subsampledBitmap.getHeight(), rotation);
float scale = ImageSizeUtils.computeImageScale(srcSize, decodingInfo.getTargetSize(), decodingInfo
.getViewScaleType(), scaleType == ImageScaleType.EXACTLY_STRETCHED);
if (Float.compare(scale, 1f) != 0) {
m.setScale(scale, scale);
if (loggingEnabled) {
L.d(LOG_SCALE_IMAGE, srcSize, srcSize.scale(scale), scale, decodingInfo.getImageKey());
}
}
}
// Flip bitmap if need
if (flipHorizontal) {
m.postScale(-1, 1);
if (loggingEnabled) L.d(LOG_FLIP_IMAGE, decodingInfo.getImageKey());
}
// Rotate bitmap if need
if (rotation != 0) {
m.postRotate(rotation);
if (loggingEnabled) L.d(LOG_ROTATE_IMAGE, rotation, decodingInfo.getImageKey());
}
Bitmap finalBitmap = Bitmap.createBitmap(subsampledBitmap, 0, 0, subsampledBitmap.getWidth(), subsampledBitmap
.getHeight(), m, true);
if (finalBitmap != subsampledBitmap) {
subsampledBitmap.recycle();
}
return subsampledBitmap;
}
protected boolean getChildStaticTransformation(View child, Transformation t) {
Camera camera = new Camera();
int leftCenterView = this.mWidthCenter - this.mChildrenWidthMiddle;
float offset = (-child.getLeft() + leftCenterView) /
this.mSpaceBetweenViews;
if (offset != 0.0F) {
float absOffset = Math.abs(offset);
float scale = (float) Math.pow(0.8999999761581421D, absOffset);
t.clear();
t.setTransformationType(Transformation.TYPE_MATRIX);
t.setAlpha(this.mSetInactiveViewTransparency);
Matrix m = t.getMatrix();
m.setScale(scale, scale);
if (this.mTranslatateEnbabled) {
m.setTranslate(0.0F, this.mTranslate * absOffset);
}
if (offset > 0.0F) {
camera.save();
camera.translate(0.0F, 0.0F, this.mViewZoomOutFactor * offset);
camera.rotateY(this.mCoverflowRotation);
camera.getMatrix(m);
camera.restore();
m.preTranslate(-this.mChildrenWidthMiddle, -this.mChildrenHeight);
m.postTranslate(this.mChildrenWidthMiddle, this.mChildrenHeight);
} else {
camera.save();
camera.translate(0.0F, 0.0F, -(this.mViewZoomOutFactor * offset));
camera.rotateY(-this.mCoverflowRotation);
camera.getMatrix(m);
camera.restore();
m.preTranslate(-this.mChildrenWidthMiddle, -this.mChildrenHeight);
m.postTranslate(this.mChildrenWidthMiddle, this.mChildrenHeight);
}
this.mMatrix.reset();
if (this.mRotationEnabled) {
this.mMatrix.setRotate(this.mRotation * offset);
}
this.mMatrix.preTranslate(-this.mChildrenWidthMiddle, -this.mChildrenHeightMiddle);
this.mMatrix.postTranslate(this.mChildrenWidthMiddle, this.mChildrenHeightMiddle);
m.setConcat(m, this.mMatrix);
}
return true;
}
public static Bitmap rotateBitmap(Bitmap bitmap, int orientation) {
Matrix matrix = new Matrix();
switch (orientation) {
case ExifInterface.ORIENTATION_NORMAL:
return bitmap;
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
matrix.setScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
matrix.setRotate(180);
break;
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
matrix.setRotate(180);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_TRANSPOSE:
matrix.setRotate(90);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_90:
matrix.setRotate(90);
break;
case ExifInterface.ORIENTATION_TRANSVERSE:
matrix.setRotate(-90);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
matrix.setRotate(-90);
break;
default:
return bitmap;
}
try {
Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
bitmap.recycle();
return bmRotated;
} catch (OutOfMemoryError e) {
e.printStackTrace();
return null;
}
}
public void setZoom(float scaleX, float scaleY, Matrix outputMatrix) {
outputMatrix.reset();
outputMatrix.set(mMatrixTouch);
outputMatrix.setScale(scaleX, scaleY);
}
/**
* Crop the rectangle given by {@code mX, mY, mWidth, mHeight} within the source bitmap
* and scale the result to {@code targetWidth, targetHeight}.
* @param outOptions Bitmap options, useful to determine {@code outMimeType}.
*/
private Bitmap cropAndResize(
int targetWidth,
int targetHeight,
BitmapFactory.Options outOptions)
throws IOException {
Assertions.assertNotNull(outOptions);
// Loading large bitmaps efficiently:
// http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
// This uses scaling mode COVER
// Where would the crop rect end up within the scaled bitmap?
float newWidth, newHeight, newX, newY, scale;
float cropRectRatio = mWidth / (float) mHeight;
float targetRatio = targetWidth / (float) targetHeight;
if (cropRectRatio > targetRatio) {
// e.g. source is landscape, target is portrait
newWidth = mHeight * targetRatio;
newHeight = mHeight;
newX = mX + (mWidth - newWidth) / 2;
newY = mY;
scale = targetHeight / (float) mHeight;
} else {
// e.g. source is landscape, target is portrait
newWidth = mWidth;
newHeight = mWidth / targetRatio;
newX = mX;
newY = mY + (mHeight - newHeight) / 2;
scale = targetWidth / (float) mWidth;
}
// Decode the bitmap. We have to open the stream again, like in the example linked above.
// Is there a way to just continue reading from the stream?
outOptions.inSampleSize = getDecodeSampleSize(mWidth, mHeight, targetWidth, targetHeight);
InputStream inputStream = openBitmapInputStream();
Bitmap bitmap;
try {
// This can use significantly less memory than decoding the full-resolution bitmap
bitmap = BitmapFactory.decodeStream(inputStream, null, outOptions);
if (bitmap == null) {
throw new IOException("Cannot decode bitmap: " + mUri);
}
} finally {
if (inputStream != null) {
inputStream.close();
}
}
int cropX = Math.round(newX / (float) outOptions.inSampleSize);
int cropY = Math.round(newY / (float) outOptions.inSampleSize);
int cropWidth = Math.round(newWidth / (float) outOptions.inSampleSize);
int cropHeight = Math.round(newHeight / (float) outOptions.inSampleSize);
float cropScale = scale * outOptions.inSampleSize;
Matrix scaleMatrix = new Matrix();
scaleMatrix.setScale(cropScale, cropScale);
boolean filter = true;
return Bitmap.createBitmap(bitmap, cropX, cropY, cropWidth, cropHeight, scaleMatrix, filter);
}
private void updateTextureViewSize() {
float viewWidth = getWidth();
float viewHeight = getHeight();
float scaleX = 1.0f;
float scaleY = 1.0f;
if (mVideoWidth > viewWidth && mVideoHeight > viewHeight) {
scaleX = mVideoWidth / viewWidth;
scaleY = mVideoHeight / viewHeight;
} else if (mVideoWidth < viewWidth && mVideoHeight < viewHeight) {
scaleY = viewWidth / mVideoWidth;
scaleX = viewHeight / mVideoHeight;
} else if (viewWidth > mVideoWidth) {
scaleY = (viewWidth / mVideoWidth) / (viewHeight / mVideoHeight);
} else if (viewHeight > mVideoHeight) {
scaleX = (viewHeight / mVideoHeight) / (viewWidth / mVideoWidth);
}
// Calculate pivot points, in our case crop from center
int pivotPointX;
int pivotPointY;
switch (mScaleType) {
case TOP:
pivotPointX = 0;
pivotPointY = 0;
break;
case BOTTOM:
pivotPointX = (int) (viewWidth);
pivotPointY = (int) (viewHeight);
break;
case CENTER_CROP:
pivotPointX = (int) (viewWidth / 2);
pivotPointY = (int) (viewHeight / 2);
break;
default:
pivotPointX = (int) (viewWidth / 2);
pivotPointY = (int) (viewHeight / 2);
break;
}
Matrix matrix = new Matrix();
matrix.setScale(scaleX, scaleY, pivotPointX, pivotPointY);
setTransform(matrix);
}
/**
* Sets the scale factor to the specified values.
*
* @param scaleX
* @param scaleY
* @return
*/
public Matrix setZoom(float scaleX, float scaleY) {
Matrix save = new Matrix();
save.set(mMatrixTouch);
save.setScale(scaleX, scaleY);
return save;
}
/**
* Sets the scale factor to the specified values. x and y is pivot.
*
* @param scaleX
* @param scaleY
* @param x
* @param y
* @return
*/
public Matrix setZoom(float scaleX, float scaleY, float x, float y) {
Matrix save = new Matrix();
save.set(mMatrixTouch);
save.setScale(scaleX, scaleY, x, y);
return save;
}