1.  
  1. /*
  2. * Java 图片转换成字符图 CharMaps (整理)
  3. *
  4. * 2016-1-2 深圳 南山平山村 曾剑锋
  5. *
  6. * @(#)CharMaps.java 2014/1/16
  7. * 1、这个一个Java程序,感谢您花费大量时间阅读本文档;
  8. * 2、本人知道大家并不喜欢看大量文字描述,但实属无奈,因为我们的沟通只能通过文字;
  9. * 3、当您在复制、粘贴的时候请注意包名为:practice,文件名为:CharMaps,以防止一些不必要的麻烦;
  10. * 4、下面这张由字符组成的图是直接由图片生成的,信与不信由您决定,另外可以肯定的是本人绝对不会一个字一个敲这幅图;
  11. * 5、如果想知道她是如何完成的,请看完CharMaps类前面的全部注释,因为她是工具,有些内容需要了解、素材需要准备;
  12. * 6、本次注释参考了MyEclipse的注释风格,相对比上次来说注释要规范一些,但由于本人经验、认知水平有限,可能很多地方没有
  13. * 考虑完全,或者没有解释清楚,请谅解。
  14. */
  15. package demo;
  16.  
  17. import java.awt.image.BufferedImage;
  18. import java.io.BufferedWriter;
  19. import java.io.File;
  20. import java.io.FileWriter;
  21. import java.io.IOException;
  22. import java.util.Arrays;
  23. import java.util.regex.Matcher;
  24. import java.util.regex.Pattern;
  25. import javax.imageio.ImageIO;
  26. import javax.swing.JFileChooser;
  27. import javax.swing.filechooser.FileNameExtensionFilter;
  28. /**
  29. *
  30. * <p>
  31. * <h4>一、软件声明:</h4><br><ol>
  32. * <li>该软件是为了解决TTS无法上图的原因才写出来的,同时感谢您花费宝贵的时间来阅读本文档;<br>
  33. * <li>如果您打算使用这个小工具,那么请阅读完这个这整段注释;
  34. * <li>如果您只是路过,那么您可以也可以猫一眼 ^_^,不过我相信她不会让您失望的;<br>
  35. * <li>该软件已被我命名为CharMaps,在后面的注释中,我说明了命名理由 ^_^;<br>
  36. * <li>TTS最小字号是9px阻碍了CharMaps的强大功能,但CharMaps至少能缓解一下我们对图片的向往,希望TTS以后会放宽规则;<br>
  37. *
  38. * 该小工具被我命名为:CharMaps,没有抄袭他人的思路,是根据自己的需求写的,希望她能给您带来乐趣<br>
  39. * </ol></p>
  40. *
  41. * <p>
  42. * <h4>二、CharMaps由来:</h4><br><ol>
  43. * <li>CharMaps制作初衷是因为TTS不能上图,之前上传《动态写轮眼(火影)——Java原创》系列软件时感觉实在不爽,所以自己通过
  44. * 自己目前的认知水平写了这个CharMaps。<br>
  45. * <li>灵感来自硬件传感器——摄像头——的工作原理,有兴趣的朋友可以去找下度娘或者谷哥,听说他们很懂的样子。 ^_^<br>
  46. *</ol></p>
  47. *
  48. * <p>
  49. * <h4>三、CharMaps命名解析:</h4><br><ol>
  50. * <li>Char代表字符,因为她将图片里对一个的像素转换成了字符,为什么是字符而不是字节?原因在于字节宽高比大约是1:2.5,
  51. * 而字符的宽高大约是1:1,我说的是大约 ^_^;<br>
  52. * <li>Map是代表输出的就像每张图片一个映射(map);<br>
  53. * <li>s是因为能同时处理多张图片;<br>
  54. * <li>最终组合为CharMaps,很优雅的名字,^_^ ;<br>
  55. *</ol></p>
  56. *
  57. * <p>
  58. * <h4>四、CharMaps知识预备:</h4><br><ol>
  59. * <li>CharMaps采用了具有RGB(red,green,blue)三基色的图片,后缀名为png/PNG/jpeg/jpe/JPEG,但只能处理黑白
  60. * 图,原因是黑白图在三基色上是平均分布的,而CharMaps仅是依靠blue分量进行图片处理。<br>
  61. * <li>如果您手上没有黑白图,您可以使用我们使用的操作系统自带的The GIMP,该软件自带了离线中文帮助文档,界面挺清爽
  62. * 的,您可以通过以下途径打开:应用程序 ——> 图像 ——> The GIMP,如果您不会使用,那就看看帮助文档吧,如果
  63. * 您以前使用Photoshop(PS),估计您会有很熟悉的感觉,您以前投资在PS上的时间终于得到了有效回报, ^_^。<br>
  64. * </ol></p>
  65. *
  66. * <p>
  67. * <h4>五、CharMaps缺陷:</h4><br><ol>
  68. * <li>目前只支持黑白图,其他的图不保证效果,主要是写复杂了不利于学习交流,简单并能提供一些思路,并且每个人可以根据
  69. * 自己需要进行功能改进或者定制才是沟通学习的王道;<br>
  70. * <li>所能转换的图片目前默认支持宽:int charMapsCol = 2000;高:int charMapsRow = 1000;您自己可以修改;<br>
  71. * <li>没有提供图片的自动缩放功能,所以不要操作默认支持的宽高,或者你自己修改的宽高;<br>
  72. * <li>目前没有发现Bug,不保证您在使用的时候会不会出现Bug,就算遇到了,相信您也能够独立解决,TTS不提供沟通讨论,没办法,
  73. * 另外本软件代码行数150左右(不包括注释),您懂的 ;^_^<br>
  74. * <li>如果这个小软件给您带来了不必要的麻烦,本人向您表示歉意。<br>
  75. * </ol></P>
  76. *
  77. * <p>
  78. * <h4>六、CharMaps操作流程:</h4><br><ol>
  79. * <li>准备好一张或者多张后缀是png/PNG/jpeg/jpe/JPEG的文件,运行本程序;<br>
  80. * <li>在文件选择框选择要转换的后缀是png/PNG/jpeg/jpe/JPEG的文件,选择完成后点“打开”按钮;不选择就会得到一个空文件;<br>
  81. * <li>根据Console提示框中内容找到输出文件,默认是路径/home/soft1/charMaps.txt,您可以自己修改;<br>
  82. * <li>用文本编辑器打开,把字号(不是字体)改成2px,看看效果吧。<br>
  83. * </ol></p>
  84. *
  85. * <p>
  86. * <h4>七、CharMaps工作流程图(非代码分析的朋友可以略过):</h4><br><ol>
  87. * 本次注释参考了MyEclipse的注释风格,注释尽量简洁,没有添加过多的额外的注释,以下为main()函数工作流程层次:<br>
  88. * <ul>
  89. * <li>|--filesSelectInit() //初始化文件选择器,主要用于过滤掉一些后缀不是png/PNG/jpeg/jpe/JPEG的文件,方便选择文件;<br>
  90. * <li>|--charMapsInit() //初始化charMaps数组,并以字符‘虢’填充,主要是笔画多,作为黑色背景好,还有就是字里有老虎 ^_^;<br>
  91. * <li>|--ImageProcessing() //图片处理函数,里面包含了如何对图片进行处理的方法;<br>
  92. * <ul><li>|--singleImageProcessing() //单张图片处理函数;<br>
  93. * <ul><li>|--fileSuffixCheck() //文件后缀检查,采用了正则表达式,主要是为了防止有些朋友选错;<br>
  94. * <li>|--ImageSizeCheck() //图片大小检查,主要是因为charMaps大小已由charMapsRow和charMapsCol固定了;<br>
  95. * <li>|--ImageMapToCharMaps() //将图片(Image)映射(map)到charMaps,所有的图片都是以charMaps中心点进行映射
  96. * 这个步骤中把每张图片的没有内容的边框裁减掉了;<br>
  97. * </ul>
  98. * </ul>
  99. * <li>|--addFrameForCharMaps()//如果转换的图片尺寸没有大于charMaps,那么给图片加个框,您可以通过注释掉这一行
  100. * 看有这个函数和没有这个函数的区别;<br>
  101. * <li>|--fileSave() //将最终的结果保存起来,路径已经固定,如果您有需要的话可以自己修改里面的路径。<br>
  102. * </ul></ol></P>
  103. * @author 曾剑锋<br>
  104. * @date 2014-1-16<br>
  105. */
  106. public class CharMaps{
  107. /** 声明一个文件选择器引用 */
  108. static JFileChooser jFileChooser = null;
  109. /**
  110. *&nbsp &nbsp &nbsp &nbsp
  111. * 在很多时候,我们在转换成为字符的时候,上、下、左、右总有我们那些我们不需要的一些行,这行不
  112. *是我们自己需要的,我们还让软件帮我们处理掉吧,默认赋值有那么点讲究,您应该能看懂的,其实跟后面
  113. *的判断取值有关,初始化值是根据小的取大值,大的取小值的方式,您自己可以看着取。
  114. *
  115. */
  116. static int firstOfUpRow = Integer.MAX_VALUE;
  117. static int firstOfCol = Integer.MAX_VALUE;
  118. static int lastOfUpRow = Integer.MIN_VALUE;
  119. static int lastOfCol = Integer.MIN_VALUE;
  120. /**
  121. * charMapsRow用于定义charMaps的行数<br>
  122. * charMapsCol用于定义charMaps的列数<br>
  123. */
  124. static int charMapsRow = 1000;
  125. static int charMapsCol = 2000;
  126. static char[][] charMaps = null;
  127.  
  128. /** 用于保存您选择的单个或者多个文件路径集合, 初始化为null */
  129. static File[] filePaths = null;
  130.  
  131. /** 保存图片的宽、高 */
  132. static int imageWidth = 0;
  133. static int imageHeight = 0;
  134. /**
  135. * &nbsp &nbsp &nbsp &nbsp
  136. * 在多张图片处理时候,每张图片处理使用不同的字符区别,charSelectindex用于计数,10个字符循环,
  137. * 如果一个charMaps同一个位置上字符会被后面的字符替代,如果没有则保持之前的字符<br>
  138. */
  139. static int charSelectindex = 0;
  140. static char[] charSelects = {'一','二','三','四','五','六','七','八','九','十'};
  141. /** 图像缓冲引用 */
  142. static BufferedImage bufferedImage = null;
  143. /**
  144. * main()函数,完成任务如下:<br><ol>
  145. * <li>对文件选择器进行初始化;<br>
  146. * <li>对charMaps二维数组进行初始化;<br>
  147. * <li>对已选择的图片集进行处理;<br>
  148. * <li>由于图片集处理函数对图片有效边界进行了记录,调用addFrameForCharMaps(),添加在上、下、左、右各
  149. * 添加一个字符的边框,使输出的CharMaps转换出来的图更具视觉效果;<br>
  150. * <li>保存转换好的文件;<br>
  151. * <li>如果出现异常,给出提示信息。<br></ol>
  152. */
  153. public static void main(String[] args) {
  154. try {
  155. filesSelectInit();
  156. charMapsInit();
  157. ImageProcessing();
  158. addFrameForCharMaps();
  159. fileSave();
  160. } catch (Exception e) {
  161. System.out.println("请选择后缀为png/PNG/jpeg/jpe/JPEG的文件");
  162. }
  163. }
  164. /**
  165. * 图像处理函数,完成任务如下:<br><ol>
  166. * <li>判断jFileChooser是否按下了打开;<br>
  167. * <li>获取一个或者多个文件,保存于filePaths中;<br>
  168. * <li>使用for循环迭代分成单张图片依次处理,调用singleImageProcessing()函数处理;<br>
  169. * <li>图片处理完给出提示。<br></ol>
  170. */
  171. private static void ImageProcessing() throws IOException {
  172. //判断是否在文件选择框上点了确定
  173. if (jFileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
  174. filePaths = jFileChooser.getSelectedFiles();
  175. for (File filePath : filePaths) {
  176. singleImageProcessing(filePath);
  177. }
  178. System.out.println("3、完成图像处理");
  179. }
  180. }
  181. /**
  182. * 单张图片处理函数,完成任务如下:<br><ol>
  183. * <li>调用文件后缀检查函数fileSuffixCheck(),防止因操作失误而引发的异常;<br>
  184. * <li>调用图片尺寸检查函数ImageSizeCheck(),防止图片尺寸过大,因为没有提供图片缩放功能;<br>
  185. * <li>调用图片映射函数ImageMapToCharMaps(),将图片的像素点映射到CharMaps数组中;<br>
  186. * <li>如果是多张图片的charSelectindex完成对charSelects数组中10个字符的自动选择。<br></ol>
  187. *
  188. * @param filePath 传入filePath进行检查,在返回回来,如果不行就抛弃。<br>
  189. * @throws IOException<br>
  190. */
  191. private static void singleImageProcessing(File filePath) throws IOException {
  192. filePath = fileSuffixCheck(filePath);
  193. ImageSizeCheck(filePath);
  194. ImageMapToCharMaps();
  195. charSelectindex = charSelectindex++ % 10;
  196. }
  197. /**
  198. * 为charMaps添加边框,完成任务如下:<br>
  199. * &nbsp &nbsp &nbsp &nbsp
  200. * 如果有效的图形区域小于charMaps数组大小,在上、下、左、右按条件添加一个字符的边框,使输出的CharMaps转换出来的图更具视觉效果;<br>
  201. */
  202. private static void addFrameForCharMaps() {
  203. firstOfCol = firstOfCol > 0 ? firstOfCol-1 : 0;
  204. firstOfUpRow = firstOfUpRow > 0 ? firstOfUpRow-1 : 0;
  205. lastOfCol = lastOfCol < charMapsCol ? lastOfCol+1 : charMapsCol;
  206. lastOfUpRow = lastOfUpRow < charMapsRow ? lastOfUpRow+1 : charMapsRow;
  207. }
  208. /**
  209. * 图片映射函数,完成任务如下:<br><ol>
  210. * <li>双重循环获取图片的宽高;<br>
  211. * <li>读出图片对应的坐标的RGB值<br>
  212. * <li>判断对应坐标点的RGB是背景还是需要转换,这里之使用了B(blue)的值,判断,这也是为什么目前的
  213. * CharMaps只能处理黑白图,当然应该也可以处理白蓝 ^_^<br>
  214. * <li>对符合要求的的像素点改变charMaps对应点的字符<br>
  215. * <li>对符合要求的像素进行边界检测,主要是完成对图片的边沿检查<br></ol>
  216. */
  217. private static void ImageMapToCharMaps() {
  218. for (int i = 0; i < imageHeight; i++) {
  219. for (int j = 0; j < imageWidth; j++) {
  220. int rgb = bufferedImage.getRGB(j, i);
  221. if ((rgb&0xff)<128 ) {
  222. charMaps[charMaps.length/2-imageHeight/2+i][charMaps[0].length/2-imageWidth/2+j] = charSelects[charSelectindex];
  223. boundedRangeOfImage(i,j);
  224. }
  225. }
  226. }
  227. }
  228. /**
  229. * 图片边界范围检查函数,完成任务如下:<br>
  230. * &nbsp &nbsp &nbsp &nbsp
  231. * 主要是完成检查当前点是否是图片的有效边缘,对图片上、下、左、右有效区域进行查找,为后面保存时裁剪作准备。<br>
  232. * @param i 当前点的行号
  233. * @param j 当前点的列号
  234. */
  235. private static void boundedRangeOfImage(int i, int j) {
  236. //记录图形中最上面开始出现图形行号
  237. if (charMaps.length/2-imageHeight/2+i<firstOfUpRow) {
  238. firstOfUpRow = charMaps.length/2-imageHeight/2+i;
  239. }
  240. //记录图形中最下面开始不再出现图形行号
  241. if (charMaps.length/2-imageHeight/2+i>lastOfUpRow) {
  242. lastOfUpRow = charMaps.length/2-imageHeight/2+i;
  243. }
  244. //记录图形中一行里面开始出现图形列号
  245. if (charMaps[0].length/2-imageWidth/2+j<firstOfCol) {
  246. firstOfCol = charMaps[0].length/2-imageWidth/2+j;
  247. }
  248. //记录图形中一行里面开始不再出现图形列号
  249. if (charMaps[0].length/2-imageWidth/2+j>lastOfCol) {
  250. lastOfCol = charMaps[0].length/2-imageWidth/2+j;
  251. }
  252. }
  253. /**
  254. * 图片尺寸检查函数,完成任务如下:<br>
  255. * &nbsp &nbsp &nbsp &nbsp
  256. * 主要是完成对图片的尺寸进行检查,不要比默认设置或者自己定制的charMaps数组大。<br>
  257. */
  258. private static void ImageSizeCheck(File filePath) throws IOException {
  259. bufferedImage = ImageIO.read(filePath);
  260. //得到图片的长宽
  261. imageWidth = bufferedImage.getWidth();
  262. imageHeight = bufferedImage.getHeight();
  263. if ((charMapsRow < imageHeight) || (charMapsCol < imageWidth)) {
  264. System.out.println("图片宽因该小于2000,高小于1000");
  265. return ;
  266. }
  267. }
  268. /**
  269. * 文件后缀检查函数,完成任务如下:<br>
  270. * &nbsp &nbsp &nbsp &nbsp
  271. * 采用正则表达式对文件进行匹配。<br>
  272. */
  273. private static File fileSuffixCheck(File filePath) {
  274. //使用正则表达式来防止选择目前不支持的文件,目前只支持png/PNG/jpeg/jpe/JPEG格式图片
  275. Pattern pattern = Pattern.compile(".+[.][pPJj][nNpP][eEgGpP][gG]?");
  276. Matcher matcher = pattern.matcher(filePath.getName());
  277. if (matcher.matches() == false) {
  278. return null;
  279. }
  280. return filePath;
  281. }
  282. /**
  283. * charMaps初始化函数,Init是初始化的英文单词缩写,完成任务如下:<br>
  284. * &nbsp &nbsp &nbsp &nbsp
  285. * 完成对charMaps初始化,并提示完成。<br>
  286. */
  287. private static void charMapsInit() {
  288. charMaps = new char[charMapsRow][charMapsCol];
  289. //记得需要初始化,否则好像出不来值
  290. for (int i = 0; i < charMaps.length; i++) {
  291. Arrays.fill(charMaps[i], '虢');
  292. }
  293. System.out.println("2、完成charMaps数组初始化");
  294. }
  295. /**
  296. * 文件保存函数,完成任务如下:<br><ol>
  297. * <li>设置一个文件保存的路径,这个路径可以自己修改;<br>
  298. * <li>创建文件路径下的文件缓冲区;<br>
  299. * <li>将charMaps中的字符写好文件中,忽略在上、下、左、右边界之外的部分,只将边界内的字符输出;<br>
  300. * <li>每写完一行字符,进行换行;<br>
  301. * <li>最后关闭文件缓冲区,如果不关闭,文件缓冲区内的字符可能不会写到文件中,请注意;<br>
  302. * <li>提示完成以及提示文件路径。<br><ol>
  303. */
  304. private static void fileSave() {
  305. JFileChooser jFileChooser = new JFileChooser();
  306. jFileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);//只能选择目录
  307. jFileChooser.showOpenDialog(null);
  308. File saveFilePath = new File(jFileChooser.getSelectedFile().getPath()+"charMaps.txt");
  309. try {
  310. BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(saveFilePath));
  311. for (int i = 0; i < charMaps.length; i++) {
  312. if ((i >= firstOfUpRow) && (i <= lastOfUpRow)) {
  313. bufferedWriter.write(charMaps[i], firstOfCol, lastOfCol-firstOfCol+1);
  314. bufferedWriter.newLine();
  315. }
  316. }
  317. bufferedWriter.close();
  318. } catch (IOException e1) {
  319. e1.printStackTrace();
  320. }
  321. System.out.println("4、完成文件保存\n");
  322. System.out.println("CharMaps已完成完成工作,请到"+saveFilePath.getPath()+"中查看结果 ^_^\n");
  323. }
  324. /**
  325. * 文件选择对话框初始化函数,Init是初始化的英文单词缩写,完成任务如下:<br><ol>
  326. * <li>提示欢迎使用CharMaps;<br>
  327. * <li>创建文件选择对话框;<br>
  328. * <li>创建文件选择过滤器;<br>
  329. * <li>将文件选择过滤器添加进入文件对话框,还句话说是:使文件选择过滤器有效;<br>
  330. * <li>将文件选择对话框设置为可以多选;<br>
  331. * <li>提示完成初始化。<br></ol>
  332. */
  333. private static void filesSelectInit() {
  334. System.out.println("\n\t欢迎使用CharMaps");
  335. jFileChooser = new JFileChooser();
  336. FileNameExtensionFilter filter = new FileNameExtensionFilter(
  337. "Images", "jpg", "png","PNG","JPG","jpe","JPE");
  338. jFileChooser.setFileFilter(filter);
  339. jFileChooser.setMultiSelectionEnabled(true);
  340. System.out.println("1、完成文件选择初始化");
  341. }
  342. }

