Search code examples
androidcanvasmatrixscale

Matrix mirror and scale


I am playing some animation where all frames are same height, but different width. All well, but I would like to apply some transformations using matrix for better performance.

On first frame:

  • I randomly decide if I want to apply mirror matrix
  • I measure height to see if I need to apply scale down matrix.

Below is code that almost works. Somehow it is not consistent and frames are sometimes centered and sometimes offset. I don't have experience with matrixes so I would appreciate if someone with more knowledge can confirm/fix/improve transformation procedure. This matrix is supplied to canvas drawing method.

Additionally I would like to control:

  • if scale down is required scale down to exact height (height is my only orientation value)
  • can matrix be used so that all frames will be drawn with bottom-center?

edit: I guess I can control exact scale down size and bottom center position with screenRect (destination rect)?

Basic stripped down code:

RectF screenRect = new RectF(0, 0, ((float) displayWith), ((float) displayHeight));

Matrix mirror = null;
if (isMirror) {
    mirror = new Matrix();
    mirror.setScale(-1, 1);
    mirror.postTranslate(p.x, 0); // position X back to original point
}

Matrix scale = null;
if (isScaleDown) { // down-scale
    scale = new Matrix();
    scale.setRectToRect(imageRect, screenRect, Matrix.ScaleToFit.CENTER);           
}               

// COMBINED TRANSFORMATION MATRIX
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Matrix trans = null;
if (scale != null) trans = scale;
if (mirror != null && trans == null) trans = mirror;
if (mirror != null && trans != null) trans.setConcat(trans, mirror);
return trans;

Solution

  • For those interested, I ended up setting "scale" and "mirror" matrix this way:

    1. matrix.setScale(scaleFactor, scaleFactor); // value between 0..1
    2. matrix.postScale(-1, 1, offsetX, offsetY); // flip vertically and offset to right position
    3. matrix.postTranslate(dx, dy); // final matrix position - for me "bottom-center align"