Java Code Examples for android.graphics.Matrix#setTranslate()

The following examples show how to use android.graphics.Matrix#setTranslate() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: TransitionUtils.java    From android_9.0.0_r45 with Apache License 2.0 6 votes vote down vote up
/**
 * Creates a View using the bitmap copy of <code>view</code>. If <code>view</code> is large,
 * the copy will use a scaled bitmap of the given view.
 *
 * @param sceneRoot The ViewGroup in which the view copy will be displayed.
 * @param view The view to create a copy of.
 * @param parent The parent of view.
 */
public static View copyViewImage(ViewGroup sceneRoot, View view, View parent) {
    Matrix matrix = new Matrix();
    matrix.setTranslate(-parent.getScrollX(), -parent.getScrollY());
    view.transformMatrixToGlobal(matrix);
    sceneRoot.transformMatrixToLocal(matrix);
    RectF bounds = new RectF(0, 0, view.getWidth(), view.getHeight());
    matrix.mapRect(bounds);
    int left = Math.round(bounds.left);
    int top = Math.round(bounds.top);
    int right = Math.round(bounds.right);
    int bottom = Math.round(bounds.bottom);

    ImageView copy = new ImageView(view.getContext());
    copy.setScaleType(ImageView.ScaleType.CENTER_CROP);
    Bitmap bitmap = createViewBitmap(view, matrix, bounds, sceneRoot);
    if (bitmap != null) {
        copy.setImageBitmap(bitmap);
    }
    int widthSpec = View.MeasureSpec.makeMeasureSpec(right - left, View.MeasureSpec.EXACTLY);
    int heightSpec = View.MeasureSpec.makeMeasureSpec(bottom - top, View.MeasureSpec.EXACTLY);
    copy.measure(widthSpec, heightSpec);
    copy.layout(left, top, right, bottom);
    return copy;
}
 
Example 2
Source File: RadialGradientRippleView.java    From AndroidDigIn with Apache License 2.0 6 votes vote down vote up
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    mScaledBitmap = Bitmap.createScaledBitmap(mOriBitmap, w, h, true);
    mRippleScaledBitmap = Bitmap.createScaledBitmap(mOriBitmap,
            (int) (w * RIPPLE_SCALE_FACTOR), (int) (h * RIPPLE_SCALE_FACTOR), true);
    int width1 = mScaledBitmap.getWidth();
    int height1 = mScaledBitmap.getHeight();
    int width2 = mRippleScaledBitmap.getWidth();
    int height2 = mRippleScaledBitmap.getHeight();
    mDisW = Math.abs(width1 - width2) / 2;
    mDisH = Math.abs(height1 - height2) / 2;//算出两图中点相聚的距离,就是放大后需要矫正的位移距离
    mOriBitmap.recycle();
    mOriBitmap = null;
    //这里的模式无所谓,因为在屏幕外看不到
    mBitmapShader = new BitmapShader(mRippleScaledBitmap,
            Shader.TileMode.MIRROR,//这里的模式无所谓,因为在屏幕外看不到
            Shader.TileMode.MIRROR);
    Matrix matrix = new Matrix();
    matrix.setTranslate(-mDisW, -mDisH);
    mBitmapShader.setLocalMatrix(matrix);
}
 
Example 3
Source File: CutCornerTreatmentTest.java    From material-components-android with Apache License 2.0 6 votes vote down vote up
/**
 * Tests that the {@link CutCornerTreatment} doesn't have rounding error which can lead to
 * incorrectly calculating that the path is not convex.
 */
@Test
public void hasNoMatrixTransformationRoundingError() {
  ShapePath cornerPath = new ShapePath();
  cutCornerTreatment.getCornerPath(90, 1, cornerPath);
  Matrix edgeTransform = new Matrix();
  edgeTransform.setTranslate(DEFAULT_ANGLE, cornerPath.endY);

  path.moveTo(WIDTH, 0);
  path.lineTo(WIDTH, HEIGHT);
  path.lineTo(0, DEFAULT_ANGLE);
  cornerPath.applyToPath(new Matrix(), path);
  shapePath.reset(0, 0);
  shapePath.lineTo(WIDTH - DEFAULT_ANGLE, 0);
  shapePath.applyToPath(edgeTransform, path);

  assertTrue(path.isConvex());
}
 
