Principles, code verification and Application of matrix for image transformation in Android (2)

Source: Internet
Author: User

Part 2 code verification

The verification code for various image transformations described in the first section is as follows. A total of 10 cases are listed. To verify a specific situation, you only need to comment out the corresponding code. Images used in the test:


Its size is 162x251.

 

For the results of each transformation, see the description after the code.

Package COM. pat. testtransformmatrix; import android. app. activity; import android. content. context; import android. graphics. bitmap; import android. graphics. bitmapfactory; import android. graphics. canvas; import android. graphics. matrix; import android. OS. bundle; import android. util. log; import android. view. motionevent; import android. view. view; import android. view. window; import android. view. windowmanager; import android. view. view. ontouchlistener; import android. widget. imageview; public class testtransformmatrixactivity extends activityimplementsontouchlistener {private transformmatrixview view; @ override public void oncreate (bundle savedinstancestate) {super. oncreate (savedinstancestate); requestwindowfeature (window. feature_no_title); this. getwindow (). setflags (windowmanager. layoutparams. flag_fullscreen, windowmanager. layoutparams. flag_fullscreen); view = new transformmatrixview (this); view. setscaletype (imageview. scaletype. matrix); view. setontouchlistener (this); setcontentview (View);} class transformmatrixview extends imageview {private Bitmap bitmap; private matrix; Public transformmatrixview (context) {super (context); bitmap = bitmapfactory. decoderesource (getresources (), R. drawable. sophie); matrix = new matrix () ;}@ overrideprotected void ondraw (canvas) {// draw the original image canvas. drawbitmap (bitmap, 0, 0, null); // draw the transformed image canvas. drawbitmap (bitmap, matrix, null); super. ondraw (canvas) ;}@ overridepublic void setimagematrix (matrix) {This. matrix. set (matrix); super. setimagematrix (matrix);} public bitmap getimagebitmap () {return bitmap;} public Boolean ontouch (view V, motionevent e) {If (E. getaction () = motionevent. action_up) {matrix = new matrix (); // output the image width and height (162x251) log. E ("testtransformmatrixactivity", "image size: width x Height =" + view. getimagebitmap (). getwidth () + "X" + view. getimagebitmap (). getheight (); // 1. translation matrix. posttranslate (view. getimagebitmap (). getwidth (), view. getimagebitmap (). getheight (); // pan the view in the X direction. getimagebitmap (). getwidth (), in the Y axis. getimagebitmap (). getheight () view. setimagematrix (matrix); // the following code is used to view the element float [] matrixvalues = new float [9]; matrix. getvalues (matrixvalues); For (INT I = 0; I <3; ++ I) {string temp = new string (); For (Int J = 0; j <3; ++ J) {temp + = matrixvalues [3 * I + J] + "\ t";} log. E ("testtransformmatrixactivity", temp);} // 2. rotate (around the center of the image) // matrix. setrotate (45f, view. getimagebitmap (). getwidth ()/2f, view. getimagebitmap (). getheight ()/2f); // perform the following translation transformation to ensure that the transformed image and the original image do not overlap. // matrix. posttranslate (view. getimagebitmap (). getwidth () * 1.5f, 0f); // view. setimagematrix (matrix); // the following code is used to view the elements in the matrix // float [] matrixvalues = new float [9]; // matrix. getvalues (matrixvalues); // For (INT I = 0; I <3; ++ I) // {// string temp = new string (); // For (Int J = 0; j <3; ++ J) // {// temp + = matrixvalues [3 * I + J] + "\ t "; ///} // log. E ("testtransformmatrixactivity", temp); //} // 3. rotation (around the coordinate origin) + translation (the effect is the same as 2) // matrix. setrotate (45f); // matrix. pretranslate (-1f * view. getimagebitmap (). getwidth ()/2f,-1f * view. getimagebitmap (). getheight ()/2f); // matrix. posttranslate (float) view. getimagebitmap (). getwidth ()/2f, (float) view. getimagebitmap (). getheight ()/2f); // perform the following translation transformation to ensure that the transformed image and the original image do not overlap. // matrix. posttranslate (float) view. getimagebitmap (). getwidth () * 1.5f, 0f); // view. setimagematrix (matrix); // the following code is used to view the elements in the matrix // float [] matrixvalues = new float [9]; // matrix. getvalues (matrixvalues); // For (INT I = 0; I <3; ++ I) // {// string temp = new string (); // For (Int J = 0; j <3; ++ J) // {// temp + = matrixvalues [3 * I + J] + "\ t "; ///} // log. E ("testtransformmatrixactivity", temp); //} // 4. zoom // matrix. setscale (2f, 2f); // the following code is used to view the elements in the matrix // float [] matrixvalues = new float [9]; // matrix. getvalues (matrixvalues); // For (INT I = 0; I <3; ++ I) // {// string temp = new string (); // For (Int J = 0; j <3; ++ J) // {// temp + = matrixvalues [3 * I + J] + "\ t "; ///} // log. E ("testtransformmatrixactivity", temp); //} // perform the following translation transformation, this is purely to make the transformed image and the original image do not overlap // matrix. posttranslate (view. getimagebitmap (). getwidth (), view. getimagebitmap (). getheight (); // view. setimagematrix (matrix); // the following code is used to view the elements in the matrix. // matrixvalues = new float [9]; // matrix. getvalues (matrixvalues); // For (INT I = 0; I <3; ++ I) // {// string temp = new string (); // For (Int J = 0; j <3; ++ J) // {// temp + = matrixvalues [3 * I + J] + "\ t "; ///} // log. E ("testtransformmatrixactivity", temp); //} // 5. miscut-horizontal // matrix. setskew (0.5f, 0f); // the following code is used to view the elements in the matrix // float [] matrixvalues = new float [9]; // matrix. getvalues (matrixvalues); // For (INT I = 0; I <3; ++ I) // {// string temp = new string (); // For (Int J = 0; j <3; ++ J) // {// temp + = matrixvalues [3 * I + J] + "\ t "; ///} // log. E ("testtransformmatrixactivity", temp); //} // perform the following translation transformation, this is purely to make the transformed image and the original image do not overlap // matrix. posttranslate (view. getimagebitmap (). getwidth (), 0f); // view. setimagematrix (matrix); // the following code is used to view the elements in the matrix. // matrixvalues = new float [9]; // matrix. getvalues (matrixvalues); // For (INT I = 0; I <3; ++ I) // {// string temp = new string (); // For (Int J = 0; j <3; ++ J) // {// temp + = matrixvalues [3 * I + J] + "\ t "; ///} // log. E ("testtransformmatrixactivity", temp); //} // 6. miscut-vertical // matrix. setskew (0f, 0.5f); // the following code is used to view the elements in the matrix // float [] matrixvalues = new float [9]; // matrix. getvalues (matrixvalues); // For (INT I = 0; I <3; ++ I) // {// string temp = new string (); // For (Int J = 0; j <3; ++ J) // {// temp + = matrixvalues [3 * I + J] + "\ t "; ///} // log. E ("testtransformmatrixactivity", temp); //} // perform the following translation transformation, this is purely to make the transformed image and the original image do not overlap // matrix. posttranslate (0f, view. getimagebitmap (). getheight (); // view. setimagematrix (matrix); // the following code is used to view the elements in the matrix. // matrixvalues = new float [9]; // matrix. getvalues (matrixvalues); // For (INT I = 0; I <3; ++ I) // {// string temp = new string (); // For (Int J = 0; j <3; ++ J) // {// temp + = matrixvalues [3 * I + J] + "\ t "; ///} // log. E ("testtransformmatrixactivity", temp); //} // 7. miscut-horizontal + vertical // matrix. setskew (0.5f, 0.5f); // the following code is used to view the elements in the matrix // float [] matrixvalues = new float [9]; // matrix. getvalues (matrixvalues); // For (INT I = 0; I <3; ++ I) // {// string temp = new string (); // For (Int J = 0; j <3; ++ J) // {// temp + = matrixvalues [3 * I + J] + "\ t "; ///} // log. E ("testtransformmatrixactivity", temp); //} // perform the following translation transformation, this is purely to make the transformed image and the original image do not overlap // matrix. posttranslate (0f, view. getimagebitmap (). getheight (); // view. setimagematrix (matrix); // the following code is used to view the elements in the matrix. // matrixvalues = new float [9]; // matrix. getvalues (matrixvalues); // For (INT I = 0; I <3; ++ I) // {// string temp = new string (); // For (Int J = 0; j <3; ++ J) // {// temp + = matrixvalues [3 * I + J] + "\ t "; ///} // log. E ("testtransformmatrixactivity", temp); //} // 8. symmetric (horizontal symmetry) // float matrix_values [] = {1f, 0f, 0f, 0f,-1f, 0f, 0f, 0f, 1f}; // matrix. setvalues (matrix_values); // the following code is used to view the elements in the matrix // float [] matrixvalues = new float [9]; // matrix. getvalues (matrixvalues); // For (INT I = 0; I <3; ++ I) // {// string temp = new string (); // For (Int J = 0; j <3; ++ J) // {// temp + = matrixvalues [3 * I + J] + "\ t "; ///} // log. E ("testtransformmatrixactivity", temp); //} // perform the following translation transformation, this is purely to make the transformed image and the original image do not overlap // matrix. posttranslate (0f, view. getimagebitmap (). getheight () * 2f); // view. setimagematrix (matrix); // the following code is used to view the elements in the matrix. // matrixvalues = new float [9]; // matrix. getvalues (matrixvalues); // For (INT I = 0; I <3; ++ I) // {// string temp = new string (); // For (Int J = 0; j <3; ++ J) // {// temp + = matrixvalues [3 * I + J] + "\ t "; ///} // log. E ("testtransformmatrixactivity", temp); //} // 9. symmetric-vertical // float matrix_values [] = {-1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 0f}; // matrix. setvalues (matrix_values); // the following code is used to view the elements in the matrix // float [] matrixvalues = new float [9]; // matrix. getvalues (matrixvalues); // For (INT I = 0; I <3; ++ I) // {// string temp = new string (); // For (Int J = 0; j <3; ++ J) // {// temp + = matrixvalues [3 * I + J] + "\ t "; ///} // log. E ("testtransformmatrixactivity", temp); //} // perform the following translation transformation, this is purely to make the transformed image and the original image do not overlap // matrix. posttranslate (view. getimagebitmap (). getwidth () * 2f, 0f); // view. setimagematrix (matrix); // the following code is used to view the elements in the matrix. // matrixvalues = new float [9]; // matrix. getvalues (matrixvalues); // For (INT I = 0; I <3; ++ I) // {// string temp = new string (); // For (Int J = 0; j <3; ++ J) // {// temp + = matrixvalues [3 * I + J] + "\ t "; ///} // log. E ("testtransformmatrixactivity", temp); //} // 10. symmetric (the axis of symmetry is a straight line y = x) // float matrix_values [] = {0f,-1f, 0f,-1f, 0f, 0f, 0f, 0f, 1f }; // matrix. setvalues (matrix_values); // the following code is used to view the elements in the matrix // float [] matrixvalues = new float [9]; // matrix. getvalues (matrixvalues); // For (INT I = 0; I <3; ++ I) // {// string temp = new string (); // For (Int J = 0; j <3; ++ J) // {// temp + = matrixvalues [3 * I + J] + "\ t "; ///} // log. E ("testtransformmatrixactivity", temp); //} // perform the following translation transformation, this is purely to make the transformed image and the original image do not overlap // matrix. posttranslate (view. getimagebitmap (). getheight () + view. getimagebitmap (). getwidth (), // view. getimagebitmap (). getheight () + view. getimagebitmap (). getwidth (); // view. setimagematrix (matrix); // the following code is used to view the elements in the matrix. // matrixvalues = new float [9]; // matrix. getvalues (matrixvalues); // For (INT I = 0; I <3; ++ I) // {// string temp = new string (); // For (Int J = 0; j <3; ++ J) // {// temp + = matrixvalues [3 * I + J] + "\ t "; ///} // log. E ("testtransformmatrixactivity", temp); //} view. invalidate () ;}return true ;}}

 

In the above Code, the specific results of various transformations and their corresponding transformation matrices are given below.

1. Translation

Output result:

Check the correctness of the above matrix based on the situations described in "1. Translation transformation" in the first part.

 

2. Rotate (around the center of the image)

Output result:

It is actually

Matrix. setrotate (45f, view. getimagebitmap (). getwidth ()/2f, view. getimagebitmap (). getheight ()/2f );

Matrix. posttranslate (view. getimagebitmap (). getwidth () * 1.5f, 0f );

The results of the two statements. According to the formula in "2. Rotation Transformation" in the first part,

Matrix. setrotate (45f, view. getimagebitmap (). getwidth ()/2f, view. getimagebitmap (). getheight ()/2f );

The resulting conversion matrix is:

The Matrix. posttranslate (view. getimagebitmap (). getwidth () * 1.5f, 0f); Means to the left of the matrix, multiply the following matrix:

Post is left multiplication, which we mentioned in the previous theoretical section. We will discuss this issue later.

 

So it is actually:

When the accuracy error is calculated, we can see that the calculated result is consistent with the result directly output by the program.

 

3. Rotate (rotate around the coordinate origin, add two translations, and the effect is the same as 2)

According to the interpretation of the rotation around a certain point in "II. Rotation Transformation" in the first part, it is not difficult to know:

Matrix. setrotate (45f, view. getimagebitmap (). getwidth ()/2f, view. getimagebitmap (). getheight ()/2f );

Equivalent

Matrix. setrotate (45f );

Matrix. pretranslate (-1f * view. getimagebitmap (). getwidth ()/2f,-1f * view. getimagebitmap (). getheight ()/2f );

Matrix. posttranslate ((Float) View. getimagebitmap (). getwidth ()/2f ,(Float) View. getimagebitmap (). getheight ()/2f );

 

The Matrix. setrotate (45f) corresponds to the following matrix:

Matrix. pretranslate (-1f * view. getimagebitmap (). getwidth ()/2f,-1f * view. getimagebitmap (). getheight ()/2f) corresponds to the following matrix:

Because it is pretranslate, it is a first multiplication, that is, a right multiplication, that is, it should appear on the right side of the matrix corresponding to matrix. setrotate (45f.

 

Matrix. posttranslate ((Float) View. getimagebitmap (). getwidth ()/2f ,(Float) View. getimagebitmap (). getheight ()/2f) corresponds to the following matrix:

This time, because it is posttranslate, It is a postmultiplication, that is, a left multiplication, that is, it should appear on the left side of the matrix corresponding to matrix. setrotate (45f.

 

So,

Matrix. setrotate (45f );

Matrix. pretranslate (-1f * view. getimagebitmap (). getwidth ()/2f,-1f * view. getimagebitmap (). getheight ()/2f );

Matrix. posttranslate ((Float) View. getimagebitmap (). getwidth ()/2f ,(Float) View. getimagebitmap (). getheight ()/2f );

The corresponding matrix is:

This is actually the same as the following matrix (45 degrees clockwise around the image Center:

Therefore, the transformed image here is the same as the transformed image in 2.

 

4. Scaling

The two matrices output by the program are:

The second matrix is actually the result of multiplying the following two matrices:

 

You can verify the results by referring to "3. scaling and transformation" and "1. Translation and transformation" in the first part.

 

5. (horizontal)

The two matrices output by the Code are:

The second matrix is actually the result of multiplying the following two matrices:

 

You can verify the results by yourself based on the first part of the "4. Incorrect tangent transformation" and "1. Translation transformation" statements.

 

6. mis-tangent Transformation (vertical mis-tangent)

The two matrices output by the Code are:

The second matrix is actually the result of multiplying the following two matrices:

You can verify the results by yourself based on the first part of the "4. Incorrect tangent transformation" and "1. Translation transformation" statements.

 

7. mis-tangent Transformation (horizontal + vertical mis-tangent)

The two matrices output by the Code are:

The latter is the result of multiplying the following two matrices:

You can verify the results by yourself based on the first part of the "4. Incorrect tangent transformation" and "1. Translation transformation" statements.

 

8. symmetric transformation (horizontal symmetry)

The two matrices output by the Code are:

The latter is the result of multiplying the following two matrices:

 

You can verify the results by referring to the "5. symmetric transformation" and "1. Translation transformation" statements in the first part.

 

9. symmetric transformation (vertical symmetry)

The two matrices output by the Code are:

The latter is the result of multiplying the following two matrices:

 

You can verify the results by referring to the "5. symmetric transformation" and "1. Translation transformation" statements in the first part.

 

10. symmetric transformation (the axis of symmetry is a straight lineY = x)

The two matrices output by the Code are:

The latter is the result of multiplying the following two matrices:

 

You can verify the results by referring to the "5. symmetric transformation" and "1. Translation transformation" statements in the first part.

 

11. Questions about multiplication and multiplication

Because the multiplication operation of the matrix does not meet the exchange law, we have mentioned the first and second multiplication problems many times before, that is, the first multiplication is the right multiplication in the matrix operation, and the second multiplication is the left multiplication in the matrix operation. In fact, the concept of first multiplication and then multiplication is for the time sequence of transformation operations. Left multiplication and right multiplication are for the left and right positions of matrix operations. Take the first part of "2. Rotation and transformation" as an example:

 

The closer it is to the pixel matrix in the original image, the more first multiplication, the more far away from the pixel matrix in the original image, the more then multiplication. In fact, during image processing, the matrix operation is performed from the right to the left. This forms a matrix (right multiplication) on the Right, a more advanced operation (first multiplication), and vice versa.

 

Of course, in practice, if a matrix is specified first, for example, setrotate () is used to specify the matrix in the transformation matrix above, then, the subsequent pre or post operations on the matrix are relative to the intermediate matrix.

 

All of this is actually a natural thing.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.