第二部分 代码验证

在第一部分中讲到的各种图像变换的验证代码如下,一共列出了10种情况。如果要验证其中的某一种情况,只需将相应的代码反注释即可。试验中用到的图片:

其尺寸为162 x 251。

每种变换的结果,请见代码之后的说明。

  1. import android.app.Activity;
  2. import android.content.Context;
  3. import android.graphics.Bitmap;
  4. import android.graphics.BitmapFactory;
  5. import android.graphics.Canvas;
  6. import android.graphics.Matrix;
  7. import android.os.Bundle;
  8. import android.util.Log;
  9. import android.view.MotionEvent;
  10. import android.view.View;
  11. import android.view.Window;
  12. import android.view.WindowManager;
  13. import android.view.View.OnTouchListener;
  14. import android.widget.ImageView;
  15. public class TestTransformMatrixActivity extends Activity
  16. implements
  17. OnTouchListener
  18. {
  19. private TransformMatrixView view;
  20. @Override
  21. public void onCreate(Bundle savedInstanceState)
  22. {
  23. super.onCreate(savedInstanceState);
  24. requestWindowFeature(Window.FEATURE_NO_TITLE);
  25. this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
  26. view = new TransformMatrixView(this);
  27. view.setScaleType(ImageView.ScaleType.MATRIX);
  28. view.setOnTouchListener(this);
  29. setContentView(view);
  30. }
  31. class TransformMatrixView extends ImageView
  32. {
  33. private Bitmap bitmap;
  34. private Matrix matrix;
  35. public TransformMatrixView(Context context)
  36. {
  37. super(context);
  38. bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.sophie);
  39. matrix = new Matrix();
  40. }
  41. @Override
  42. protected void onDraw(Canvas canvas)
  43. {
  44. // 画出原图像
  45. canvas.drawBitmap(bitmap, 0, 0, null);
  46. // 画出变换后的图像
  47. canvas.drawBitmap(bitmap, matrix, null);
  48. super.onDraw(canvas);
  49. }
  50. @Override
  51. public void setImageMatrix(Matrix matrix)
  52. {
  53. this.matrix.set(matrix);
  54. super.setImageMatrix(matrix);
  55. }
  56. public Bitmap getImageBitmap()
  57. {
  58. return bitmap;
  59. }
  60. }
  61. public boolean onTouch(View v, MotionEvent e)
  62. {
  63. if(e.getAction() == MotionEvent.ACTION_UP)
  64. {
  65. Matrix matrix = new Matrix();
  66. // 输出图像的宽度和高度(162 x 251)
  67. Log.e("TestTransformMatrixActivity", "image size: width x height = " +  view.getImageBitmap().getWidth() + " x " + view.getImageBitmap().getHeight());
  68. // 1. 平移
  69. matrix.postTranslate(view.getImageBitmap().getWidth(), view.getImageBitmap().getHeight());
  70. // 在x方向平移view.getImageBitmap().getWidth(),在y轴方向view.getImageBitmap().getHeight()
  71. view.setImageMatrix(matrix);
  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. //          // 2. 旋转(围绕图像的中心点)
  85. //          matrix.setRotate(45f, view.getImageBitmap().getWidth() / 2f, view.getImageBitmap().getHeight() / 2f);
  86. //
  87. //          // 做下面的平移变换,纯粹是为了让变换后的图像和原图像不重叠
  88. //          matrix.postTranslate(view.getImageBitmap().getWidth() * 1.5f, 0f);
  89. //          view.setImageMatrix(matrix);
  90. //
  91. //          // 下面的代码是为了查看matrix中的元素
  92. //          float[] matrixValues = new float[9];
  93. //          matrix.getValues(matrixValues);
  94. //          for(int i = 0; i < 3; ++i)
  95. //          {
  96. //              String temp = new String();
  97. //              for(int j = 0; j < 3; ++j)
  98. //              {
  99. //                  temp += matrixValues[3 * i + j ] + "\t";
  100. //              }
  101. //              Log.e("TestTransformMatrixActivity", temp);
  102. //          }
  103. //          // 3. 旋转(围绕坐标原点) + 平移(效果同2)
  104. //          matrix.setRotate(45f);
  105. //          matrix.preTranslate(-1f * view.getImageBitmap().getWidth() / 2f, -1f * view.getImageBitmap().getHeight() / 2f);
  106. //          matrix.postTranslate((float)view.getImageBitmap().getWidth() / 2f, (float)view.getImageBitmap().getHeight() / 2f);
  107. //
  108. //          // 做下面的平移变换,纯粹是为了让变换后的图像和原图像不重叠
  109. //          matrix.postTranslate((float)view.getImageBitmap().getWidth() * 1.5f, 0f);
  110. //          view.setImageMatrix(matrix);
  111. //
  112. //          // 下面的代码是为了查看matrix中的元素
  113. //          float[] matrixValues = new float[9];
  114. //          matrix.getValues(matrixValues);
  115. //          for(int i = 0; i < 3; ++i)
  116. //          {
  117. //              String temp = new String();
  118. //              for(int j = 0; j < 3; ++j)
  119. //              {
  120. //                  temp += matrixValues[3 * i + j ] + "\t";
  121. //              }
  122. //              Log.e("TestTransformMatrixActivity", temp);
  123. //          }
  124. //          // 4. 缩放
  125. //          matrix.setScale(2f, 2f);
  126. //          // 下面的代码是为了查看matrix中的元素
  127. //          float[] matrixValues = new float[9];
  128. //          matrix.getValues(matrixValues);
  129. //          for(int i = 0; i < 3; ++i)
  130. //          {
  131. //              String temp = new String();
  132. //              for(int j = 0; j < 3; ++j)
  133. //              {
  134. //                  temp += matrixValues[3 * i + j ] + "\t";
  135. //              }
  136. //              Log.e("TestTransformMatrixActivity", temp);
  137. //          }
  138. //
  139. //          // 做下面的平移变换,纯粹是为了让变换后的图像和原图像不重叠
  140. //          matrix.postTranslate(view.getImageBitmap().getWidth(), view.getImageBitmap().getHeight());
  141. //          view.setImageMatrix(matrix);
  142. //
  143. //          // 下面的代码是为了查看matrix中的元素
  144. //          matrixValues = new float[9];
  145. //          matrix.getValues(matrixValues);
  146. //          for(int i = 0; i < 3; ++i)
  147. //          {
  148. //              String temp = new String();
  149. //              for(int j = 0; j < 3; ++j)
  150. //              {
  151. //                  temp += matrixValues[3 * i + j ] + "\t";
  152. //              }
  153. //              Log.e("TestTransformMatrixActivity", temp);
  154. //          }
  155. //          // 5. 错切 - 水平
  156. //          matrix.setSkew(0.5f, 0f);
  157. //          // 下面的代码是为了查看matrix中的元素
  158. //          float[] matrixValues = new float[9];
  159. //          matrix.getValues(matrixValues);
  160. //          for(int i = 0; i < 3; ++i)
  161. //          {
  162. //              String temp = new String();
  163. //              for(int j = 0; j < 3; ++j)
  164. //              {
  165. //                  temp += matrixValues[3 * i + j ] + "\t";
  166. //              }
  167. //              Log.e("TestTransformMatrixActivity", temp);
  168. //          }
  169. //
  170. //          // 做下面的平移变换,纯粹是为了让变换后的图像和原图像不重叠
  171. //          matrix.postTranslate(view.getImageBitmap().getWidth(), 0f);
  172. //          view.setImageMatrix(matrix);
  173. //
  174. //          // 下面的代码是为了查看matrix中的元素
  175. //          matrixValues = new float[9];
  176. //          matrix.getValues(matrixValues);
  177. //          for(int i = 0; i < 3; ++i)
  178. //          {
  179. //              String temp = new String();
  180. //              for(int j = 0; j < 3; ++j)
  181. //              {
  182. //                  temp += matrixValues[3 * i + j ] + "\t";
  183. //              }
  184. //              Log.e("TestTransformMatrixActivity", temp);
  185. //          }
  186. //          // 6. 错切 - 垂直
  187. //          matrix.setSkew(0f, 0.5f);
  188. //          // 下面的代码是为了查看matrix中的元素
  189. //          float[] matrixValues = new float[9];
  190. //          matrix.getValues(matrixValues);
  191. //          for(int i = 0; i < 3; ++i)
  192. //          {
  193. //              String temp = new String();
  194. //              for(int j = 0; j < 3; ++j)
  195. //              {
  196. //                  temp += matrixValues[3 * i + j ] + "\t";
  197. //              }
  198. //              Log.e("TestTransformMatrixActivity", temp);
  199. //          }
  200. //
  201. //          // 做下面的平移变换,纯粹是为了让变换后的图像和原图像不重叠
  202. //          matrix.postTranslate(0f, view.getImageBitmap().getHeight());
  203. //          view.setImageMatrix(matrix);
  204. //
  205. //          // 下面的代码是为了查看matrix中的元素
  206. //          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. //          7. 错切 - 水平 + 垂直
  218. //          matrix.setSkew(0.5f, 0.5f);
  219. //          // 下面的代码是为了查看matrix中的元素
  220. //          float[] matrixValues = new float[9];
  221. //          matrix.getValues(matrixValues);
  222. //          for(int i = 0; i < 3; ++i)
  223. //          {
  224. //              String temp = new String();
  225. //              for(int j = 0; j < 3; ++j)
  226. //              {
  227. //                  temp += matrixValues[3 * i + j ] + "\t";
  228. //              }
  229. //              Log.e("TestTransformMatrixActivity", temp);
  230. //          }
  231. //
  232. //          // 做下面的平移变换,纯粹是为了让变换后的图像和原图像不重叠
  233. //          matrix.postTranslate(0f, view.getImageBitmap().getHeight());
  234. //          view.setImageMatrix(matrix);
  235. //
  236. //          // 下面的代码是为了查看matrix中的元素
  237. //          matrixValues = new float[9];
  238. //          matrix.getValues(matrixValues);
  239. //          for(int i = 0; i < 3; ++i)
  240. //          {
  241. //              String temp = new String();
  242. //              for(int j = 0; j < 3; ++j)
  243. //              {
  244. //                  temp += matrixValues[3 * i + j ] + "\t";
  245. //              }
  246. //              Log.e("TestTransformMatrixActivity", temp);
  247. //          }
  248. //          // 8. 对称 (水平对称)
  249. //          float matrix_values[] = {1f, 0f, 0f, 0f, -1f, 0f, 0f, 0f, 1f};
  250. //          matrix.setValues(matrix_values);
  251. //          // 下面的代码是为了查看matrix中的元素
  252. //          float[] matrixValues = new float[9];
  253. //          matrix.getValues(matrixValues);
  254. //          for(int i = 0; i < 3; ++i)
  255. //          {
  256. //              String temp = new String();
  257. //              for(int j = 0; j < 3; ++j)
  258. //              {
  259. //                  temp += matrixValues[3 * i + j ] + "\t";
  260. //              }
  261. //              Log.e("TestTransformMatrixActivity", temp);
  262. //          }
  263. //
  264. //          // 做下面的平移变换,纯粹是为了让变换后的图像和原图像不重叠
  265. //          matrix.postTranslate(0f, view.getImageBitmap().getHeight() * 2f);
  266. //          view.setImageMatrix(matrix);
  267. //
  268. //          // 下面的代码是为了查看matrix中的元素
  269. //          matrixValues = new float[9];
  270. //          matrix.getValues(matrixValues);
  271. //          for(int i = 0; i < 3; ++i)
  272. //          {
  273. //              String temp = new String();
  274. //              for(int j = 0; j < 3; ++j)
  275. //              {
  276. //                  temp += matrixValues[3 * i + j ] + "\t";
  277. //              }
  278. //              Log.e("TestTransformMatrixActivity", temp);
  279. //          }
  280. //          // 9. 对称 - 垂直
  281. //          float matrix_values[] = {-1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f};
  282. //          matrix.setValues(matrix_values);
  283. //          // 下面的代码是为了查看matrix中的元素
  284. //          float[] matrixValues = new float[9];
  285. //          matrix.getValues(matrixValues);
  286. //          for(int i = 0; i < 3; ++i)
  287. //          {
  288. //              String temp = new String();
  289. //              for(int j = 0; j < 3; ++j)
  290. //              {
  291. //                  temp += matrixValues[3 * i + j ] + "\t";
  292. //              }
  293. //              Log.e("TestTransformMatrixActivity", temp);
  294. //          }
  295. //
  296. //          // 做下面的平移变换,纯粹是为了让变换后的图像和原图像不重叠
  297. //          matrix.postTranslate(view.getImageBitmap().getWidth() * 2f, 0f);
  298. //          view.setImageMatrix(matrix);
  299. //
  300. //          // 下面的代码是为了查看matrix中的元素
  301. //          matrixValues = new float[9];
  302. //          matrix.getValues(matrixValues);
  303. //          for(int i = 0; i < 3; ++i)
  304. //          {
  305. //              String temp = new String();
  306. //              for(int j = 0; j < 3; ++j)
  307. //              {
  308. //                  temp += matrixValues[3 * i + j ] + "\t";
  309. //              }
  310. //              Log.e("TestTransformMatrixActivity", temp);
  311. //          }
  312. //          // 10. 对称(对称轴为直线y = x)
  313. //          float matrix_values[] = {0f, -1f, 0f, -1f, 0f, 0f, 0f, 0f, 1f};
  314. //          matrix.setValues(matrix_values);
  315. //          // 下面的代码是为了查看matrix中的元素
  316. //          float[] matrixValues = new float[9];
  317. //          matrix.getValues(matrixValues);
  318. //          for(int i = 0; i < 3; ++i)
  319. //          {
  320. //              String temp = new String();
  321. //              for(int j = 0; j < 3; ++j)
  322. //              {
  323. //                  temp += matrixValues[3 * i + j ] + "\t";
  324. //              }
  325. //              Log.e("TestTransformMatrixActivity", temp);
  326. //          }
  327. //
  328. //          // 做下面的平移变换,纯粹是为了让变换后的图像和原图像不重叠
  329. //          matrix.postTranslate(view.getImageBitmap().getHeight() + view.getImageBitmap().getWidth(),
  330. //                  view.getImageBitmap().getHeight() + view.getImageBitmap().getWidth());
  331. //          view.setImageMatrix(matrix);
  332. //
  333. //          // 下面的代码是为了查看matrix中的元素
  334. //          matrixValues = new float[9];
  335. //          matrix.getValues(matrixValues);
  336. //          for(int i = 0; i < 3; ++i)
  337. //          {
  338. //              String temp = new String();
  339. //              for(int j = 0; j < 3; ++j)
  340. //              {
  341. //                  temp += matrixValues[3 * i + j ] + "\t";
  342. //              }
  343. //              Log.e("TestTransformMatrixActivity", temp);
  344. //          }
  345. view.invalidate();
  346. }
  347. return true;
  348. }
  349. }

