android.graphics.Matrix#postTranslate ( )源码实例Demo

下面列出了android.graphics.Matrix#postTranslate ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

源代码1 项目: fresco   文件: DefaultZoomableController.java
/**
 * Calculates the zoom transformation based on the current gesture.
 *
 * @param outTransform the matrix to store the result to
 * @param limitTypes whether to limit translation and/or scale.
 * @return whether or not the transform has been corrected due to limitation
 */
protected boolean calculateGestureTransform(Matrix outTransform, @LimitFlag int limitTypes) {
  TransformGestureDetector detector = mGestureDetector;
  boolean transformCorrected = false;
  outTransform.set(mPreviousTransform);
  if (mIsRotationEnabled) {
    float angle = detector.getRotation() * (float) (180 / Math.PI);
    outTransform.postRotate(angle, detector.getPivotX(), detector.getPivotY());
  }
  if (mIsScaleEnabled) {
    float scale = detector.getScale();
    outTransform.postScale(scale, scale, detector.getPivotX(), detector.getPivotY());
  }
  transformCorrected |=
      limitScale(outTransform, detector.getPivotX(), detector.getPivotY(), limitTypes);
  if (mIsTranslationEnabled) {
    outTransform.postTranslate(detector.getTranslationX(), detector.getTranslationY());
  }
  transformCorrected |= limitTranslation(outTransform, limitTypes);
  return transformCorrected;
}
 
源代码2 项目: fresco   文件: ScalingUtils.java
@Override
public void getTransformImpl(
    Matrix outTransform,
    Rect parentRect,
    int childWidth,
    int childHeight,
    float focusX,
    float focusY,
    float scaleX,
    float scaleY) {
  float scale, dx, dy;
  scale = scaleY;
  dx = parentRect.left + (parentRect.width() - childWidth * scale) * 0.5f;
  dy = parentRect.top;
  outTransform.setScale(scale, scale);
  outTransform.postTranslate((int) (dx + 0.5f), (int) (dy + 0.5f));
}
 
源代码3 项目: Sky31Radio   文件: MarkerDrawable.java
private void computePath(Rect bounds) {
    final float currentScale = mCurrentScale;
    final Path path = mPath;
    final RectF rect = mRect;
    final Matrix matrix = mMatrix;

    path.reset();
    int totalSize = Math.min(bounds.width(), bounds.height());

    float initial = mClosedStateSize;
    float destination = totalSize;
    float currentSize = initial + (destination - initial) * currentScale;

    float halfSize = currentSize / 2f;
    float inverseScale = 1f - currentScale;
    float cornerSize = halfSize * inverseScale;
    float[] corners = new float[]{halfSize, halfSize, halfSize, halfSize, halfSize, halfSize, cornerSize, cornerSize};
    rect.set(bounds.left, bounds.top, bounds.left + currentSize, bounds.top + currentSize);
    path.addRoundRect(rect, corners, Path.Direction.CCW);
    matrix.reset();
    matrix.postRotate(-45, bounds.left + halfSize, bounds.top + halfSize);
    matrix.postTranslate((bounds.width() - currentSize) / 2, 0);
    float hDiff = (bounds.bottom - currentSize - mExternalOffset) * inverseScale;
    matrix.postTranslate(0, hDiff);
    path.transform(matrix);
}
 
源代码4 项目: o2oa   文件: BaseZoomableImageView.java
private void setBaseMatrix(Bitmap bitmap, 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);
}
 
源代码5 项目: android-tv-launcher   文件: Rotate3dAnimation.java
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
    final float fromDegrees = mFromDegrees;
    float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);

    final float centerX = mCenterX;
    final float centerY = mCenterY;
    final Camera camera = mCamera;

    final Matrix matrix = t.getMatrix();

    camera.save();
    if (mReverse) {
        camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
    } else {
        camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
    }
    camera.rotateY(degrees);
    camera.getMatrix(matrix);
    camera.restore();

    matrix.preTranslate(-centerX, -centerY);
    matrix.postTranslate(centerX, centerY);
}
 