Example 4
Source File: TransitionUtils.java    From Transitions-Everywhere with Apache License 2.0 6 votes vote down vote up
/**
 * Creates a View using the bitmap copy of <code>view</code>. If <code>view</code> is large,
 * the copy will use a scaled bitmap of the given view.
 *
 * @param sceneRoot The ViewGroup in which the view copy will be displayed.
 * @param view The view to create a copy of.
 * @param parent The parent of view
 */
@NonNull
public static View copyViewImage(@NonNull ViewGroup sceneRoot, @NonNull View view, @NonNull View parent) {
    Matrix matrix = new Matrix();
    matrix.setTranslate(-parent.getScrollX(), -parent.getScrollY());
    ViewUtils.transformMatrixToGlobal(view, matrix);
    ViewUtils.transformMatrixToLocal(sceneRoot, matrix);
    RectF bounds = new RectF(0, 0, view.getWidth(), view.getHeight());
    matrix.mapRect(bounds);
    int left = Math.round(bounds.left);
    int top = Math.round(bounds.top);
    int right = Math.round(bounds.right);
    int bottom = Math.round(bounds.bottom);

    ImageView copy = new ImageView(view.getContext());
    copy.setScaleType(ImageView.ScaleType.CENTER_CROP);
    Bitmap bitmap = createViewBitmap(view, matrix, bounds);
    if (bitmap != null) {
        copy.setImageBitmap(bitmap);
    }
    int widthSpec = View.MeasureSpec.makeMeasureSpec(right - left, View.MeasureSpec.EXACTLY);
    int heightSpec = View.MeasureSpec.makeMeasureSpec(bottom - top, View.MeasureSpec.EXACTLY);
    copy.measure(widthSpec, heightSpec);
    copy.layout(left, top, right, bottom);
    return copy;
}
 
Example 5
Source File: TwoDScrollerListview.java    From 2DScroller with Apache License 2.0 5 votes vote down vote up
@Override
protected boolean getChildStaticTransformation(View child, Transformation t) {

	int topCenterView = mHeightCenter - mChildrenHeightMiddle;
	int childTop      = Math.max(0,child.getTop());
	float offset      = (-childTop + topCenterView)/ (float) mSpaceBetweenViews;
	final Matrix matrix = t.getMatrix();
	if (offset != 0) {
		float absOffset = Math.abs(offset);
		t.clear();
		t.setTransformationType(Transformation.TYPE_MATRIX);

		float px = child.getLeft() + (child.getWidth()) / 2;
		float py = child.getTop() + (child.getHeight()) / 2; 

		if (mTranslatateEnbabled){
			matrix.setTranslate(mTranslate * absOffset, 0);
		}

		if (offset > 0) {
			matrix.preTranslate(-px,0);
			matrix.postTranslate(px,0);
		} else {
			matrix.preTranslate(-px, -py);
			matrix.postTranslate(px, py);
		}
	}
	return true;
}
 
Example 6
Source File: ParameterUtils.java    From android_9.0.0_r45 with Apache License 2.0 5 votes vote down vote up
/**
 * Calculate the effective crop rectangle for this preview viewport;
 * assumes the preview is centered to the sensor and scaled to fit across one of the dimensions
 * without skewing.
 *
 * <p>The preview size must be a subset of the active array size; the resulting
 * rectangle will also be a subset of the active array rectangle.</p>
 *
 * <p>The unzoomed crop rectangle is calculated only.</p>
 *
 * @param activeArray active array dimensions, in sensor space
 * @param previewSize size of the preview buffer render target, in pixels (not in sensor space)
 * @return a rectangle which serves as the preview stream's effective crop region (unzoomed),
 *         in sensor space
 *
 * @throws NullPointerException
 *          if any of the args were {@code null}
 * @throws IllegalArgumentException
 *          if {@code previewSize} is wider or taller than {@code activeArray}
 */
