Android ImageView Matrix Rotate, Scale, Skew, Translate Example

android.graphics.Matrix is the class that be used to process images in android. This article will show you examples of how to use android.graphics.Matrix to rotate, scale, skew and translate bitmap images in android.

1. Matrix Methods Introduce.

  1. Image is composed of pixels, and the transformation of the image is mainly to deal with each pixel of the picture, and the corresponding transformation of each pixel can complete the transformation of the image.
  2. android.graphics.Matrix provide below methods to process images.
  3. setRotate(float degree) : Rotate image for angle degree. Axis is (0, 0).
  4. setRotate(float degree,float x,float y) : Similar with setRotate(float degree), but axis is (x, y).
    rotate-diagram
  5. setScale(float scaleX,float scaleY) : Scale image, scaleX and scaleY are the scaling ratio in X and Y direction.
  6. setScale(float scaleX,float scaleY,float x,float y) : Similar with setScale(float scaleX,float scaleY), but axis is (x, y).
    sacle-diagram
  7. setSkew(float skewX,float skewY) : Skew image, skewX and skewY are the skew ratio in X and Y direction.
  8. setSkew(float skewX,float skewY,float x,float y) : Similar with setSkew(float skewX,float skewY), but axis is (x, y).
    skew-x-diagram
    skew-y-diagram
  9. setTranslate(float x, float y): Move the image to another place, x and y are the distance between the new point with the original point.
    translate-diagram

2. Use Matrix To Process Images Steps.

  1. Create a new Bitmap object based on the original image’s width and height.
     Bitmap translateBitmap = Bitmap.createBitmap(originalImageWith + xTranslate, 
                           originalImageHeight + yTranslate, originalImageConfig);
  2. Create a Canvas object based on the above Bitmap object.
     Canvas translateCanvas = new Canvas(translateBitmap);
  3. Create Matrix object, and use one of it’s methods introduced in section 1 to set transformation information.
     Matrix translateMatrix = new Matrix();
    
     // Set x y translate value.
    
     translateMatrix.setTranslate(xTranslate, yTranslate);
  4. Draw original bitmap image to the newly created Canvas using Matrix effect. So the created Bitmap in step 1 will have the new image effect.
     translateCanvas.drawBitmap(originalBitmap, translateMatrix, new Paint());
  5. Set the newly created Bitmap to an ImageView to show the transformation effect.
     imageViewOriginal.setImageBitmap(translateBitmap);