源代码6 项目: codeexamples-android   文件: Rotate3dAnimation.java
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
    final float fromDegrees = mFromDegrees;
    float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);

    final float centerX = mCenterX;
    final float centerY = mCenterY;
    final Camera camera = mCamera;

    final Matrix matrix = t.getMatrix();

    camera.save();
    if (mReverse) {
        camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
    } else {
        camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
    }
    camera.rotateY(degrees);
    camera.getMatrix(matrix);
    camera.restore();

    matrix.preTranslate(-centerX, -centerY);
    matrix.postTranslate(centerX, centerY);
}
 
源代码7 项目: sketch   文件: RotateImageProcessor.java
public static Bitmap rotate(@NonNull Bitmap bitmap, int degrees, @NonNull BitmapPool bitmapPool) {
    Matrix matrix = new Matrix();
    matrix.setRotate(degrees);

    // 根据旋转角度计算新的图片的尺寸
    RectF newRect = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight());
    matrix.mapRect(newRect);
    int newWidth = (int) newRect.width();
    int newHeight = (int) newRect.height();

    // 角度不能整除90°时新图片会是斜的,因此要支持透明度,这样倾斜导致露出的部分就不会是黑的
    Bitmap.Config config = bitmap.getConfig() != null ? bitmap.getConfig() : Bitmap.Config.ARGB_8888;
    if (degrees % 90 != 0 && config != Bitmap.Config.ARGB_8888) {
        config = Bitmap.Config.ARGB_8888;
    }

    Bitmap result = bitmapPool.getOrMake(newWidth, newHeight, config);

    matrix.postTranslate(-newRect.left, -newRect.top);

    final Canvas canvas = new Canvas(result);
    final Paint paint = new Paint(Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG);
    canvas.drawBitmap(bitmap, matrix, paint);

    return result;
}
 
源代码8 项目: KJFrameForAndroid   文件: AnimatorProxy.java
private void transformMatrix(Matrix m, View view) {
    final float w = view.getWidth();
    final float h = view.getHeight();
    final boolean hasPivot = mHasPivot;
    final float pX = hasPivot ? mPivotX : w / 2f;
    final float pY = hasPivot ? mPivotY : h / 2f;

    final float rX = mRotationX;
    final float rY = mRotationY;
    final float rZ = mRotationZ;
    if ((rX != 0) || (rY != 0) || (rZ != 0)) {
        final Camera camera = mCamera;
        camera.save();
        camera.rotateX(rX);
        camera.rotateY(rY);
        camera.rotateZ(-rZ);
        camera.getMatrix(m);
        camera.restore();
        m.preTranslate(-pX, -pY);
        m.postTranslate(pX, pY);
    }

    final float sX = mScaleX;
    final float sY = mScaleY;
    if ((sX != 1.0f) || (sY != 1.0f)) {
        m.postScale(sX, sY);
        final float sPX = -(pX / w) * ((sX * w) - w);
        final float sPY = -(pY / h) * ((sY * h) - h);
        m.postTranslate(sPX, sPY);
    }

    m.postTranslate(mTranslationX, mTranslationY);
}
 
源代码9 项目: timecat   文件: AnimatorProxy.java
private void transformMatrix(Matrix m, View view) {
    final float w = view.getWidth();
    final float h = view.getHeight();
    final boolean hasPivot = mHasPivot;
    final float pX = hasPivot ? mPivotX : w / 2f;
    final float pY = hasPivot ? mPivotY : h / 2f;

    final float rX = mRotationX;
    final float rY = mRotationY;
    final float rZ = mRotationZ;
    if ((rX != 0) || (rY != 0) || (rZ != 0)) {
        final Camera camera = mCamera;
        camera.save();
        camera.rotateX(rX);
        camera.rotateY(rY);
        camera.rotateZ(-rZ);
        camera.getMatrix(m);
        camera.restore();
        m.preTranslate(-pX, -pY);
        m.postTranslate(pX, pY);
    }

    final float sX = mScaleX;
    final float sY = mScaleY;
    if ((sX != 1.0f) || (sY != 1.0f)) {
        m.postScale(sX, sY);
        final float sPX = -(pX / w) * ((sX * w) - w);
        final float sPY = -(pY / h) * ((sY * h) - h);
        m.postTranslate(sPX, sPY);
    }

    m.postTranslate(mTranslationX, mTranslationY);
}
 