private static Rect getPreviewCropRectangleUnzoomed(Rect activeArray, Size previewSize) {
    if (previewSize.getWidth() > activeArray.width()) {
        throw new IllegalArgumentException("previewSize must not be wider than activeArray");
    } else if (previewSize.getHeight() > activeArray.height()) {
        throw new IllegalArgumentException("previewSize must not be taller than activeArray");
    }

    float aspectRatioArray = activeArray.width() * 1.0f / activeArray.height();
    float aspectRatioPreview = previewSize.getWidth() * 1.0f / previewSize.getHeight();

    float cropH, cropW;
    if (Math.abs(aspectRatioPreview - aspectRatioArray) < ASPECT_RATIO_TOLERANCE) {
        cropH = activeArray.height();
        cropW = activeArray.width();
    } else if (aspectRatioPreview < aspectRatioArray) {
        // The new width must be smaller than the height, so scale the width by AR
        cropH = activeArray.height();
        cropW = cropH * aspectRatioPreview;
    } else {
        // The new height must be smaller (or equal) than the width, so scale the height by AR
        cropW = activeArray.width();
        cropH = cropW / aspectRatioPreview;
    }

    Matrix translateMatrix = new Matrix();
    RectF cropRect = new RectF(/*left*/0, /*top*/0, cropW, cropH);

    // Now center the crop rectangle so its center is in the center of the active array
    translateMatrix.setTranslate(activeArray.exactCenterX(), activeArray.exactCenterY());
    translateMatrix.postTranslate(-cropRect.centerX(), -cropRect.centerY());

    translateMatrix.mapRect(/*inout*/cropRect);

    // Round the rect corners towards the nearest integer values
    return ParamsUtils.createRect(cropRect);
}
 
Example 7
Source File: ImageUtils.java    From AndroidUtilCode with Apache License 2.0 5 votes vote down vote up
/**
 * Return the round bitmap.
 *
 * @param src         The source of bitmap.
 * @param recycle     True to recycle the source of bitmap, false otherwise.
 * @param borderSize  The size of border.
 * @param borderColor The color of border.
 * @return the round bitmap
 */
