Implementing Image Transformations with Matrix Operations in Android
Matrix operations in Android provide powerful tools for image manipulation. The Matrix class represents a 3x3 transformation matrix that can scale, rotate, and translate graphical elements.
Matrix transform = new Matrix();
transform.setValues(new float[]{
2, 0, 0,
0, 1, 0,
0, 0, 1
});
// Resulting transformation:
// x' = 2x + 0y + 0z
// y' = 0x + 1y + 0z
// z' = 0x + 0y + 1z (z represents depth)
Common transformations have dedicated methods:
// Uniform scaling
transform.setScale(scaleX, scaleY);
// Rotation (degrees)
transform.setRotate(angle);
For smoother rendering, enable anti-aliasing:
Paint renderPaint = new Paint();
renderPaint.setAntiAlias(true);
Custom rotation pivots can be specified:
// Rotate around image center
transform.setRotate(angle, image.getWidth()/2, image.getHeight()/2);
Tranlsation moves the image:
transform.setTranslate(offsetX, offsetY);
Mirror effects require matrix manipulasion:
// Horizontal mirror effect
transform.setValues(new float[] {
-1, 0, 0,
0, 1, 0,
0, 0, 1
});
// Shift mirrored image right
transform.postTranslate(image.getWidth(), 0);
For partial reflections, create a bitmap with half the height and apply a gradient mask for realistic fading.
Complete implementation example:
public class ImageTransformActivity extends Activity {
private ImageView originalView, transformedView;
@Override
protected void onCreate(Bundle state) {
super.onCreate(state);
setContentView(R.layout.image_transform);
originalView = findViewById(R.id.original_image);
transformedView = findViewById(R.id.transformed_image);
}
public void loadImage(View v) {
Intent picker = new Intent(Intent.ACTION_PICK);
picker.setType("image/*");
startActivityForResult(picker, 0);
}
@Override
protected void onActivityResult(int req, int res, Intent data) {
try {
if (data != null) {
Uri imageUri = data.getData();
Bitmap source = BitmapFactory.decodeStream(
getContentResolver().openInputStream(imageUri));
originalView.setImageBitmap(source);
Bitmap result = Bitmap.createBitmap(
source.getWidth(),
source.getHeight(),
source.getConfig());
Canvas canvas = new Canvas(result);
Matrix transform = new Matrix();
// Apply mirror transformation
transform.setValues(new float[]{
-1, 0, 0,
0, 1, 0,
0, 0, 1
});
transform.postTranslate(source.getWidth(), 0);
Paint paint = new Paint();
paint.setAntiAlias(true);
canvas.drawBitmap(source, transform, paint);
transformedView.setImageBitmap(result);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}