源代码10 项目: CameraButton   文件: CameraButton.java
/**
 * Since algorithm has differences between values calculation of right/left icons
 * we have to pass some flag for identify icon side.
 */
private void drawIcon(Canvas canvas, int index, float progress, boolean isLeftIcon) {
    float centerX = canvas.getWidth() / 2f;
    float centerY = canvas.getHeight() / 2f;

    float iconWidth = calculateIconWidth(progress);
    float translation = calculateTranslation(progress);
    float scaleX = iconWidth / mIconSize;

    float matrixDx = isLeftIcon
            ? centerX - mIconSize / 2f - translation
            : centerX + mIconSize / 2f + translation - iconWidth;

    Matrix matrix = mIconMatrices[index];
    matrix.reset();
    matrix.setScale(scaleX, 1);
    matrix.postTranslate(matrixDx, centerY - mIconSize / 2f);

    mIconShaders[index].setLocalMatrix(matrix);

    Paint paint = mIconPaints[index];
    paint.setAlpha((int) (255 * (1 - progress)));

    float rectLeft = isLeftIcon
            ? centerX - mIconSize / 2f - translation
            : centerX + mIconSize / 2f + translation - iconWidth;

    float rectRight = isLeftIcon
            ? centerX - mIconSize / 2f - translation + iconWidth
            : centerX + mIconSize / 2f + translation;

    canvas.drawRect(
            rectLeft,
            centerY - mIconSize / 2f,
            rectRight,
            centerY + mIconSize / 2f,
            paint
    );
}
 
源代码11 项目: AndroidPDF   文件: PdfPage.java
public Bitmap renderBitmap(int width, int height, RectF pageSliceBounds)
{
    Matrix matrix = new Matrix();
    matrix.postScale(width / getMediaBox().width(), -height / getMediaBox().height());
    matrix.postTranslate(0, height);
    matrix.postTranslate(-pageSliceBounds.left*width, -pageSliceBounds.top*height);
    matrix.postScale(1/pageSliceBounds.width(), 1/pageSliceBounds.height());
    return render(new Rect(0,0,width,height), matrix);
}
 
源代码12 项目: DeviceConnect-Android   文件: CanvasActivity.java
/**
 * Sets a bitmap to ImageView.
 * @param bitmap bitmap
 * @param mode mode
 * @param x x
 * @param y y
 */
private synchronized void setImageBitmap(final Bitmap bitmap, final int mode, final int x, final int y) {
    switch (mode) {
        default:
        case WearConst.MODE_NORMAL:
            Matrix matrix = new Matrix();
            matrix.postTranslate((float) x, (float) y);
            mImageView.setImageBitmap(bitmap);
            mImageView.setScaleType(ImageView.ScaleType.MATRIX);
            mImageView.setImageMatrix(matrix);
            mImageView.setVisibility(View.VISIBLE);
            BoxInsetLayout.LayoutParams normalLayoutParam = new BoxInsetLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER, BOX_ALL);
            mFrameLayout.setLayoutParams(normalLayoutParam);
            break;
        case WearConst.MODE_SCALES:
            mImageView.setImageBitmap(bitmap);
            mImageView.setScaleType(ImageView.ScaleType.FIT_START);
            mImageView.setTranslationX(x);
            mImageView.setTranslationY(y);
            mImageView.setVisibility(View.VISIBLE);
            BoxInsetLayout.LayoutParams scaleLayoutParam = new BoxInsetLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT, Gravity.LEFT | Gravity.TOP);
            mFrameLayout.setLayoutParams(scaleLayoutParam);
            break;
        case WearConst.MODE_FILLS:
            BitmapDrawable bd = new BitmapDrawable(getResources(), bitmap);
            bd.setTileModeX(Shader.TileMode.REPEAT);
            bd.setTileModeY(Shader.TileMode.REPEAT);
            mImageView.setImageDrawable(bd);
            mImageView.setScaleType(ImageView.ScaleType.FIT_XY);
            mImageView.setTranslationX(x);
            mImageView.setTranslationY(y);
            mImageView.setVisibility(View.VISIBLE);
            BoxInsetLayout.LayoutParams fillLayoutParam = new BoxInsetLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT, Gravity.LEFT | Gravity.TOP);
            mFrameLayout.setLayoutParams(fillLayoutParam);
            break;
    }
}
 