public static Bitmap toRound(final Bitmap src,
                             @IntRange(from = 0) int borderSize,
                             @ColorInt int borderColor,
                             final boolean recycle) {
    if (isEmptyBitmap(src)) return null;
    int width = src.getWidth();
    int height = src.getHeight();
    int size = Math.min(width, height);
    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    Bitmap ret = Bitmap.createBitmap(width, height, src.getConfig());
    float center = size / 2f;
    RectF rectF = new RectF(0, 0, width, height);
    rectF.inset((width - size) / 2f, (height - size) / 2f);
    Matrix matrix = new Matrix();
    matrix.setTranslate(rectF.left, rectF.top);
    if (width != height) {
        matrix.preScale((float) size / width, (float) size / height);
    }
    BitmapShader shader = new BitmapShader(src, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
    shader.setLocalMatrix(matrix);
    paint.setShader(shader);
    Canvas canvas = new Canvas(ret);
    canvas.drawRoundRect(rectF, center, center, paint);
    if (borderSize > 0) {
        paint.setShader(null);
        paint.setColor(borderColor);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(borderSize);
        float radius = center - borderSize / 2f;
        canvas.drawCircle(width / 2f, height / 2f, radius, paint);
    }
    if (recycle && !src.isRecycled() && ret != src) src.recycle();
    return ret;
}
 
Example 8
Source File: RefreshView.java    From Taurus with Apache License 2.0 5 votes vote down vote up
private void drawJet(Canvas canvas) {
    Matrix matrix = mMatrix;
    matrix.reset();

    float dragPercent = mPercent;
    float rotateAngle = 0;

    // Check overdrag
    if (dragPercent > 1.0f && !mEndOfRefreshing) {
        rotateAngle = (dragPercent % 1) * 10;
        dragPercent = 1.0f;
    }

    float offsetX = ((mScreenWidth * dragPercent) / 2) - mJetWidthCenter;

    float offsetY = mJetTopOffset
            + (mParent.getTotalDragDistance() / 2)
            * (1.0f - dragPercent)
            - mJetHeightCenter;

    if (isRefreshing) {
        if (checkCurrentAnimationPart(AnimationPart.FIRST)) {
            offsetY -= getAnimationPartValue(AnimationPart.FIRST);
        } else if (checkCurrentAnimationPart(AnimationPart.SECOND)) {
            offsetY -= getAnimationPartValue(AnimationPart.SECOND);
        } else if (checkCurrentAnimationPart(AnimationPart.THIRD)) {
            offsetY += getAnimationPartValue(AnimationPart.THIRD);
        } else if (checkCurrentAnimationPart(AnimationPart.FOURTH)) {
            offsetY += getAnimationPartValue(AnimationPart.FOURTH);
        }
    }

    matrix.setTranslate(offsetX, offsetY);

    if (dragPercent == 1.0f) {
        matrix.preRotate(rotateAngle, mJetWidthCenter, mJetHeightCenter);
    }

    canvas.drawBitmap(mJet, matrix, null);
}
 
Example 9
Source File: CropCircleTransformation.java    From AccountBook with GNU General Public License v3.0 5 votes vote down vote up
@Override
public Resource<Bitmap> transform(Resource<Bitmap> resource, int outWidth, int outHeight) {
  Bitmap source = resource.get();
  int size = Math.min(source.getWidth(), source.getHeight());

  int width = (source.getWidth() - size) / 2;
  int height = (source.getHeight() - size) / 2;

  Bitmap bitmap = mBitmapPool.get(size, size, Bitmap.Config.ARGB_8888);
  if (bitmap == null) {
    bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
  }

  Canvas canvas = new Canvas(bitmap);
  Paint paint = new Paint();
  BitmapShader shader =
      new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
  if (width != 0 || height != 0) {
    // source isn't square, move viewport to center
    Matrix matrix = new Matrix();
    matrix.setTranslate(-width, -height);
    shader.setLocalMatrix(matrix);
  }
  paint.setShader(shader);
  paint.setAntiAlias(true);

  float r = size / 2f;
  canvas.drawCircle(r, r, r, paint);

  return BitmapResource.obtain(bitmap, mBitmapPool);
}
 
Example 10
Source File: CropCircleTransformation.java    From droidkaigi2016 with Apache License 2.0 5 votes vote down vote up
@Override
public Bitmap transform(Bitmap source) {
    int size = Math.min(source.getWidth(), source.getHeight());

    int width = (source.getWidth() - size) / 2;
    int height = (source.getHeight() - size) / 2;

    Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_4444);

    Canvas canvas = new Canvas(bitmap);
    Paint paint = new Paint();
    BitmapShader shader =
            new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
    if (width != 0 || height != 0) {
        // source isn't square, move viewport to center
        Matrix matrix = new Matrix();
        matrix.setTranslate(-width, -height);
        shader.setLocalMatrix(matrix);
    }
    paint.setShader(shader);
    paint.setAntiAlias(true);

    float r = size / 2f;
    canvas.drawCircle(r, r, r, paint);

    source.recycle();

    return bitmap;
}
 
Example 11
Source File: TopAlignedImageView.java    From carstream-android-auto with Apache License 2.0 5 votes vote down vote up
private void setupScaleMatrix(int width, int height) {
    if (!mHasFrame) {
        // we have to ensure that we already have frame
        // called and have width and height
        return;
    }
    final Drawable drawable = getDrawable();
    if (drawable == null) {
        // we have to check if drawable is null because
        // when not initialized at startup drawable we can
        // rise NullPointerException
        return;
    }
    Matrix matrix = mMatrix;
    final int intrinsicWidth = drawable.getIntrinsicWidth();
    final int intrinsicHeight = drawable.getIntrinsicHeight();

    float factorWidth = width/(float) intrinsicWidth;
    float factorHeight = height/(float) intrinsicHeight;
    float factor = Math.max(factorHeight, factorWidth);

    // there magic happen and can be adjusted to current
    // needs
    matrix.setTranslate(-intrinsicWidth/2.0f, 0);
    matrix.postScale(factor, factor, 0, 0);
    matrix.postTranslate(width/2.0f, 0);
    setImageMatrix(matrix);
}
 