3. Matrix Example.

  1. Project file structure.
    ./
    ├── app
    │   ├── build.gradle
    │   ├── proguard-rules.pro
    │   └── src
    │       ├── main
    │       │   ├── AndroidManifest.xml
    │       │   ├── java
    │       │   │   └── com
    │       │   │       └── dev2qa
    │       │   │           └── example
    │       │   │               ├── MatrixRotateScaleSkewTranslateActivity.java
    │       │   ├── res
    │       │   │   ├── layout
    │       │   │   │   ├── activity_matrix_rotate_scale_skew_translate.xml
  2. activity_matrix_rotate_scale_skew_translate.xml
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                tools:layout_editor_absoluteY="8dp"
                tools:layout_editor_absoluteX="8dp">
    
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal"
                    android:background="@color/colorBlue">
    
                    <Button
                        android:id="@+id/buttonRotateImage"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:text="Rotate" />
    
                    <Button
                        android:id="@+id/buttonScaleImage"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:text="Scale" />
    
                    <Button
                        android:id="@+id/buttonSkewImage"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:text="Skew" />
    
                    <Button
                        android:id="@+id/buttonTranslateImage"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:text="Translate" />
                </LinearLayout>
    
                <ImageView
                    android:id="@+id/imageViewOriginal"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:minWidth="200sp"
                    android:src="@drawable/img2" />
    
                <ImageView
                    android:id="@+id/imageViewMatrix"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:minWidth="200sp"
                    android:background="@color/colorOrange"/>
    
            </LinearLayout>
    </ScrollView>
  3. MatrixRotateScaleSkewTranslateActivity.java
    import android.graphics.Bitmap;
    import android.graphics.Bitmap.Config;
    import android.graphics.Canvas;
    import android.graphics.Matrix;
    import android.graphics.Paint;
    import android.graphics.drawable.BitmapDrawable;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.Button;
    import android.widget.ImageView;
    
    import java.util.Random;
    
    public class MatrixRotateScaleSkewTranslateActivity extends AppCompatActivity {
    
        // Save current rotate degree.
        private float currRotateDegree = 0;
    
        // Save current x scale.
        private float currXScale = 1;
        private float currYScale = 1;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_matrix_rotate_scale_skew_translate);
    
            final ImageView imageViewOriginal = (ImageView)findViewById(R.id.imageViewOriginal);
            BitmapDrawable originalBitmapDrawable = (BitmapDrawable) imageViewOriginal.getDrawable();
            final Bitmap originalBitmap = originalBitmapDrawable.getBitmap();
            final int originalImageWith = originalBitmap.getWidth();
            final int originalImageHeight = originalBitmap.getHeight();
            final Config originalImageConfig = originalBitmap.getConfig();
    
            /* Matrix rotate example.*/
            Button buttonRotate = (Button)findViewById(R.id.buttonRotateImage);
            buttonRotate.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    currRotateDegree += 60;
                    this.rotateImage(currRotateDegree);
                }
    
                private void rotateImage(float rotateDegree)
                {
                    // Create a bitmap which has same width and height value of original bitmap.
                    Bitmap rotateBitmap = Bitmap.createBitmap(originalImageWith, originalImageHeight, originalImageConfig);
    
                    Canvas rotateCanvas = new Canvas(rotateBitmap);
    
                    Matrix rotateMatrix = new Matrix();
    
                    // Rotate around the center point of the original image.
                    rotateMatrix.setRotate(rotateDegree, originalBitmap.getWidth()/2, originalBitmap.getHeight()/2);
    
                    Paint paint = new Paint();
                    rotateCanvas.drawBitmap(originalBitmap, rotateMatrix, paint);
                    imageViewOriginal.setImageBitmap(rotateBitmap);
                }
            });
    
            /* Matrix scale example. */
            Button buttonScale = (Button)findViewById(R.id.buttonScaleImage);
            buttonScale.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    currXScale -= 0.1;
                    currYScale -= 0.1;
    
                    if(currXScale <= 0)
                    {
                        currXScale = 1;
                    }
    
                    if(currYScale <= 0)
                    {
                        currYScale = 1;
                    }
                    this.scaleImage(currXScale, currYScale);
                }
    
                private void scaleImage(float xScale, float yScale)
                {
                    // Create a bitmap that has scaled width and height value from original bitmap.
                    Bitmap scaleBitmap = Bitmap.createBitmap((int)(originalImageWith * xScale), (int)(originalImageHeight * yScale), originalImageConfig);
    
                    Canvas scaleCanvas = new Canvas(scaleBitmap);
    
                    Matrix scaleMatrix = new Matrix();
    
                    // Set x y scale value.
                    scaleMatrix.setScale(xScale, yScale, originalImageWith/2, originalImageHeight/2);
    
                    Paint paint = new Paint();
                    scaleCanvas.drawBitmap(originalBitmap, scaleMatrix, paint);
                    imageViewOriginal.setImageBitmap(scaleBitmap);
                }
            });
    
             /* Matrix skew example. */
            Button buttonSkew = (Button)findViewById(R.id.buttonSkewImage);
            buttonSkew.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // Generate a random skew value.
                    double randomNumber = Math.random();
    
                    double xSkew = randomNumber;
                    double ySkew = randomNumber;
                    this.skewImage(xSkew, ySkew);
                }
    
                private void skewImage(double xSkew, double ySkew)
                {
                    // According to the skew ratio of the picture, calculate the size of the image after the transformation.
                    int xAfterSkew = (int)(originalImageWith * (1 + xSkew));
                    int yAfterSkew = (int)(originalImageHeight * (1 + ySkew));
    
                    Bitmap skewBitmap = Bitmap.createBitmap(xAfterSkew, yAfterSkew, originalImageConfig);
    
                    Canvas skewCanvas = new Canvas(skewBitmap);
    
                    Matrix skewMatrix = new Matrix();
    
                    // Set x y skew value.
                    skewMatrix.setSkew((float)xSkew, (float)ySkew, originalImageWith/2, originalImageHeight/2);
    
                    Paint paint = new Paint();
                    skewCanvas.drawBitmap(originalBitmap, skewMatrix, paint);
                    imageViewOriginal.setImageBitmap(skewBitmap);
                }
            });
    
            /* Matrix translate example. */
            Button buttonTranslate = (Button)findViewById(R.id.buttonTranslateImage);
            buttonTranslate.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // Generate a random translate value.
                    Random random = new Random();
                    int xTranslate = random.nextInt(1000);
                    int yTranslate = random.nextInt(2000);
                    this.translateImage(xTranslate, yTranslate);
                }
    
                private void translateImage(int xTranslate, int yTranslate)
                {
                    // According to the skew ratio of the picture, calculate the size of the image after the transformation.
                    Bitmap translateBitmap = Bitmap.createBitmap(originalImageWith + xTranslate, originalImageHeight + yTranslate, originalImageConfig);
    
                    Canvas translateCanvas = new Canvas(translateBitmap);
    
                    Matrix translateMatrix = new Matrix();
    
                    // Set x y translate value..
                    translateMatrix.setTranslate(xTranslate, yTranslate);
    
                    Paint paint = new Paint();
                    translateCanvas.drawBitmap(originalBitmap, translateMatrix, paint);
                    imageViewOriginal.setImageBitmap(translateBitmap);
                }
            });
        }
    }

4. Example Demo Video.

  1. Below is this example demo video.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.