源代码13 项目: sealrtc-android   文件: MarkerDrawable.java
private void computePath(Rect bounds) {
    final float currentScale = mCurrentScale;
    final Path path = mPath;
    final RectF rect = mRect;
    final Matrix matrix = mMatrix;

    path.reset();
    int totalSize = Math.min(bounds.width(), bounds.height());

    float initial = mClosedStateSize;
    float destination = totalSize;
    float currentSize = initial + (destination - initial) * currentScale;

    float halfSize = currentSize / 2f;
    float inverseScale = 1f - currentScale;
    float cornerSize = halfSize * inverseScale;
    float[] corners =
            new float[] {
                halfSize,
                halfSize,
                halfSize,
                halfSize,
                halfSize,
                halfSize,
                cornerSize,
                cornerSize
            };
    rect.set(bounds.left, bounds.top, bounds.left + currentSize, bounds.top + currentSize);
    path.addRoundRect(rect, corners, Path.Direction.CCW);
    matrix.reset();
    matrix.postRotate(-45, bounds.left + halfSize, bounds.top + halfSize);
    matrix.postTranslate((bounds.width() - currentSize) / 2, 0);
    float hDiff = (bounds.bottom - currentSize - mExternalOffset) * inverseScale;
    matrix.postTranslate(0, hDiff);
    path.transform(matrix);
}
 
源代码14 项目: ViewSupport   文件: Rotate3dAnimation.java
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
    float degrees = mFromDegrees + ((mToDegrees - mFromDegrees) * interpolatedTime);
    final Matrix matrix = t.getMatrix();

    mCamera.save();

    // 调节深度
    if (mReverse) {
        mCamera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
    } else {
        mCamera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
    }

    // 绕轴旋转
    switch (mAxis) {
        case 1:
            mCamera.rotateX(degrees);
            break;
        case 2:
            mCamera.rotateY(degrees);
            break;
        case 3:
            mCamera.rotateZ(degrees);
            break;
    }

    mCamera.getMatrix(matrix);
    mCamera.restore();

    // 修复失真
    float[] mValues = new float[9];
    matrix.getValues(mValues);          //获取数值
    mValues[6] = mValues[6] / scale;    //数值修正
    mValues[7] = mValues[7] / scale;    //数值修正
    matrix.setValues(mValues);          //重新赋值

    // 设置中心
    matrix.preTranslate(-mCenterX, -mCenterY);
    matrix.postTranslate(mCenterX, mCenterY);
}
 
源代码15 项目: Telegram-FOSS   文件: CameraView.java
private void adjustAspectRatio(int previewWidth, int previewHeight, int rotation) {
    txform.reset();

    int viewWidth = getWidth();
    int viewHeight = getHeight();
    float viewCenterX = viewWidth / 2;
    float viewCenterY = viewHeight / 2;

    float scale;
    if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) {
        scale = Math.max((float) (viewHeight + clipTop + clipBottom) / previewWidth, (float) (viewWidth) / previewHeight);
    } else {
        scale = Math.max((float) (viewHeight + clipTop + clipBottom) / previewHeight, (float) (viewWidth) / previewWidth);
    }

    float previewWidthScaled = previewWidth * scale;
    float previewHeightScaled = previewHeight * scale;

    float scaleX = previewHeightScaled / (viewWidth);
    float scaleY = previewWidthScaled / (viewHeight);

    txform.postScale(scaleX, scaleY, viewCenterX, viewCenterY);

    if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
        txform.postRotate(90 * (rotation - 2), viewCenterX, viewCenterY);
    } else {
        if (Surface.ROTATION_180 == rotation) {
            txform.postRotate(180, viewCenterX, viewCenterY);
        }
    }

    if (mirror) {
        txform.postScale(-1, 1, viewCenterX, viewCenterY);
    }
    if (clipTop != 0) {
        txform.postTranslate(0, -clipTop / 2);
    } else if (clipBottom != 0) {
        txform.postTranslate(0, clipBottom / 2);
    }

    textureView.setTransform(txform);

    Matrix matrix = new Matrix();
    if (cameraSession != null) {
        matrix.postRotate(cameraSession.getDisplayOrientation());
    }
    matrix.postScale(viewWidth / 2000f, viewHeight / 2000f);
    matrix.postTranslate(viewWidth / 2f, viewHeight / 2f);
    matrix.invert(this.matrix);
}
 