下面给出上述代码中,各种变换的具体结果及其对应的相关变换矩阵

1.     平移

输出的结果:

请对照第一部分中的“一、平移变换”所讲的情形,考察上述矩阵的正确性。

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

输出的结果:

它实际上是

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

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

这两条语句综合作用的结果。根据第一部分中“二、旋转变换”里面关于围绕某点旋转的公式,

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

所产生的转换矩阵就是:

而matrix.postTranslate(view.getImageBitmap().getWidth()* 1.5f, 0f);的意思就是在上述矩阵的左边再乘以下面的矩阵:

关于post是左乘这一点,我们在前面的理论部分曾经提及过,后面我们还会专门讨论这个问题。

所以它实际上就是:

出去计算上的精度误差,我们可以看到我们计算出来的结果,和程序直接输出的结果是一致的。

3.     旋转(围绕坐标原点旋转,在加上两次平移,效果同2)

根据第一部分中“二、旋转变换”里面关于围绕某点旋转的解释,不难知道:

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

等价于

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);

其中matrix.setRotate(45f)对应的矩阵是:

matrix.preTranslate(-1f* view.getImageBitmap().getWidth() / 2f, -1f * view.getImageBitmap().getHeight()/ 2f)对应的矩阵是:

由于是preTranslate,是先乘,也就是右乘,即它应该出现在matrix.setRotate(45f)所对应矩阵的右侧。

