postRotate自定义imageview上的矩阵比例更改

时间:2019-02-22 10:11:50

标签: android image rotation imageview

以下是我的自定义图片视图-

CropImgImageView extends AppCompatImageView  {

private Matrix imageMatrix;
private MatrixUtils matrixUtils;
private GestureProcessor gestureDetector;

private RectF allowedBounds;
private RectF imageBounds;
private RectF realImageBounds;

private OnImagePositionedListener imagePositionedListener;

private CropImgImageViewConfig config;

private boolean rotated = false;

public CropImgImageView(Context context, CropImgImageViewConfig config) {
    super(context);
    //setLayerType(View.LAYER_TYPE_HARDWARE, null);
    initWith(config);
}

private void initWith(CropImgImageViewConfig c) {
    config = c;
    config.addConfigChangeListener(this);

    imageBounds = new RectF();
    allowedBounds = new RectF();
    realImageBounds = new RectF();

    matrixUtils = new MatrixUtils();

    imageMatrix = new Matrix();
    setScaleType(ScaleType.MATRIX);

    gestureDetector = new GestureProcessor();
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    if (hasImageSize()) {
        placeImageToInitialPosition();
    }
}

public void postRotate(float deltaAngle) {
    if (deltaAngle != 0) {
        updateImageBounds();
        rotated = !rotated;
        printScale(5);

        float[] f = new float[9];
        imageMatrix.getValues(f);
        float scaleX = f[Matrix.MSCALE_X];
        float scaleY = f[Matrix.MSCALE_Y];


        imageMatrix.postRotate(deltaAngle, imageBounds.centerX(), imageBounds.centerY());
        imageMatrix.postScale(scaleX, scaleY);
        setImageMatrix(imageMatrix);
        printScale(6);
        Log.v("CropBound", "W "+getRealImageWidth()+ " H "+getRealImageHeight());
        updateImageBounds();
        Log.v("CropBound", "Bound W "+getImageWidth()+ " H "+getImageHeight());
        //Log.v("CropBound", "View W "+getWidth()+ " H "+getHeight());
        Log.v("CropBound", "Updated W "+getRealImageWidth()+ " H "+getRealImageHeight());
    }
}

private void placeImageToInitialPosition() {
    updateImageBounds();
    moveImageToTheCenter();
    if (config.getScale() == CropImgImageViewConfig.SCALE_UNSPECIFIED) {
        switch (config.getImageInitialPosition()) {
            case CENTER_CROP:
                resizeImageToFillTheView();
                break;
            case CENTER_INSIDE:
                resizeImageToBeInsideTheView();
                break;
        }
        config.setScale(getCurrentScalePercent());
    } else {
        setScalePercent(config.getScale());
    }
    notifyImagePositioned();
}

private void resizeImageToFillTheView() {
    float scale;
    if (getWidth() < getHeight()) {
        scale = ((float) getHeight()) / getImageHeight();
    } else {
        scale = ((float) getWidth()) / getImageWidth();
    }
    scaleImage(scale);
}

private void resizeImageToBeInsideTheView() {
    float scale;
    if (getImageWidth() < getImageHeight()) {
        scale = ((float) getHeight()) / getImageHeight();
    } else {
        scale = ((float) getWidth()) / getImageWidth();
    }
    scaleImage(scale);
}

private void moveImageToTheCenter() {
    updateImageBounds();
    float deltaX = (getWidth() / 2f) - imageBounds.centerX();
    float deltaY = (getHeight() / 2f) - imageBounds.centerY();
    translateImage(deltaX, deltaY);
}

private float calculateMinScale() {
    float viewWidth = getWidth(), viewHeight = getHeight();
    if (getRealImageWidth() <= viewWidth && getRealImageHeight() <= viewHeight) {
        return config.getMinScale();
    }
    float scaleFactor = viewWidth < viewHeight ?
            viewWidth / getRealImageWidth() :
            viewHeight / getRealImageHeight();
    return scaleFactor * 0.8f;
}

private int getRealImageWidth() {
    Drawable image = getDrawable();
    return image != null ? image.getIntrinsicWidth() : -1;
}

private int getRealImageHeight() {
    Drawable image = getDrawable();
    return image != null ? image.getIntrinsicHeight() : -1;
}

public int getImageWidth() {
    return (int) getImgBoundWidth(imageBounds);
}

public int getImageHeight() {
    return (int) getImgBoundHeight(imageBounds);
}

public float getImgBoundWidth(RectF rectF){
    if (rectF.left > rectF.right){
        return rectF.left - rectF.right;
    }else {
        return rectF.right - rectF.left;
    }
}

public float getImgBoundHeight(RectF rectF){
    if (rectF.top > rectF.bottom){
        return rectF.top - rectF.bottom;
    }else {
        return rectF.bottom - rectF.top;
    }
}

public boolean hasImageSize() {
    return getRealImageWidth() != -1 && getRealImageHeight() != -1;
}

public GestureProcessor getImageTransformGestureDetector() {
    return gestureDetector;
}

@Override
public void onNewBounds(RectF bounds) {
    updateImageBounds();
    allowedBounds.set(bounds);
    Log.v("CropBound", "Allowed B "+allowedBounds.left+" "+allowedBounds.right+ " "+allowedBounds.top+ " "+allowedBounds.bottom);
    if (hasImageSize()) {
        post(new Runnable() {
            @Override
            public void run() {
                animateToAllowedBounds();
            }
        });
        updateImageBounds();
        invalidate();
    }
}

private void animateToAllowedBounds() {
    updateImageBounds();
    printScale(1);
    Matrix endMatrix = MatrixUtils.findTransformToAllowedBounds(
            realImageBounds, imageMatrix,
            allowedBounds);
    MatrixAnimator animator = new MatrixAnimator();
    animator.animate(imageMatrix, endMatrix, new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            imageMatrix.set((Matrix) animation.getAnimatedValue());
            printScale(2);
            setImageMatrix(imageMatrix);
            updateImageBounds();
            invalidate();
        }
    });
}