源代码16 项目: JCropImageView   文件: JCropImageView.java
@TargetApi(VERSION_CODES.JELLY_BEAN)
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    Drawable d = getDrawable();
    if (d != null && mCropType > -1) {

        final int dw = d.getIntrinsicWidth();
        final int dh = d.getIntrinsicHeight();
        int dx = 0, dy = 0;
        int msWidth = 0, msHeight = 0;
        int theoryw = 0, theoryh = 0;
        float scalew = 0, scaleh = 0;
        float scale = 0;

        if (mCropType <= CropType.FIT_FILL) { // fit width || bestfit
            // 1. get anchor by width. constrain to drawablewidth if wrap-content
            msWidth = MeasureSpec.getSize(widthMeasureSpec); // the view width
            if (getLayoutParams().width == LayoutParams.WRAP_CONTENT) { // wrap
                msWidth = dw < msWidth ? dw : msWidth;
            }

            // 2. compute scale and theoretical height
            scalew = (float) msWidth / dw; // scale_via_width
            theoryh = (int) (dh * scalew); // theoretical = height x scale_via_width
        }

        if (mCropType >= CropType.FIT_FILL) {// fit bestfit || height
            // 1. get anchor by height. constrain to drawableheight if wrap-content
            msHeight = MeasureSpec.getSize(heightMeasureSpec); // the view height
            if (getLayoutParams().height == LayoutParams.WRAP_CONTENT) { // wrap
                msHeight = dh < msHeight ? dh : msHeight;
            }

            // 2. compute scale and theoretical width
            scaleh = (float) msHeight / dh; // scale_via_height
            theoryw = (int) (dw * scaleh); // theoretical = width x scale_via_height
        }

        if (scalew > scaleh) { // fit width
            scale = scalew;

            // 3. constrain by maxheight
            // if match_parent then additional constraint if viewport < maxheight
            // if wrap_content then anything works even if viewport < or >  maxheight
            int maxHeight = getMaxHeight();
            msHeight = getLayoutParams().height;
            if (msHeight >= LayoutParams.MATCH_PARENT) { // match parent
                if (msHeight == LayoutParams.MATCH_PARENT) {
                    msHeight = MeasureSpec.getSize(heightMeasureSpec);
                }
                maxHeight = msHeight < maxHeight ? msHeight : maxHeight;
            }
            msHeight = theoryh > maxHeight ? maxHeight : theoryh; // limited height

            // 4. translate
            if (mCropAlign >= CropAlign.ALIGN_CENTER) {
                // AlignTo.ALIGN_CENTER || AlignTo.ALIGN_LEFT || AlignTo.ALIGN_RIGHT
                // if you want center crop shift it up by 50% aka 0.5f
                dy = (int)( (msHeight - theoryh) * 0.5f + 0.5f ); // + 0.5f for rounding
            } else if (mCropAlign == CropAlign.ALIGN_BOTTOM) {
                // AlignTo.ALIGN_BOTTOM
                // if you want bottom crop shift it up by 100% aka 1.0f
                dy = (int)( (msHeight - theoryh) * 1.0f + 0.5f ); // + 0.5f for rounding
            }

        } else { // fit height
            scale = scaleh;

            // 3. constrain by maxwidth
            // if match_parent then additional constraint if viewport < maxwidth
            // if wrap_content then anything works even if viewport < or >  maxwidth
            int maxWidth = getMaxWidth();
            msWidth = getLayoutParams().width;
            if (msWidth >= LayoutParams.MATCH_PARENT) { // match parent or is set
                if (msWidth == LayoutParams.MATCH_PARENT) {
                    msWidth = MeasureSpec.getSize(widthMeasureSpec);
                }
                maxWidth = msWidth < maxWidth ? msWidth : maxWidth;
            }
            msWidth = theoryw > maxWidth ? maxWidth : theoryw; // limited width

            if (mCropAlign <= CropAlign.ALIGN_CENTER) {
                // AlignTo.ALIGN_CENTER || AlignTo.ALIGN_TOP || AlignTo.ALIGN_BOTTOM
                // if you want center crop shift it left by 50% aka 0.5f
                dx = (int)( (msWidth - theoryw) * 0.5f + 0.5f ); // + 0.5f for rounding
            } else if (mCropAlign == CropAlign.ALIGN_RIGHT) { //AlignTo.ALIGN_RIGHT
                // if you want right crop shift right up by 100% aka 1.0f
                dx = (int)( (msWidth - theoryw) * 1.0f + 0.5f ); // + 0.5f for rounding
            }
        }

        // this is to scale it only by width - the pivot point is at (0,0)
        // for top crop we dont need to translate it
        Matrix matrix = getImageMatrix();
        matrix.setScale(scale, scale);
        matrix.postTranslate(dx, dy);
        setImageMatrix(matrix);
        setMeasuredDimension(msWidth, msHeight);
    }
    else super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
 