Example 12
Source File: BitmapUtils.java    From DevUtils with Apache License 2.0 5 votes vote down vote up
/**
 * 图片圆形处理
 * @param bitmap      待操作源图片
 * @param borderSize  边框尺寸
 * @param borderColor 边框颜色
 * @return 圆形处理后的图片
 */
public static Bitmap round(final Bitmap bitmap, @IntRange(from = 0) final int borderSize, @ColorInt final int borderColor) {
    if (isEmpty(bitmap)) return null;

    int width = bitmap.getWidth();
    int height = bitmap.getHeight();
    int size = Math.min(width, height);

    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    float center = size / 2f;
    RectF rectF = new RectF(0, 0, width, height);
    rectF.inset((width - size) / 2f, (height - size) / 2f);

    Matrix matrix = new Matrix();
    matrix.setTranslate(rectF.left, rectF.top);
    if (width != height) {
        matrix.preScale((float) size / width, (float) size / height);
    }
    BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
    shader.setLocalMatrix(matrix);
    paint.setShader(shader);

    Bitmap newBitmap = Bitmap.createBitmap(width, height, bitmap.getConfig());
    Canvas canvas = new Canvas(newBitmap);
    canvas.drawRoundRect(rectF, center, center, paint);

    if (borderSize > 0) {
        paint.setShader(null);
        paint.setColor(borderColor);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(borderSize);
        float radius = center - borderSize / 2f;
        canvas.drawCircle(width / 2f, height / 2f, radius, paint);
    }
    return newBitmap;
}
 
Example 13
Source File: ApolloUtils.java    From mobile-manager-tool with MIT License 5 votes vote down vote up
/**
    * Used to fit a Bitmap nicely inside a View
    * 
    * @param view
    * @param bitmap
    */
@SuppressWarnings("deprecation")
   public static void setBackground(View view, Bitmap bitmap) {

       if (bitmap == null) {
           view.setBackgroundResource(0);
           return;
       }

       int vwidth = view.getWidth();
       int vheight = view.getHeight();
       int bwidth = bitmap.getWidth();
       int bheight = bitmap.getHeight();

       float scalex = (float)vwidth / bwidth;
       float scaley = (float)vheight / bheight;
       float scale = Math.max(scalex, scaley) * 1.0f;

       Bitmap.Config config = Bitmap.Config.ARGB_8888;
       Bitmap background = Bitmap.createBitmap(vwidth, vheight, config);

       Canvas canvas = new Canvas(background);

       Matrix matrix = new Matrix();
       matrix.setTranslate(-bwidth / 2, -bheight / 2);
       matrix.postScale(scale, scale);
       matrix.postTranslate(vwidth / 2, vheight / 2);

       canvas.drawBitmap(bitmap, matrix, null);

       view.setBackgroundDrawable(new BitmapDrawable(view.getResources(), background));
   }
 
Example 14
Source File: BitmapUtil.java    From PaintView with MIT License 5 votes vote down vote up
/**
 * 处理图片绘制位置,在width和height中显示居中
 * @param width
 * @param height
 * @param matrix
 */
public static void setBitmapPosition(Bitmap bitmap, int width, int height, Matrix matrix) {
    float left = (width - bitmap.getWidth()) / 2;
    float top = (height - bitmap.getHeight()) / 2;
    //缩放后
    if (bitmap.getWidth() < width && bitmap.getHeight() < height) {
        matrix.setTranslate(left, top);
    }
    else if (bitmap.getWidth() < width) {
        matrix.setTranslate(left, 0);
    }
    else if (bitmap.getHeight() < height) {
        matrix.setTranslate(0, top);
    }
}
 