转换的图片:

  

转换后的图片:

  

Java 图片转换为字符图 CharMaps (整理)的更多相关文章

  1. Java 图片提取RGB数组 RGBOfCharMaps (整理)

    package demo; /** * Java 图片提取RGB数组 RGBOfCharMaps (整理) * 声明: * 和ImageCombining配合使用的工具,这里是提取图片的R.G.B生成 ...

  2. Java图片转字符

    很久都没有更新博客了,昨天下午一个朋友问我能不能将一张图片转换成字符画,然后我想我这个朋友不知道,也许有的朋友以不知道,我就简单的分享一下 package com.xsl.zhuanhuan; imp ...

  3. 机器学习进阶-图像基本处理-视频的读取与处理 1.cv2.VideoCapture(视频的载入) 2.vc.isOpened(载入的视频是否可以打开) 3.vc.read(视频中一张图片的读取) 4.cv2.cvtColor(将图片转换为灰度图)

    1.vc = cv2.VideoCapture('test.mp4') #进行视频的载入 2.vc.isOpened() # 判断载入的视频是否可以打开 3.ret, frame = vc.read( ...

  4. python实战===图片转换为字符的源码(转)

    #cmd执行命令为>>> python xx.py pic.png#-*- coding:utf-8 -*- from PIL import Image import argpars ...

  5. Python 图片转字符图

    pip install Image argparse pillow from PIL import Image import argparse #命令行输入参数处理 parser = argparse ...

  6. 如何使用 python3 将RGB 图片转换为 灰度图

    首先,介绍第一种方法, 使用  PIL  库,   PIL库是一种python语言常用的一个图形处理库. 关于   PIL  库的安装本文就不介绍了. from PIL import Image I ...

  7. python小项目练习之转换像素图片为字符图

    实例来源实验楼网站,没事可以多逛逛,在此多谢实验楼的无私分享 from PIL import Image import argparse """ description: ...

  8. Android 将ARGB图片转换为灰度图

    思路如下: 1.读取or照相,得到一张ARGB图片. 2.转化为bitmap类,并对其数据做如下操作: A通道保持不变,然后逐像素计算:X = 0.3×R+0.59×G+0.11×B,并使这个像素的值 ...

  9. Java图片转换为base64格式

    /** * @Descriptionmap 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 * @author temdy * @Date 2015-01-26 * @param pa ...

随机推荐

  1. 单元最短路径算法模板汇总(Dijkstra, BF,SPFA),附链式前向星模板

    一:dijkstra算法时间复杂度,用优先级队列优化的话,O((M+N)logN)求单源最短路径,要求所有边的权值非负.若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的 ...

  2. Lock wait timeout exceeded; try restarting transaction

    What gives this away is the word transaction. It is evident by the statement that the query was atte ...

  3. (4)用opengl读入off文件生成可执行文件把模型显示出来(未完待续)

    ·找了好几个程序,好像都达不到我的要求,去教程里看看吧! 在往上抛出了这问题,好几天才有人回答,我已经找到程序了 正好的他的分析对我分解程序很有用 这是一个难度比较高的 首先你要分析.off文件结构, ...

  4. poj 1797(最短路变形)

    题目链接:http://poj.org/problem?id=1797 思路:题目意思很简单,n个顶点,m条路,每条路上都有最大载重限制,问1->n最大载重量.其实就是一最短路的变形,定义wei ...

  5. 错误:error libGL.so: cannot open shared object file: No such file or directory

    Failed to load libGL.soerror libGL.so: cannot open shared object file: No such file or directory 启动e ...

  6. WordPress主题制作教程6:常用模版标签

    在wordpress中,模板标签指一些字段,比如标题,内容,作者,发布日期,评论数等等,获取静态值和循环里面经常使用. 输出模板标签一般有两种方式:the_yourtag() 输出标签值和get_th ...

  7. 自己用反射写的一个request.getParameter工具类

    适用范围:当我们在jsp页面需要接收很多值的时候,如果用request.getParameter(属性名)一个一个写的话那就太麻烦了,于是我想是 否能用反射写个工具类来简化这样的代码,经过1个小时的代 ...

  8. SQL中的Null深入研究分析

    SQL中的Null深入研究分析 虽然熟练掌握SQL的人对于Null不会有什么疑问,但总结得很全的文章还是很难找,看到一篇英文版的, 感觉还不错. Tony Hoare 在1965年发明了 null 引 ...

  9. sleep和wait到底什么区别

    wait是在当前线程持有wait对象锁的情况下,暂时放弃锁,并让出CPU资源,并积极等待其它线程调用同一对象的notify或者notifyAll方法.注意,即使只有一个线程在等待,并且有其它线程调用了 ...

  10. Win API 内存整理

    记得我的笔记本上曾经安装了一款名为内存整理大师的软件,当时觉得挺好用而且挺NB的,就是导致开机启动有点慢. 当时我就在想,内存整理是怎么实现的?不过那是水平实在是不怎么样,估计连windows程序的消 ...