matrix.postTranslate((float)view.getImageBitmap().getWidth()/ 2f, (float)view.getImageBitmap().getHeight() / 2f)对应的矩阵是:

这次由于是postTranslate,是后乘,也就是左乘,即它应该出现在matrix.setRotate(45f)所对应矩阵的左侧。

所以综合起来,

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);

对应的矩阵就是:

这和下面这个矩阵(围绕图像中心顺时针旋转45度)其实是一样的:

因此,此处变换后的图像和2中变换后的图像时一样的。

4.     缩放变换

程序所输出的两个矩阵分别是:

其中第二个矩阵,其实是下面两个矩阵相乘的结果:

大家可以对照第一部分中的“三、缩放变换”和“一、平移变换”说法,自行验证结果。

5.     错切变换(水平错切)

代码所输出的两个矩阵分别是:

其中,第二个矩阵其实是下面两个矩阵相乘的结果:

大家可以对照第一部分中的“四、错切变换”和“一、平移变换”的相关说法,自行验证结果。

6.     错切变换(垂直错切)

代码所输出的两个矩阵分别是:

其中,第二个矩阵其实是下面两个矩阵相乘的结果:

大家可以对照第一部分中的“四、错切变换”和“一、平移变换”的相关说法,自行验证结果。

7.     错切变换(水平+垂直错切)