源代码17 项目: ml   文件: ImageUtils.java
/**
 * Returns a transformation matrix from one reference frame into another.
 * Handles cropping (if maintaining aspect ratio is desired) and rotation.
 *
 * @param srcWidth Width of source frame.
 * @param srcHeight Height of source frame.
 * @param dstWidth Width of destination frame.
 * @param dstHeight Height of destination frame.
 * @param applyRotation Amount of rotation to apply from one frame to another.
 *  Must be a multiple of 90.
 * @param maintainAspectRatio If true, will ensure that scaling in x and y remains constant,
 * cropping the image if necessary.
 * @return The transformation fulfilling the desired requirements.
 */
public static Matrix getTransformationMatrix(
        final int srcWidth,
        final int srcHeight,
        final int dstWidth,
        final int dstHeight,
        final int applyRotation,
        final boolean maintainAspectRatio) {
    final Matrix matrix = new Matrix();

    if (applyRotation != 0) {
        if (applyRotation % 90 != 0) {
            Logger.debug("Rotation of %d % 90 != 0", applyRotation);
        }

        // Translate so center of image is at origin.
        matrix.postTranslate(-srcWidth / 2.0f, -srcHeight / 2.0f);

        // Rotate around origin.
        matrix.postRotate(applyRotation);
    }

    // Account for the already applied rotation, if any, and then determine how
    // much scaling is needed for each axis.
    final boolean transpose = (Math.abs(applyRotation) + 90) % 180 == 0;

    final int inWidth = transpose ? srcHeight : srcWidth;
    final int inHeight = transpose ? srcWidth : srcHeight;

    // Apply scaling if necessary.
    if (inWidth != dstWidth || inHeight != dstHeight) {
        final float scaleFactorX = dstWidth / (float) inWidth;
        final float scaleFactorY = dstHeight / (float) inHeight;

        if (maintainAspectRatio) {
            // Scale by minimum factor so that dst is filled completely while
            // maintaining the aspect ratio. Some image may fall off the edge.
            final float scaleFactor = Math.max(scaleFactorX, scaleFactorY);
            matrix.postScale(scaleFactor, scaleFactor);
        } else {
            // Scale exactly to fill dst from src.
            matrix.postScale(scaleFactorX, scaleFactorY);
        }
    }

    if (applyRotation != 0) {
        // Translate back from origin centered reference to destination frame.
        matrix.postTranslate(dstWidth / 2.0f, dstHeight / 2.0f);
    }

    return matrix;
}
 
源代码18 项目: PinchImageView   文件: PinchImageView.java
/**
 * 双击后放大或者缩小
 *
 * 将图片缩放比例缩放到nextScale指定的值.
 * 但nextScale值不能大于最大缩放值不能小于fit center情况下的缩放值.
 * 将双击的点尽量移动到控件中心.
 *
 * @param x 双击的点
 * @param y 双击的点
 *
 * @see #calculateNextScale(float, float)
 * @see #getMaxScale()
 */