Example 15
Source File: CropCircleTransformation.java    From droidkaigi2016 with Apache License 2.0 5 votes vote down vote up
@Override
public Bitmap transform(Bitmap source) {
    int size = Math.min(source.getWidth(), source.getHeight());

    int width = (source.getWidth() - size) / 2;
    int height = (source.getHeight() - size) / 2;

    Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_4444);

    Canvas canvas = new Canvas(bitmap);
    Paint paint = new Paint();
    BitmapShader shader =
            new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
    if (width != 0 || height != 0) {
        // source isn't square, move viewport to center
        Matrix matrix = new Matrix();
        matrix.setTranslate(-width, -height);
        shader.setLocalMatrix(matrix);
    }
    paint.setShader(shader);
    paint.setAntiAlias(true);

    float r = size / 2f;
    canvas.drawCircle(r, r, r, paint);

    source.recycle();

    return bitmap;
}
 
Example 16
Source File: GUIDrawable.java    From geoar-app with Apache License 2.0 4 votes vote down vote up
protected void setFocusToDrawingArea(Canvas canvas){
	Matrix m = new Matrix();
	m.setTranslate(drawableArea.left, drawableArea.top);
	canvas.setMatrix(m);
}
 
Example 17
Source File: MovingImageView.java    From MovingImageView with Apache License 2.0 4 votes vote down vote up
/**
 * Sets the best movement type and scale.
 *
 * @return image scale.
 */
private float calculateTypeAndScale() {
    movementType = MovingViewAnimator.AUTO_MOVE;
    float scale = 1f;
    float scaleByImage = Math.max(imageWidth / canvasWidth, imageHeight / canvasHeight);
    Matrix m = new Matrix();

    //Image is too small to performs any animation, needs a scale
    if (offsetWidth == 0 && offsetHeight == 0) {
        float sW = canvasWidth / imageWidth;
        float sH = canvasHeight / imageHeight;

        if (sW > sH) {
            scale = Math.min(sW, maxRelativeSize);
            m.setTranslate((canvasWidth - imageWidth * scale) / 2f, 0);
            movementType = MovingViewAnimator.VERTICAL_MOVE;

        } else if (sW < sH) {
            scale = Math.min(sH, maxRelativeSize);
            m.setTranslate(0, (canvasHeight - imageHeight * scale) / 2f);
            movementType = MovingViewAnimator.HORIZONTAL_MOVE;

        } else {
            scale = Math.max(sW, maxRelativeSize);
            movementType = (scale == sW) ? MovingViewAnimator.NONE_MOVE :
                    MovingViewAnimator.DIAGONAL_MOVE;
        }

      //Width too small to perform any horizontal animation, scale to width
    } else if (offsetWidth == 0) {
        scale = canvasWidth / imageWidth;
        movementType = MovingViewAnimator.VERTICAL_MOVE;

      //Height too small to perform any vertical animation, scale to height
    } else if (offsetHeight == 0) {
        scale = canvasHeight / imageHeight;
        movementType = MovingViewAnimator.HORIZONTAL_MOVE;

      //Enough size but too big, resize down
    } else if (scaleByImage > maxRelativeSize) {
        scale = maxRelativeSize / scaleByImage;
        if(imageWidth * scale < canvasWidth || imageHeight * scale < canvasHeight) {
            scale = Math.max(canvasWidth / imageWidth, canvasHeight / imageHeight);
        }
    }

    m.preScale(scale, scale);
    setImageMatrix(m);
    return scale;
}
 
