栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > 架构设计

Android中图像变换Matrix的原理应用,面试安卓系统架构

架构设计 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android中图像变换Matrix的原理应用,面试安卓系统架构

  1. canvas.drawBitmap(bitmap, matrix, null);

  2. super.onDraw(canvas);

  3. }

  4. @Override

  5. public void setImageMatrix(Matrix matrix)

  6. {

  7. this.matrix.set(matrix);

  8. super.setImageMatrix(matrix);

  9. }

  10. public Bitmap getImageBitmap()

  11. {

  12. return bitmap;

  13. }

  14. }

  15. public boolean onTouch(View v, MotionEvent e)

  16. {

  17. if(e.getAction() == MotionEvent.ACTION_UP)

  18. {

  19. Matrix matrix = new Matrix();

  20. // 输出图像的宽度和高度(162 x 251)

  21. Log.e(“TestTransformMatrixActivity”, "image size: width x height = " +  view.getImageBitmap().getWidth() + " x " + view.getImageBitmap().getHeight());

  22. // 1. 平移

  23. matrix.postTranslate(view.getImageBitmap().getWidth(), view.getImageBitmap().getHeight());

  24. // 在x方向平移view.getImageBitmap().getWidth(),在y轴方向view.getImageBitmap().getHeight()

  25. view.setImageMatrix(matrix);

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

  27. float[] matrixValues = new float[9];

  28. matrix.getValues(matrixValues);

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

  30. {

  31. String temp = new String();

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

  33. {

  34. temp += matrixValues[3 * i + j ] + “t”;

  35. }

  36. Log.e(“TestTransformMatrixActivity”, temp);

  37. }

  38. //          // 2. 旋转(围绕图像的中心点)

  39. //          matrix.setRotate(45f, view.getImageBitmap().getWidth() / 2f, view.getImageBitmap().getHeight() / 2f);

  40. //

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

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

  43. //          view.setImageMatrix(matrix);

  44. //

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

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

  47. //          matrix.getValues(matrixValues);

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

  49. //          {

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

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

  52. //              {

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

  54. //              }

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

  56. //          }

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

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

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

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

  61. //

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

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

  64. //          view.setImageMatrix(matrix);

  65. //

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

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

  68. //          matrix.getValues(matrixValues);

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

  70. //          {

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

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

  73. //              {

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

  75. //              }

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

  77. //          }

  78. //          // 4. 缩放

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

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

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

  82. //          matrix.getValues(matrixValues);

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

  84. //          {

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

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

  87. //              {

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

  89. //              }

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

  91. //          }

  92. //

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

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

  95. //          view.setImageMatrix(matrix);

  96. //

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

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

  99. //          matrix.getValues(matrixValues);

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

  101. //          {

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

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

  104. //              {

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

  106. //              }

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

  108. //          }

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

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

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

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

  113. //          matrix.getValues(matrixValues);

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

  115. //          {

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

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

  118. //              {

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

  120. //              }

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

  122. //          }

  123. //

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

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

  126. //          view.setImageMatrix(matrix);

  127. //

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

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

  130. //          matrix.getValues(matrixValues);

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

  132. //          {

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

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

  135. //              {

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

  137. //              }

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

  139. //          }

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

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

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

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

  144. //          matrix.getValues(matrixValues);

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

  146. //          {

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

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

  149. //              {

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

  151. //              }

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

  153. //          }

  154. //

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

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

  157. //          view.setImageMatrix(matrix);

  158. //

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

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

  161. //          matrix.getValues(matrixValues);

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

  163. //          {

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

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

  166. //              {

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

  168. //              }

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

  170. //          }

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

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

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

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

  175. //          matrix.getValues(matrixValues);

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

  177. //          {

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

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

  180. //              {

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

  182. //              }

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

  184. //          }

  185. //

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

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

  188. //          view.setImageMatrix(matrix);

  189. //

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

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

  192. //          matrix.getValues(matrixValues);

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

  194. //          {

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

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

  197. //              {

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

  199. //              }

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

  201. //          }

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

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

  204. //          matrix.setValues(matrix_values);

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

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

  207. //          matrix.getValues(matrixValues);

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

  209. //          {

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

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

  212. //              {

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

  214. //              }

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

  216. //          }

  217. //

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

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

  220. //          view.setImageMatrix(matrix);

  221. //

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

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

  224. //          matrix.getValues(matrixValues);

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

  226. //          {

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

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

  229. //              {

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

  231. //              }

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

  233. //          }

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

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

  236. //          matrix.setValues(matrix_values);

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

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

  239. //          matrix.getValues(matrixValues);

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

  241. //          {

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

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

  244. //              {

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

  246. //              }

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

  248. //          }

  249. //

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

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

  252. //          view.setImageMatrix(matrix);

  253. //

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

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

  256. //          matrix.getValues(matrixValues);

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

  258. //          {

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

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

  261. //              {

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

  263. //              }

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

  265. //          }

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

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

  268. //          matrix.setValues(matrix_values);

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

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

  271. //          matrix.getValues(matrixValues);

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

  273. //          {

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

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

  276. //              {

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

  278. //              }

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

  280. //          }

  281. //

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

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

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

  285. //          view.setImageMatrix(matrix);

  286. //

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

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

  289. //          matrix.getValues(matrixValues);

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

  291. //          {

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

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

  294. //              {

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

  296. //              }

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

  298. //          }

  299. view.invalidate();

  300. }

  301. return true;

  302. }

  303. }


  304.   

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享

的,左乘、右乘是针对矩阵运算的左右位置而言的。以第一部分“二、旋转变换”中围绕某点旋转的情况为例:

第三部分 应用

在这一部分,我们会将前面两部分所了解到的内容和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. });

  141. }

  142. // 计算两个手指之间的距离

  143. private float getDistance(MotionEvent event)

  144. {

  145. float x = event.getX(0) - event.getX(1);

  146. float y = event.getY(0) - event.getY(1);

  147. return FloatMath.sqrt(x * x + y * y);

  148. }

  149. // 计算两个手指所形成的直线和x轴的角度

  150. private float getDegree(MotionEvent event)

  151. {

  152. return (float)(Math.atan((event.getY(1) - event.getY(0)) / (event.getX(1) - event.getX(0))) * 180f);

  153. }

  154. // 计算两个手指之间,中间点的坐标

  155. private PointF midPoint( MotionEvent event)

  156. {

  157. PointF point = new PointF();

  158. float x = event.getX(0) + event.getX(1);

  159. float y = event.getY(0) + event.getY(1);

  160. point.set(x / 2, y / 2);

  161. return point;

  162. }

  163. }

下面完善PatImageViewActivity.java的代码,使之如下:

[java]  view plain copy

  1. package com.pat.imageview;

  2. import android.app.Activity;

  3. import android.graphics.Bitmap;

  4. import android.graphics.BitmapFactory;

  5. import android.os.Bundle;

  6. import android.view.Window;

  7. import android.view.WindowManager;

  8. public class PatImageViewActivity extends Activity

  9. {

  10. @Override

  11. public void onCreate(Bundle savedInstanceState)

  12. {

  13. super.onCreate(savedInstanceState);

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/908064.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号