private void doubleTap(float x, float y) {
    if (!isReady()) {
        return;
    }
    //获取第一层变换矩阵
    Matrix innerMatrix = MathUtils.matrixTake();
    getInnerMatrix(innerMatrix);
    //当前总的缩放比例
    float innerScale = MathUtils.getMatrixScale(innerMatrix)[0];
    float outerScale = MathUtils.getMatrixScale(mOuterMatrix)[0];
    float currentScale = innerScale * outerScale;
    //控件大小
    float displayWidth = getWidth();
    float displayHeight = getHeight();
    //最大放大大小
    float maxScale = getMaxScale();
    //接下来要放大的大小
    float nextScale = calculateNextScale(innerScale, outerScale);
    //如果接下来放大大于最大值或者小于fit center值,则取边界
    if (nextScale > maxScale) {
        nextScale = maxScale;
    }
    if (nextScale < innerScale) {
        nextScale = innerScale;
    }
    //开始计算缩放动画的结果矩阵
    Matrix animEnd = MathUtils.matrixTake(mOuterMatrix);
    //计算还需缩放的倍数
    animEnd.postScale(nextScale / currentScale, nextScale / currentScale, x, y);
    //将放大点移动到控件中心
    animEnd.postTranslate(displayWidth / 2f - x, displayHeight / 2f - y);
    //得到放大之后的图片方框
    Matrix testMatrix = MathUtils.matrixTake(innerMatrix);
    testMatrix.postConcat(animEnd);
    RectF testBound = MathUtils.rectFTake(0, 0, getDrawable().getIntrinsicWidth(), getDrawable().getIntrinsicHeight());
    testMatrix.mapRect(testBound);
    //修正位置
    float postX = 0;
    float postY = 0;
    if (testBound.right - testBound.left < displayWidth) {
        postX = displayWidth / 2f - (testBound.right + testBound.left) / 2f;
    } else if (testBound.left > 0) {
        postX = -testBound.left;
    } else if (testBound.right < displayWidth) {
        postX = displayWidth - testBound.right;
    }
    if (testBound.bottom - testBound.top < displayHeight) {
        postY = displayHeight / 2f - (testBound.bottom + testBound.top) / 2f;
    } else if (testBound.top > 0) {
        postY = -testBound.top;
    } else if (testBound.bottom < displayHeight) {
        postY = displayHeight - testBound.bottom;
    }
    //应用修正位置
    animEnd.postTranslate(postX, postY);
    //清理当前可能正在执行的动画
    cancelAllAnimator();
    //启动矩阵动画
    mScaleAnimator = new ScaleAnimator(mOuterMatrix, animEnd);
    mScaleAnimator.start();
    //清理临时变量
    MathUtils.rectFGiven(testBound);
    MathUtils.matrixGiven(testMatrix);
    MathUtils.matrixGiven(animEnd);
    MathUtils.matrixGiven(innerMatrix);
}
 
源代码19 项目: android-yolo-v2   文件: ImageUtils.java
public static Matrix getTransformationMatrix(final int srcWidth, final int srcHeight,
                                             final int dstWidth, final int dstHeight,
                                             final int applyRotation, final boolean maintainAspectRatio) {
    final Matrix matrix = new Matrix();

    if (applyRotation != 0) {
        // Translate so center of image is at origin.
        matrix.postTranslate(-srcWidth / 2.0f, -srcHeight / 2.0f);

        // Rotate around origin.
        matrix.postRotate(applyRotation);
    }

    // Account for the already applied rotation, if any, and then determine how
    // much scaling is needed for each axis.
    final boolean transpose = (Math.abs(applyRotation) + 90) % 180 == 0;

    final int inWidth = transpose ? srcHeight : srcWidth;
    final int inHeight = transpose ? srcWidth : srcHeight;

    // Apply scaling if necessary.
    if (inWidth != dstWidth || inHeight != dstHeight) {
        final float scaleFactorX = dstWidth / (float) inWidth;
        final float scaleFactorY = dstHeight / (float) inHeight;

        if (maintainAspectRatio) {
            // Scale by minimum factor so that dst is filled completely while
            // maintaining the aspect ratio. Some image may fall off the edge.
            final float scaleFactor = Math.max(scaleFactorX, scaleFactorY);
            matrix.postScale(scaleFactor, scaleFactor);
        } else {
            // Scale exactly to fill dst from src.
            matrix.postScale(scaleFactorX, scaleFactorY);
        }
    }

    if (applyRotation != 0) {
        // Translate back from origin centered reference to destination frame.
        matrix.postTranslate(dstWidth / 2.0f, dstHeight / 2.0f);
    }

    return matrix;
}
 