代码所输出的两个矩阵分别是:

其中,后者是下面两个矩阵相乘的结果:

大家可以对照第一部分中的“四、错切变换”和“一、平移变换”的相关说法,自行验证结果。

8.     对称变换(水平对称)

代码所输出的两个各矩阵分别是:

其中,后者是下面两个矩阵相乘的结果:

大家可以对照第一部分中的“五、对称变换”和“一、平移变换”的相关说法,自行验证结果。

9.     对称变换(垂直对称)

代码所输出的两个矩阵分别是:

其中,后者是下面两个矩阵相乘的结果:

大家可以对照第一部分中的“五、对称变换”和“一、平移变换”的相关说法,自行验证结果。

10.   对称变换(对称轴为直线y = x)

代码所输出的两个矩阵分别是:

其中,后者是下面两个矩阵相乘的结果:

大家可以对照第一部分中的“五、对称变换”和“一、平移变换”的相关说法,自行验证结果。

11.   关于先乘和后乘的问题

由于矩阵的乘法运算不满足交换律,我们在前面曾经多次提及先乘、后乘的问题,即先乘就是矩阵运算中右乘,后乘就是矩阵运算中的左乘。其实先乘、后乘的概念是针对变换操作的时间先后而言的,左乘、右乘是针对矩阵运算的左右位置而言的。以第一部分“二、旋转变换”中围绕某点旋转的情况为例:

越靠近原图像中像素的矩阵,越先乘,越远离原图像中像素的矩阵,越后乘。事实上,图像处理时,矩阵的运算是从右边往左边方向进行运算的。这就形成了越在右边的矩阵(右乘),越先运算(先乘),反之亦然。

当然,在实际中,如果首先指定了一个matrix,比如我们先setRotate(),即指定了上面变换矩阵中,中间的那个矩阵,那么后续的矩阵到底是pre还是post运算,都是相对这个中间矩阵而言的。

所有这些,其实都是很自然的事情。

Android中图像变换Matrix的原理、代码验证和应用(二)的更多相关文章

  1. Android中图像变换Matrix的原理、代码验证和应用(一)

    第一部分 Matrix的数学原理 在Android中,如果你用Matrix进行过图像处理,那么一定知道Matrix这个类.Android中的Matrix是一个3 x 3的矩阵,其内容如下: Matri ...

  2. Android中图像变换Matrix的原理、代码验证和应用(三)

    第三部分 应用 在这一部分,我们会将前面两部分所了解到的内容和Android手势结合起来,利用各种不同的手势对图像进行平移.缩放和旋转,前面两项都是在实践中经常需要用到的功能,后一项据说苹果也是最近才 ...

  3. Android中的LruCache的原理和使用

    Android中的LruCache的原理和使用 LruCache,虽然很多文章都把LRU翻译成"最近最少使用"缓存策略,但Android中的LruCache真的如此吗? 答案是No ...

  4. Android中SensorManager.getRotationMatrix函数原理解释

    SensorManager是Android中的一个类,其有一个函数getRotationMatrix,可以计算出旋转矩阵,进而通过getOrientation求得设备的方向(航向角.俯仰角.横滚角). ...

  5. Android中的Matrix(矩阵)

    写在前面 看这篇笔记之前先看一下参考文章,这篇笔记没有系统的讲述矩阵和代码的东西,参考文章写的也有错误的地方,要辨证的看. 如何计算矩阵乘法 android matrix 最全方法详解与进阶(完整篇) ...

  6. Android 中View的工作原理

    Android中的View在Android的知识体系中扮演着重要的角色.简单来说,View就是Android在视觉的体现.我们所展现的页面就是Android提供的GUI库中控件的组合.但是当要求不能满 ...

  7. Android中微信抢红包插件原理解析和开发实现

    一.前言 自从去年中微信添加抢红包的功能,微信的电商之旅算是正式开始正式火爆起来.但是作为Android开发者来说,我们在抢红包的同时意识到了很多问题,就是手动去抢红包的速度慢了,当然这些有很多原因导 ...

  8. 【转】Android 学习笔记——利用JNI技术在Android中调用、调试C++代码

    原文网址:http://cherishlc.iteye.com/blog/1756762 在Android中调用C++其实就是在Java中调用C++代码,只是在windows下编译生成DLL,在And ...

  9. Android中典型的ROOT原理(5)

    ROOT的作用 Customization 用户的个人定制,如删除一些预安装,定制开机动画等. 特权操作 所有需要特权操作的基本都是要通过ROOT,这也是ROOT的初衷. ROOT的第一步:寻找漏洞并 ...