Example 18
Source File: ScalingImageView.java    From ShaderEditor with MIT License 4 votes vote down vote up
protected void setMinWidth(RectF rect, Matrix matrix) {
	// don't try to store the drawable dimensions by overriding
	// setImageDrawable() since it is called in the ImageView's
	// constructor and no referenced member of this object will
	// have been initialized yet. So it's best to simply request
	// the dimensions when they are required only.
	RectF srcRect = new RectF(getDrawableRect());

	if (rect == null || matrix == null) {
		return;
	}

	float dw = srcRect.width();
	float dh = srcRect.height();
	float rw = rect.width();
	float rh = rect.height();

	if (dw < 1 || dh < 1 || rw < 1 || rh < 1) {
		return;
	}

	RectF dstRect = new RectF();
	matrix.setTranslate(dw * -.5f, dh * -.5f);
	matrix.postRotate(rotation);
	matrix.mapRect(dstRect, srcRect);

	float xr = rw / dstRect.width();
	float yr = rh / dstRect.height();
	float scale;

	if (scaleType == ImageView.ScaleType.CENTER) {
		scale = 1f;
	} else if (scaleType == ImageView.ScaleType.CENTER_INSIDE) {
		scale = Math.min(xr, yr);
	} else if (scaleType == ImageView.ScaleType.CENTER_CROP) {
		scale = Math.max(xr, yr);
	} else {
		throw new UnsupportedOperationException();
	}

	matrix.postScale(scale, scale);
	matrix.postTranslate(
			Math.round(rect.left + rw * .5f),
			Math.round(rect.top + rh * .5f));

	matrix.mapRect(dstRect, srcRect);

	minWidth = dstRect.width();
}
 
Example 19
Source File: ParameterUtils.java    From android_9.0.0_r45 with Apache License 2.0 4 votes vote down vote up
private static WeightedRectangle convertCameraAreaToActiveArrayRectangle(
        Rect activeArray, ZoomData zoomData, Camera.Area area, boolean usePreviewCrop) {
    Rect previewCrop = zoomData.previewCrop;
    Rect reportedCrop = zoomData.reportedCrop;

    float scaleW = previewCrop.width() * 1.0f /
            (NORMALIZED_RECTANGLE_MAX - NORMALIZED_RECTANGLE_MIN);
    float scaleH = previewCrop.height() * 1.0f /
            (NORMALIZED_RECTANGLE_MAX - NORMALIZED_RECTANGLE_MIN);

    /*
     * Calculate the reported metering region from the non-intersected normalized region
     * by scaling and translating back into active array-relative coordinates.
     */
    Matrix transform = new Matrix();

    // Move top left from (-1000, -1000) to (0, 0)
    transform.setTranslate(/*dx*/NORMALIZED_RECTANGLE_MAX, /*dy*/NORMALIZED_RECTANGLE_MAX);

    // Scale from [0, 2000] back into the preview rectangle
    transform.postScale(scaleW, scaleH);

    // Move the rect so that the [-1000,-1000] point ends up at the preview [left, top]
    transform.postTranslate(previewCrop.left, previewCrop.top);

    Rect cropToIntersectAgainst = usePreviewCrop ? previewCrop : reportedCrop;

    // Now apply the transformation backwards to get the reported metering region
    Rect reportedMetering = ParamsUtils.mapRect(transform, area.rect);
    // Intersect it with the crop region, to avoid reporting out-of-bounds
    // metering regions
    if (!reportedMetering.intersect(cropToIntersectAgainst)) {
        reportedMetering.set(RECTANGLE_EMPTY);
    }

    int weight = area.weight;
    if (weight < MeteringRectangle.METERING_WEIGHT_MIN) {
        Log.w(TAG,
                "convertCameraAreaToMeteringRectangle - rectangle "
                        + stringFromArea(area) + " has too small weight, clip to 0");
        weight = 0;
    }

    return new WeightedRectangle(reportedMetering, area.weight);
}
 
Example 20
Source File: ParameterUtils.java    From android_9.0.0_r45 with Apache License 2.0 4 votes vote down vote up
/**
 * Calculate the actual/effective/reported normalized rectangle data from a metering
 * rectangle.
 *
 * <p>If any of the rectangles are out-of-range of their intended bounding box,
 * the {@link #RECTANGLE_EMPTY empty rectangle} is substituted instead
 * (with a weight of {@code 0}).</p>
 *
 * <p>The metering rectangle is bound by the crop region (effective/reported respectively).
 * The metering {@link Camera.Area area} is bound by {@code [-1000, 1000]}.</p>
 *
 * <p>No parameters are mutated; returns the new metering data.</p>
 *
 * @param activeArraySize active array size of the sensor (e.g. max jpeg size)
 * @param meteringRect the user-specified metering rectangle
 * @param zoomData the calculated zoom data corresponding to this request
 *
 * @return the metering area, the reported/effective metering rectangles
 */