源代码20 项目: LLApp   文件: PinchImageView.java
/**
 * 当缩放操作结束动画
 *
 * 如果图片超过边界,找到最近的位置动画恢复.
 * 如果图片缩放尺寸超过最大值或者最小值,找到最近的值动画恢复.
 */
private void scaleEnd() {
    if (!isReady()) {
        return;
    }
    //是否修正了位置
    boolean change = false;
    //获取图片整体的变换矩阵
    Matrix currentMatrix = MathUtils.matrixTake();
    getCurrentImageMatrix(currentMatrix);
    //整体缩放比例
    float currentScale = MathUtils.getMatrixScale(currentMatrix)[0];
    //第二层缩放比例
    float outerScale = MathUtils.getMatrixScale(mOuterMatrix)[0];
    //控件大小
    float displayWidth = getWidth();
    float displayHeight = getHeight();
    //最大缩放比例
    float maxScale = getMaxScale();
    //比例修正
    float scalePost = 1f;
    //位置修正
    float postX = 0;
    float postY = 0;
    //如果整体缩放比例大于最大比例,进行缩放修正
    if (currentScale > maxScale) {
        scalePost = maxScale / currentScale;
    }
    //如果缩放修正后整体导致第二层缩放小于1(就是图片比fit center状态还小),重新修正缩放
    if (outerScale * scalePost < 1f) {
        scalePost = 1f / outerScale;
    }
    //如果缩放修正不为1,说明进行了修正
    if (scalePost != 1f) {
        change = true;
    }
    //尝试根据缩放点进行缩放修正
    Matrix testMatrix = MathUtils.matrixTake(currentMatrix);
    testMatrix.postScale(scalePost, scalePost, mLastMovePoint.x, mLastMovePoint.y);
    RectF testBound = MathUtils.rectFTake(0, 0, getDrawable().getIntrinsicWidth(), getDrawable().getIntrinsicHeight());
    //获取缩放修正后的图片方框
    testMatrix.mapRect(testBound);
    //检测缩放修正后位置有无超出,如果超出进行位置修正
    if (testBound.right - testBound.left < displayWidth) {
        postX = displayWidth / 2f - (testBound.right + testBound.left) / 2f;
    } else if (testBound.left > 0) {
        postX = -testBound.left;
    } else if (testBound.right < displayWidth) {
        postX = displayWidth - testBound.right;
    }
    if (testBound.bottom - testBound.top < displayHeight) {
        postY = displayHeight / 2f - (testBound.bottom + testBound.top) / 2f;
    } else if (testBound.top > 0) {
        postY = -testBound.top;
    } else if (testBound.bottom < displayHeight) {
        postY = displayHeight - testBound.bottom;
    }
    //如果位置修正不为0,说明进行了修正
    if (postX != 0 || postY != 0) {
        change = true;
    }
    //只有有执行修正才执行动画
    if (change) {
        //计算结束矩阵
        Matrix animEnd = MathUtils.matrixTake(mOuterMatrix);
        animEnd.postScale(scalePost, scalePost, mLastMovePoint.x, mLastMovePoint.y);
        animEnd.postTranslate(postX, postY);
        //清理当前可能正在执行的动画
        cancelAllAnimator();
        //启动矩阵动画
        mScaleAnimator = new ScaleAnimator(mOuterMatrix, animEnd);
        mScaleAnimator.start();
        //清理临时变量
        MathUtils.matrixGiven(animEnd);
    }
    //清理临时变量
    MathUtils.rectFGiven(testBound);
    MathUtils.matrixGiven(testMatrix);
    MathUtils.matrixGiven(currentMatrix);
}