最全Android中图像变换Matrix的原理应用,2024年最新大厂面试会问什么问题

最后

下面是有几位Android行业大佬对应上方技术点整理的一些进阶资料。希望能够帮助到大家提升技术

高级UI,自定义View

UI这块知识是现今使用者最多的。当年火爆一时的Android入门培训,学会这小块知识就能随便找到不错的工作了。

不过很显然现在远远不够了,拒绝无休止的CV,亲自去项目实战,读源码,研究原理吧!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  1. //

  2. //          // 做下面的平移变换,纯粹是为了让变换后的图像和原图像不重叠

  3. //          matrix.postTranslate(view.getImageBitmap().getWidth() * 1.5f, 0f);

  4. //          view.setImageMatrix(matrix);

  5. //

  6. //          // 下面的代码是为了查看matrix中的元素

  7. //          float[] matrixValues = new float[9];

  8. //          matrix.getValues(matrixValues);

  9. //          for(int i = 0; i < 3; ++i)

  10. //          {

  11. //              String temp = new String();

  12. //              for(int j = 0; j < 3; ++j)

  13. //              {

  14. //                  temp += matrixValues[3 * i + j ] + “\t”;

  15. //              }

  16. //              Log.e(“TestTransformMatrixActivity”, temp);

  17. //          }

  18. //          // 3. 旋转(围绕坐标原点) + 平移(效果同2)

  19. //          matrix.setRotate(45f);

  20. //          matrix.preTranslate(-1f * view.getImageBitmap().getWidth() / 2f, -1f * view.getImageBitmap().getHeight() / 2f);

  21. //          matrix.postTranslate((float)view.getImageBitmap().getWidth() / 2f, (float)view.getImageBitmap().getHeight() / 2f);

  22. //

  23. //          // 做下面的平移变换,纯粹是为了让变换后的图像和原图像不重叠

  24. //          matrix.postTranslate((float)view.getImageBitmap().getWidth() * 1.5f, 0f);

  25. //          view.setImageMatrix(matrix);

  26. //

  27. //          // 下面的代码是为了查看matrix中的元素

  28. //          float[] matrixValues = new float[9];

  29. //          matrix.getValues(matrixValues);

  30. //          for(int i = 0; i < 3; ++i)

  31. //          {

  32. //              String temp = new String();

  33. //              for(int j = 0; j < 3; ++j)

  34. //              {

  35. //                  temp += matrixValues[3 * i + j ] + “\t”;

  36. //              }

  37. //              Log.e(“TestTransformMatrixActivity”, temp);

  38. //          }

  39. //          // 4. 缩放

  40. //          matrix.setScale(2f, 2f);

  41. //          // 下面的代码是为了查看matrix中的元素

  42. //          float[] matrixValues = new float[9];

  43. //          matrix.getValues(matrixValues);

  44. //          for(int i = 0; i < 3; ++i)

  45. //          {

  46. //              String temp = new String();

  47. //              for(int j = 0; j < 3; ++j)

  48. //              {

  49. //                  temp += matrixValues[3 * i + j ] + “\t”;

  50. //              }

  51. //              Log.e(“TestTransformMatrixActivity”, temp);

  52. //          }

  53. //

  54. //          // 做下面的平移变换,纯粹是为了让变换后的图像和原图像不重叠

  55. //          matrix.postTranslate(view.getImageBitmap().getWidth(), view.getImageBitmap().getHeight());

  56. //          view.setImageMatrix(matrix);

  57. //

  58. //          // 下面的代码是为了查看matrix中的元素

  59. //          matrixValues = new float[9];

  60. //          matrix.getValues(matrixValues);

  61. //          for(int i = 0; i < 3; ++i)

  62. //          {

  63. //              String temp = new String();

  64. //              for(int j = 0; j < 3; ++j)

  65. //              {

  66. //                  temp += matrixValues[3 * i + j ] + “\t”;

  67. //              }

  68. //              Log.e(“TestTransformMatrixActivity”, temp);

  69. //          }

  70. //          // 5. 错切 - 水平

  71. //          matrix.setSkew(0.5f, 0f);

  72. //          // 下面的代码是为了查看matrix中的元素

  73. //          float[] matrixValues = new float[9];

  74. //          matrix.getValues(matrixValues);

  75. //          for(int i = 0; i < 3; ++i)

  76. //          {

  77. //              String temp = new String();

  78. //              for(int j = 0; j < 3; ++j)

  79. //              {

  80. //                  temp += matrixValues[3 * i + j ] + “\t”;

  81. //              }

  82. //              Log.e(“TestTransformMatrixActivity”, temp);

  83. //          }

  84. //

  85. //          // 做下面的平移变换,纯粹是为了让变换后的图像和原图像不重叠

  86. //          matrix.postTranslate(view.getImageBitmap().getWidth(), 0f);

  87. //          view.setImageMatrix(matrix);

  88. //

  89. //          // 下面的代码是为了查看matrix中的元素

  90. //          matrixValues = new float[9];

  91. //          matrix.getValues(matrixValues);

  92. //          for(int i = 0; i < 3; ++i)

  93. //          {

  94. //              String temp = new String();

  95. //              for(int j = 0; j < 3; ++j)

  96. //              {

  97. //                  temp += matrixValues[3 * i + j ] + “\t”;

  98. //              }

  99. //              Log.e(“TestTransformMatrixActivity”, temp);

  100. //          }

  101. //          // 6. 错切 - 垂直

  102. //          matrix.setSkew(0f, 0.5f);

  103. //          // 下面的代码是为了查看matrix中的元素

  104. //          float[] matrixValues = new float[9];

  105. //          matrix.getValues(matrixValues);

  106. //          for(int i = 0; i < 3; ++i)

  107. //          {

  108. //              String temp = new String();

  109. //              for(int j = 0; j < 3; ++j)

  110. //              {

  111. //                  temp += matrixValues[3 * i + j ] + “\t”;

  112. //              }

  113. //              Log.e(“TestTransformMatrixActivity”, temp);

  114. //          }

  115. //

  116. //          // 做下面的平移变换,纯粹是为了让变换后的图像和原图像不重叠

  117. //          matrix.postTranslate(0f, view.getImageBitmap().getHeight());

  118. //          view.setImageMatrix(matrix);

  119. //

  120. //          // 下面的代码是为了查看matrix中的元素

  121. //          matrixValues = new float[9];

  122. //          matrix.getValues(matrixValues);

  123. //          for(int i = 0; i < 3; ++i)

  124. //          {

  125. //              String temp = new String();

  126. //              for(int j = 0; j < 3; ++j)

  127. //              {

  128. //                  temp += matrixValues[3 * i + j ] + “\t”;

  129. //              }

  130. //              Log.e(“TestTransformMatrixActivity”, temp);

  131. //          }

  132. //          7. 错切 - 水平 + 垂直

  133. //          matrix.setSkew(0.5f, 0.5f);

  134. //          // 下面的代码是为了查看matrix中的元素

  135. //          float[] matrixValues = new float[9];

  136. //          matrix.getValues(matrixValues);

  137. //          for(int i = 0; i < 3; ++i)

  138. //          {

  139. //              String temp = new String();

  140. //              for(int j = 0; j < 3; ++j)

  141. //              {

  142. //                  temp += matrixValues[3 * i + j ] + “\t”;

  143. //              }

  144. //              Log.e(“TestTransformMatrixActivity”, temp);

  145. //          }

  146. //

  147. //          // 做下面的平移变换,纯粹是为了让变换后的图像和原图像不重叠

  148. //          matrix.postTranslate(0f, view.getImageBitmap().getHeight());

  149. //          view.setImageMatrix(matrix);

  150. //

  151. //          // 下面的代码是为了查看matrix中的元素

  152. //          matrixValues = new float[9];

  153. //          matrix.getValues(matrixValues);

  154. //          for(int i = 0; i < 3; ++i)

  155. //          {

  156. //              String temp = new String();

  157. //              for(int j = 0; j < 3; ++j)

  158. //              {

  159. //                  temp += matrixValues[3 * i + j ] + “\t”;

  160. //              }

  161. //              Log.e(“TestTransformMatrixActivity”, temp);

  162. //          }

  163. //          // 8. 对称 (水平对称)

  164. //          float matrix_values[] = {1f, 0f, 0f, 0f, -1f, 0f, 0f, 0f, 1f};

  165. //          matrix.setValues(matrix_values);

  166. //          // 下面的代码是为了查看matrix中的元素

  167. //          float[] matrixValues = new float[9];

  168. //          matrix.getValues(matrixValues);

  169. //          for(int i = 0; i < 3; ++i)

  170. //          {

  171. //              String temp = new String();

  172. //              for(int j = 0; j < 3; ++j)

  173. //              {

  174. //                  temp += matrixValues[3 * i + j ] + “\t”;

  175. //              }

  176. //              Log.e(“TestTransformMatrixActivity”, temp);

  177. //          }

  178. //

  179. //          // 做下面的平移变换,纯粹是为了让变换后的图像和原图像不重叠

  180. //          matrix.postTranslate(0f, view.getImageBitmap().getHeight() * 2f);

  181. //          view.setImageMatrix(matrix);

  182. //

  183. //          // 下面的代码是为了查看matrix中的元素

  184. //          matrixValues = new float[9];

  185. //          matrix.getValues(matrixValues);

  186. //          for(int i = 0; i < 3; ++i)

  187. //          {

  188. //              String temp = new String();

  189. //              for(int j = 0; j < 3; ++j)

  190. //              {

  191. //                  temp += matrixValues[3 * i + j ] + “\t”;

  192. //              }

  193. //              Log.e(“TestTransformMatrixActivity”, temp);

  194. //          }

  195. //          // 9. 对称 - 垂直

  196. //          float matrix_values[] = {-1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f};

  197. //          matrix.setValues(matrix_values);

  198. //          // 下面的代码是为了查看matrix中的元素

  199. //          float[] matrixValues = new float[9];

  200. //          matrix.getValues(matrixValues);

  201. //          for(int i = 0; i < 3; ++i)

  202. //          {

  203. //              String temp = new String();

  204. //              for(int j = 0; j < 3; ++j)

  205. //              {

  206. //                  temp += matrixValues[3 * i + j ] + “\t”;

  207. //              }

  208. //              Log.e(“TestTransformMatrixActivity”, temp);

  209. //          }

  210. //

  211. //          // 做下面的平移变换,纯粹是为了让变换后的图像和原图像不重叠

  212. //          matrix.postTranslate(view.getImageBitmap().getWidth() * 2f, 0f);

  213. //          view.setImageMatrix(matrix);

  214. //

  215. //          // 下面的代码是为了查看matrix中的元素

  216. //          matrixValues = new float[9];

  217. //          matrix.getValues(matrixValues);

  218. //          for(int i = 0; i < 3; ++i)

  219. //          {

  220. //              String temp = new String();

  221. //              for(int j = 0; j < 3; ++j)

  222. //              {

  223. //                  temp += matrixValues[3 * i + j ] + “\t”;

  224. //              }

  225. //              Log.e(“TestTransformMatrixActivity”, temp);

  226. //          }

  227. //          // 10. 对称(对称轴为直线y = x)

  228. //          float matrix_values[] = {0f, -1f, 0f, -1f, 0f, 0f, 0f, 0f, 1f};

  229. //          matrix.setValues(matrix_values);

  230. //          // 下面的代码是为了查看matrix中的元素

  231. //          float[] matrixValues = new float[9];

  232. //          matrix.getValues(matrixValues);

  233. //          for(int i = 0; i < 3; ++i)

  234. //          {

  235. //              String temp = new String();

  236. //              for(int j = 0; j < 3; ++j)

  237. //              {

  238. //                  temp += matrixValues[3 * i + j ] + “\t”;

  239. //              }

  240. //              Log.e(“TestTransformMatrixActivity”, temp);

  241. //          }

  242. //

  243. //          // 做下面的平移变换,纯粹是为了让变换后的图像和原图像不重叠

  244. //          matrix.postTranslate(view.getImageBitmap().getHeight() + view.getImageBitmap().getWidth(),

  245. //                  view.getImageBitmap().getHeight() + view.getImageBitmap().getWidth());

  246. //          view.setImageMatrix(matrix);

  247. //

  248. //          // 下面的代码是为了查看matrix中的元素

  249. //          matrixValues = new float[9];

  250. //          matrix.getValues(matrixValues);

  251. //          for(int i = 0; i < 3; ++i)

  252. //          {

  253. //              String temp = new String();

  254. //              for(int j = 0; j < 3; ++j)

  255. //              {

  256. //                  temp += matrixValues[3 * i + j ] + “\t”;

  257. //              }

  258. //              Log.e(“TestTransformMatrixActivity”, temp);

  259. //          }

  260. view.invalidate();

  261. }

  262. return true;

  263. }

  264. }


  265.   