public static MeteringData convertMeteringRectangleToLegacy(
        Rect activeArray, MeteringRectangle meteringRect, ZoomData zoomData) {
    Rect previewCrop = zoomData.previewCrop;

    float scaleW = (NORMALIZED_RECTANGLE_MAX - NORMALIZED_RECTANGLE_MIN) * 1.0f /
            previewCrop.width();
    float scaleH = (NORMALIZED_RECTANGLE_MAX - NORMALIZED_RECTANGLE_MIN) * 1.0f /
            previewCrop.height();

    Matrix transform = new Matrix();
    // Move the preview crop so that top,left is at (0,0), otherwise after scaling
    // the corner bounds will be outside of [-1000, 1000]
    transform.setTranslate(-previewCrop.left, -previewCrop.top);
    // Scale into [0, 2000] range about the center of the preview
    transform.postScale(scaleW, scaleH);
    // Move so that top left of a typical rect is at [-1000, -1000]
    transform.postTranslate(/*dx*/NORMALIZED_RECTANGLE_MIN, /*dy*/NORMALIZED_RECTANGLE_MIN);

    /*
     * Calculate the preview metering region (effective), and the camera1 api
     * normalized metering region.
     */
    Rect normalizedRegionUnbounded = ParamsUtils.mapRect(transform, meteringRect.getRect());

    /*
     * Try to intersect normalized area with [-1000, 1000] rectangle; otherwise
     * it's completely out of range
     */
    Rect normalizedIntersected = new Rect(normalizedRegionUnbounded);

    Camera.Area meteringArea;
    if (!normalizedIntersected.intersect(NORMALIZED_RECTANGLE_DEFAULT)) {
        Log.w(TAG,
                "convertMeteringRectangleToLegacy - metering rectangle too small, " +
                "no metering will be done");
        normalizedIntersected.set(RECTANGLE_EMPTY);
        meteringArea = new Camera.Area(RECTANGLE_EMPTY,
                MeteringRectangle.METERING_WEIGHT_DONT_CARE);
    } else {
        meteringArea = new Camera.Area(normalizedIntersected,
                meteringRect.getMeteringWeight());
    }

    /*
     * Calculate effective preview metering region
     */
    Rect previewMetering = meteringRect.getRect();
    if (!previewMetering.intersect(previewCrop)) {
        previewMetering.set(RECTANGLE_EMPTY);
    }

    /*
     * Calculate effective reported metering region
     * - Transform the calculated metering area back into active array space
     * - Clip it to be a subset of the reported crop region
     */
    Rect reportedMetering;
    {
        Camera.Area normalizedAreaUnbounded = new Camera.Area(
                normalizedRegionUnbounded, meteringRect.getMeteringWeight());
        WeightedRectangle reportedMeteringRect = convertCameraAreaToActiveArrayRectangle(
                activeArray, zoomData, normalizedAreaUnbounded, /*usePreviewCrop*/false);
        reportedMetering = reportedMeteringRect.rect;
    }

    if (DEBUG) {
        Log.v(TAG, String.format(
                "convertMeteringRectangleToLegacy - activeArray = %s, meteringRect = %s, " +
                "previewCrop = %s, meteringArea = %s, previewMetering = %s, " +
                "reportedMetering = %s, normalizedRegionUnbounded = %s",
                activeArray, meteringRect,
                previewCrop, stringFromArea(meteringArea), previewMetering,
                reportedMetering, normalizedRegionUnbounded));
    }

    return new MeteringData(meteringArea, previewMetering, reportedMetering);
}