随机推荐

  1. HTML常用标签跟表格

    <html>    --开始标签 <head> 网页上的控制信息 <title>页面标题</title> </head> <body& ...

  2. Oracle中把一个DateTime的字符串转化成date类型。to_date('2016/12/8 18:55:43','yyyy/MM/dd hh24:mi:ss'),

    Oracle中把一个DateTime或者该形态字符串转化成date类型. to_date('2016/12/8 18:55:43','yyyy/MM/dd hh24:mi:ss'), 或者: sele ...

  3. iOS ARC内存管理

    iOS的内存管理机制,只要是iOS开发者,不管多长的时间经验,都能说出来一点,但是要深入的理解.还是不简单的.随着ARC(自动管理内存)的流行.iOS开发者告别了手动管理内存的复杂工作.但是自动管理内 ...

  4. Padrino 生成器指南

    英文版出处:http://www.padrinorb.com/guides/generators Padrino提供了用于快速创建应用的生成器,其优势在于构建推荐的Padrino应用结构.自动生成罗列 ...

  5. [LINK]php的三种CLI常量:STDIN,STDOUT,STDERR

    FROM : http://www.cnblogs.com/thinksasa/archive/2013/02/27/2935158.html PHP CLI(command line interfa ...

  6. iOS关于TableViewController和CollectionViewController中self.view心得记录

    之前写代码,不喜欢记录,导致很多做过的功能,时间久了都遗忘了. 以后要勤记录~~~ 一丶首先说一下TableViewController 大家都知道,如果直接创建一个继承于TableViewContr ...

  7. Apache Shiro 使用手册(一)Shiro架构介绍 - kdboy - ITeye技术网站

    转载 原文地址 http://kdboy.iteye.com/blog/1154644 一.什么是Shiro Apache Shiro是一个强大易用的Java安全框架,提供了认证.授权.加密和会话管理 ...

  8. Webwork 学习之路【04】Configuration 详解

    Webwork做为经典的Web MVC 框架,个人觉得源码中配置文件这部分代码的实现十分考究. 支持自定义自己的配置文件.自定义配置文件读取类.自定义国际化支持. 可以作为参考,单独引入到其他项目中, ...

  9. 在线音乐网站【03】Part one 功能实现

    今天打算把网站功能的具体实现给总结一下,如果你想了解整个小项目,建议你先看看前面2篇博客. 1.在线音乐网站(1)需求和功能结构 2.在线音乐网站(2)数据库和开发环境 7.网站主要模块实现 a.在线 ...

  10. JS事件详解

    hello,我是沐晴,最近呢,来总结一下 JS中的常用的事件,希望我们都能一起查漏补缺. 焦点事件 焦点事件在表单中经常用到,那什么是焦点呢?比如我们文本框里面的有光标的时候,就是获得了焦点,我们就可 ...