第三部分 应用

在这一部分,我们会将前面两部分所了解到的内容和Android手势结合起来,利用各种不同的手势对图像进行平移、缩放和旋转,前面两项都是在实践中经常需要用到的功能,后一项据说苹果也是最近才加上的,而实际上在Android中,咱们通过自己的双手,也可以很轻松地实现之。

首先创建一个Android项目PatImageView,同时创建一个Activity:PatImageViewActivity。完成这一步后, 记得在AndroidManifest.xml中增加如下许可:

uses-permissionandroid:name=_“android.permission.VIBRATE”_/

因为我们将要通过短按还是长按,来确定将图片到底是缩放还是旋转。

现在来创建一个ImageView的派生类:PatImageView,其代码(PatImageView.java)如下(2011-11-22 revised):

[java]  view plain copy

  1. package com.pat.imageview;

  2. import android.app.Service;

  3. import android.content.Context;

  4. import android.graphics.Matrix;

  5. import android.graphics.PointF;

  6. import android.os.Vibrator;

  7. import android.util.FloatMath;

  8. import android.view.GestureDetector;

  9. import android.view.MotionEvent;

  10. import android.view.View;

  11. import android.widget.ImageView;

  12. public class PatImageView extends ImageView

  13. {

  14. private Matrix matrix;

  15. private Matrix savedMatrix;

  16. private boolean long_touch = false;

  17. private static int NONE = 0;

  18. private static int DRAG = 1;    // 拖动

  19. private static int ZOOM = 2;    // 缩放

  20. private static int ROTA = 3;    // 旋转

  21. private int mode = NONE;

  22. private PointF startPoint;

  23. private PointF middlePoint;

  24. private float oldDistance;

  25. private float oldAngle;

  26. private Vibrator vibrator;

  27. private GestureDetector gdetector;

  28. public PatImageView(final Context context)

  29. {

  30. super(context);

  31. matrix = new Matrix();

  32. savedMatrix = new Matrix();

  33. matrix.setTranslate(0f, 0f);

  34. setScaleType(ScaleType.MATRIX);

  35. setImageMatrix(matrix);

  36. startPoint = new PointF();

  37. middlePoint = new PointF();

  38. oldDistance = 1f;

  39. gdetector = new GestureDetector(context, new GestureDetector.OnGestureListener()

  40. {

  41. @Override

  42. public boolean onSingleTapUp(MotionEvent e)

  43. {

  44. return true;

  45. }

  46. @Override

  47. public void onShowPress(MotionEvent e)

  48. {

  49. }

  50. @Override

  51. public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)

  52. {

  53. return true;

  54. }

  55. @Override

  56. public void onLongPress(MotionEvent e)

  57. {

  58. long_touch = true;

  59. vibrator = (Vibrator) context.getSystemService(Service.VIBRATOR_SERVICE);

  60. // 振动50ms,提示后续的操作将是旋转图片,而非缩放图片

  61. vibrator.vibrate(50);

  62. }

  63. @Override

  64. public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)

  65. {

  66. return true;

  67. }

  68. @Override

  69. public boolean onDown(MotionEvent e)

  70. {

  71. return true;

  72. }

  73. });

  74. setOnTouchListener(new OnTouchListener()

  75. {

  76. public boolean onTouch(View view, MotionEvent event)

  77. {

  78. switch(event.getAction() & MotionEvent.ACTION_MASK)

  79. {

  80. case MotionEvent.ACTION_DOWN:           // 第一个手指touch

  81. savedMatrix.set(matrix);

  82. startPoint.set(event.getX(), event.getY());

  83. mode = DRAG;

  84. long_touch = false;

  85. break;

  86. case MotionEvent.ACTION_POINTER_DOWN:   // 第二个手指touch

  87. oldDistance = getDistance(event);   // 计算第二个手指touch时,两指之间的距离

  88. oldAngle = getDegree(event);        // 计算第二个手指touch时,两指所形成的直线和x轴的角度

  89. if(oldDistance > 10f)

  90. {

  91. savedMatrix.set(matrix);

  92. middlePoint = midPoint(event);

  93. if(!long_touch)

  94. {

  95. mode = ZOOM;

  96. }

  97. else

  98. {

  99. mode = ROTA;

  100. }

  101. }

  102. break;

  103. case MotionEvent.ACTION_UP:

  104. mode = NONE;

  105. break;

  106. case MotionEvent.ACTION_POINTER_UP:

  107. mode = NONE;

  108. break;

  109. case MotionEvent.ACTION_MOVE:

  110. if(vibrator != null)    vibrator.cancel();

  111. if(mode == DRAG)

  112. {

  113. matrix.set(savedMatrix);

  114. matrix.postTranslate(event.getX() - startPoint.x, event.getY() - startPoint.y);

  115. }

  116. if(mode == ZOOM)

  117. {

  118. float newDistance = getDistance(event);

  119. if(newDistance > 10f)

  120. {

  121. matrix.set(savedMatrix);

  122. float scale = newDistance / oldDistance;

  123. matrix.postScale(scale, scale, middlePoint.x, middlePoint.y);

  124. }

  125. }

  126. if(mode == ROTA)

  127. {

  128. float newAngle = getDegree(event);

  129. matrix.set(savedMatrix);

  130. float degrees = newAngle - oldAngle;

  131. matrix.postRotate(degrees, middlePoint.x, middlePoint.y);

  132. }

  133. break;

  134. }

  135. setImageMatrix(matrix);

  136. invalidate();

  137. gdetector.onTouchEvent(event);

  138. return true;

  139. }

  140. });