private void setScalePercent(@FloatRange(from = 0.01f, to = 1f) float percent) {
    percent = Math.min(Math.max(0.01f, percent), 1f);
    float desiredScale = config.getMinScale() + config.getMaxScale() * percent;
    float currentScale = matrixUtils.getScaleX(imageMatrix);
    float factor = desiredScale / currentScale;
    scaleImage(factor);
    invalidate();
}

private void scaleImage(float factor) {
    updateImageBounds();
    scaleImage(factor, imageBounds.centerX(), imageBounds.centerY());
}

private void scaleImage(float factor, float pivotX, float pivotY) {
    imageMatrix.postScale(factor, factor, pivotX, pivotY);
    setImageMatrix(imageMatrix);
    updateImageBounds();
}

private void translateImage(float deltaX, float deltaY) {
    imageMatrix.postTranslate(deltaX, deltaY);
    setImageMatrix(imageMatrix);
    if (deltaX > 0.01f || deltaY > 0.01f) {
        updateImageBounds();
    }
}

private void updateImageBounds() {
    printScale(3);
    //if (rotated){
      //  realImageBounds.set(0, 0, getRealImageHeight(), getRealImageWidth());
    //}else {
        realImageBounds.set(0, 0, getRealImageWidth(), getRealImageHeight());
   // }
    imageBounds.set(realImageBounds);
    imageMatrix.mapRect(imageBounds);
    printScale(4);
}

private void printScale(int val){
    float[] f = new float[9];
    imageMatrix.getValues(f);

    float scaleX = f[Matrix.MSCALE_X];
    float scaleY = f[Matrix.MSCALE_Y];
    Log.v("CropBound", "Bounds"+val+" Scale X "+scaleX+ " Y "+scaleY);
}

@Override
public void onConfigChanged() {
    if (Math.abs(getCurrentScalePercent() - config.getScale()) > 0.001f) {
        setScalePercent(config.getScale());
        animateToAllowedBounds();
    }
}

public void setImagePositionedListener(OnImagePositionedListener imagePositionedListener) {
    this.imagePositionedListener = imagePositionedListener;
    if (hasImageSize()) {
        updateImageBounds();
        notifyImagePositioned();
    }
}

public RectF getImageRect() {
    updateImageBounds();
    return new RectF(imageBounds);
}

public void notifyImagePositioned() {
    if (imagePositionedListener != null) {
        RectF imageRect = new RectF(imageBounds);
        CropImgUtils.constrainRectTo(0, 0, getWidth(), getHeight(), imageRect);
        imagePositionedListener.onImagePositioned(imageRect);
    }
}

private float getCurrentScalePercent() {
    return CropImgUtils.boundValue(
            0.01f + (matrixUtils.getScaleX(imageMatrix) - config.getMinScale()) / (config.getMaxScale()),
            0.01f, 1f);
}



}

每次在imageMatrix.postRotate之后ic调用postRotate(90)时,我都会得到像imageMatrix这样的缩放比例

关于初始化-比例尺X 0.79999995 Y 0.79999995 第一次旋转-比例X 0.0 Y 0.0 第二旋转-比例尺X -0.79999995 Y -0.79999995 第三-比例尺X -0.0 Y -0.0 再次缩放X 0.79999995 Y 0.79999995

因此,当比例为0.0时,图像视图会变黑

有解决方案吗?

0 个答案:

没有答案