最后

其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

当然我也为你们整理好了百度、阿里、腾讯、字节跳动等等互联网超级大厂的历年面试真题集锦。这也是我这些年来养成的习惯,一定要学会把好的东西,归纳整理,然后系统的消化吸收,这样才能极大的提高学习效率和成长进阶。碎片、零散化的东西,我觉得最没有价值的。就好比你给我一张扑克牌,我只会觉得它是一张废纸,但如果你给我一副扑克牌,它便有了它的价值。这和我们收集资料就要收集那些系统化的,是一个道理。

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

Matrix);

  1. float degrees = newAngle - oldAngle;

  2. matrix.postRotate(degrees, middlePoint.x, middlePoint.y);

  3. }

  4. break;

  5. }

  6. setImageMatrix(matrix);

  7. invalidate();

  8. gdetector.onTouchEvent(event);

  9. return true;

  10. }

  11. });

最后

其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

当然我也为你们整理好了百度、阿里、腾讯、字节跳动等等互联网超级大厂的历年面试真题集锦。这也是我这些年来养成的习惯,一定要学会把好的东西,归纳整理,然后系统的消化吸收,这样才能极大的提高学习效率和成长进阶。碎片、零散化的东西,我觉得最没有价值的。就好比你给我一张扑克牌,我只会觉得它是一张废纸,但如果你给我一副扑克牌,它便有了它的价值。这和我们收集资料就要收集那些系统化的,是一个道理。

[外链图片转存中…(img-rRuCZ5SP-1715345421552)]

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值