图片相关
来源:互联网 发布:rayfile for mac下载 编辑:程序博客网 时间:2024/05/17 01:33
1. Bitmap位图
<!-- 对应于代码中的对象时BitmapDrawable --><bitmap xmlns:android="http://schemas.android.com/apk/res/android"android:src="@drawable/ic_launcher"android:antialias="true" //抗锯齿android:tileMode="mirror" //repeat:使图片平铺显示,mirror:使用图片又有镜像又有平铺显示,clamp:复制边缘的颜色,disabled:为默认选项android:filter="true" //位图过滤android:dither="true" //启用或禁用抖动的位图android:gravity="center" //设置图片的绘制位置 ></bitmap>
2.selector背景选择器
使用:1.在ListView中配置android:listSelector="@drawable/list_item_bg"
2.在listview的item中添加属性android:background=“@drawable/list_item_bg"
3.代码中使用 Drawable drawable = getResources().getDrawable(R.drawable.list_item_bg);
ListView.setSelector(drawable);android:cacheColorHint="@android:color/transparent"
<?xml version="1.0" encoding="utf-8" ?><selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 默认时的背景图片 --> <item android:drawable="@drawable/pic1" /> <!-- 没有焦点时的背景图片 --> <item android:state_window_focused="false" android:drawable="@drawable/pic1" /> <!-- 非触摸模式下获得焦点并单击时的背景图片 --> <item android:state_focused="true" android:state_pressed="true" android:drawable= "@drawable/pic2" /> <!-- 触摸模式下单击时的背景图片 --> <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/pic3" /> <!--选中时的图片背景 --> <item android:state_selected="true" android:drawable="@drawable/pic4" /> <!--获得焦点时的图片背景 --> <item android:state_focused="true" android:drawable="@drawable/pic5" /></selector>
3.shape控件显示属性
<shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 实心,就是填充的意思 --> <solid android:color="#ffeaeaea"/> <!-- 渐变,android:angle是渐变角度,渐变默认的模式为android:type="linear",即线性渐变, 可以指定渐变为径向渐变,android:type="radial",径向渐变需要指定半径android:gradientRadius="50"--> <gradient android:startColor="#ffeaeaea" android:endColor="#ffeaeaea" android:angle="270.0" android:type="linear" android:centerY="0.5" /> <padding android:left="7.0dip" android:top="7.0dip" android:right="7.0dip" android:bottom="7.0dip" /> <!-- 圆角,android:radius为角的弧度,值越大角越圆 --> <corners android:radius="6.0dip" /> <!-- 描边,把描边弄成虚线的形式,设置方式为:android:dashWidth="5dp" 横线宽度 android:dashGap="3dp" 隔开的距离 --> <stroke android:color="#ffeaeaea"/></shape>
4.读取本地图片转为Bitmap
public class FileToBitmap { public static Bitmap getBitmapFromFile(File dst, int width, int height) { if (null != dst && dst.exists()) { BitmapFactory.Options opts = null; if (width > 0 && height > 0) { opts = new BitmapFactory.Options(); opts.inJustDecodeBounds = true; BitmapFactory.decodeFile(dst.getPath(), opts); final int minSideLength = Math.min(width, height); opts.inSampleSize = computeSampleSize(opts, minSideLength, width * height); opts.inJustDecodeBounds = false; opts.inInputShareable = true; opts.inPurgeable = true; } try { return BitmapFactory.decodeFile(dst.getPath(), opts); } catch (OutOfMemoryError e) { e.printStackTrace(); } } return null; } public static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) { int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels); int roundedSize; if (initialSize <= 8) { roundedSize = 1; while (roundedSize < initialSize) { roundedSize <<= 1; } } else { roundedSize = (initialSize + 7) / 8 * 8; } return roundedSize; } private static int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) { double w = options.outWidth; double h = options.outHeight; int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math .sqrt(w * h / maxNumOfPixels)); int upperBound = (minSideLength == -1) ? 128 : (int) Math.min( Math.floor(w / minSideLength), Math.floor(h / minSideLength)); if (upperBound < lowerBound) { return lowerBound; } if ((maxNumOfPixels == -1) && (minSideLength == -1)) { return 1; } else if (minSideLength == -1) { return lowerBound; } else { return upperBound; } } } 参考文章:http://www.tuicool.com/articles/63emAv http://blog.csdn.net/haozipi/article/details/47183543?ref=myread http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=498&fromuid=6 Bitmap 究竟占多大内存
5.图片上传
@Override public void run() { // TODO Auto-generated method stub super.run(); new Runnable() { public void run() { int res = 0; String BOUNDARY = UUID.randomUUID().toString(); // 边界标识 随机生成 String PREFIX = "--", LINE_END = "\r\n"; String CONTENT_TYPE = "multipart/form-data"; // 内容类型 try { URL url = new URL(Content.SERVICE_URL + urlString); L.i(TAG, "url:" + url); HttpURLConnection conn = (HttpURLConnection) url .openConnection(); conn.setReadTimeout(Content.CONNECT_TIMEOUT); conn.setConnectTimeout(Content.CONNECT_TIMEOUT); conn.setDoInput(true); // 允许输入流 conn.setDoOutput(true); // 允许输出流 conn.setUseCaches(false); // 不允许使用缓存 conn.setRequestMethod("POST"); // 请求方式 conn.setRequestProperty("Charset", "UTF-8"); // 设置编码 conn.setRequestProperty("connection", "keep-alive"); conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary=" + BOUNDARY); if (file != null) { DataOutputStream dos = new DataOutputStream( conn.getOutputStream()); StringBuffer sb = new StringBuffer(); sb.append(PREFIX); sb.append(BOUNDARY); sb.append(LINE_END); sb.append("Content-Disposition: form-data; name=\"file\"; filename=\"" + file.getName() + "\"" + LINE_END); sb.append("Content-Type: application/octet-stream; charset=" + "UTF-8" + LINE_END); sb.append(LINE_END); dos.write(sb.toString().getBytes()); InputStream is = new FileInputStream(file); byte[] bytes = new byte[1024]; int len = 0; while ((len = is.read(bytes)) != -1) { dos.write(bytes, 0, len); } is.close(); dos.write(LINE_END.getBytes()); byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END) .getBytes(); dos.write(end_data); dos.flush(); res = conn.getResponseCode(); L.i(TAG, "response code:" + res); if (res == 200) { L.i(TAG, "request success"); InputStream input = conn.getInputStream(); StringBuffer sb1 = new StringBuffer(); int ss; while ((ss = input.read()) != -1) { sb1.append((char) ss); } result = sb1.toString(); L.i(TAG, "result : " + result); Message msg = new Message(); msg.what = 1; msg.obj = sb1.toString(); handler2.sendMessage(msg); } else { L.i(TAG, "request error"); } } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }.run(); }
6.图片下载
public class InternetTest { // 读取的方法 public byte[] readStream(InputStream inStream) throws Exception { ByteArrayOutputStream outstream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; // 用数据装 int len = -1; while ((len = inStream.read(buffer)) != -1) { outstream.write(buffer, 0, len); } outstream.close(); inStream.close(); // 关闭流一定要记得。 return outstream.toByteArray(); } @Test public void getImage() throws Exception { //要下载的图片的地址, String urlPath = "http://t2.gstatic.com/images?q=tbn:9g03SOE7gW2gEM:http://dev.10086.cn/cmdn/supesite"; URL url = new URL(urlPath);//获取到路径 // http协议连接对象 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET");// 这里是不能乱写的,详看API方法 conn.setConnectTimeout(6 * 1000); // 别超过10秒。 System.out.println(conn.getResponseCode()); if (conn.getResponseCode() == 200) { InputStream inputStream = conn.getInputStream(); byte[] data = readStream(inputStream); File file = new File("smart.jpg");// 给图片起名子 FileOutputStream outStream = new FileOutputStream(file);//写出对象 outStream.write(data);// 写入 outStream.close(); // 关闭流 } } }7.图片压缩
第一:我们先看下质量压缩方法: private Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中 int options = 100; while ( baos.toByteArray().length / 1024>100) { //循环判断如果压缩后图片是否大于100kb,大于继续压缩 baos.reset();//重置baos即清空baos image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中 options -= 10;//每次都减少10 } ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中 Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片 return bitmap; } 第二:图片按比例大小压缩方法(根据路径获取图片并压缩): private Bitmap getimage(String srcPath) { BitmapFactory.Options newOpts = new BitmapFactory.Options(); //开始读入图片,此时把options.inJustDecodeBounds 设回true了 newOpts.inJustDecodeBounds = true; Bitmap bitmap = BitmapFactory.decodeFile(srcPath,newOpts);//此时返回bm为空 newOpts.inJustDecodeBounds = false; int w = newOpts.outWidth; int h = newOpts.outHeight; //现在主流手机比较多是800*480分辨率,所以高和宽我们设置为 float hh = 800f;//这里设置高度为800f float ww = 480f;//这里设置宽度为480f //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可 int be = 1;//be=1表示不缩放 if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放 be = (int) (newOpts.outWidth / ww); } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放 be = (int) (newOpts.outHeight / hh); } if (be <= 0) be = 1; newOpts.inSampleSize = be;//设置缩放比例 //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了 bitmap = BitmapFactory.decodeFile(srcPath, newOpts); return compressImage(bitmap);//压缩好比例大小后再进行质量压缩 } 第三:图片按比例大小压缩方法(根据Bitmap图片压缩): private Bitmap comp(Bitmap image) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 100, baos); if( baos.toByteArray().length / 1024>1024) {//判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出 baos.reset();//重置baos即清空baos image.compress(Bitmap.CompressFormat.JPEG, 50, baos);//这里压缩50%,把压缩后的数据存放到baos中 } ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray()); BitmapFactory.Options newOpts = new BitmapFactory.Options(); //开始读入图片,此时把options.inJustDecodeBounds 设回true了 newOpts.inJustDecodeBounds = true; Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts); newOpts.inJustDecodeBounds = false; int w = newOpts.outWidth; int h = newOpts.outHeight; //现在主流手机比较多是800*480分辨率,所以高和宽我们设置为 float hh = 800f;//这里设置高度为800f float ww = 480f;//这里设置宽度为480f //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可 int be = 1;//be=1表示不缩放 if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放 be = (int) (newOpts.outWidth / ww); } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放 be = (int) (newOpts.outHeight / hh); } if (be <= 0) be = 1; newOpts.inSampleSize = be;//设置缩放比例 //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了 isBm = new ByteArrayInputStream(baos.toByteArray()); bitmap = BitmapFactory.decodeStream(isBm, null, newOpts); return compressImage(bitmap);//压缩好比例大小后再进行质量压缩 }
8.图片分辨率减少方法,防止OOM
public Bitmap getBitmapFromFile(File dst, int width, int height) { if (null != dst && dst.exists()) { BitmapFactory.Options opts = null; if (width > 0 && height > 0) { opts = new BitmapFactory.Options(); opts.inJustDecodeBounds = true; BitmapFactory.decodeFile(dst.getPath(), opts); // 计算图片缩放比例 final int minSideLength = Math.min(width, height); opts.inSampleSize = computeSampleSize(opts, minSideLength, width * height); opts.inJustDecodeBounds = false; opts.inInputShareable = true; opts.inPurgeable = true; } try { return BitmapFactory.decodeFile(dst.getPath(), opts); } catch (OutOfMemoryError e) { e.printStackTrace(); } } return null; } public static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) { int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels); int roundedSize; if (initialSize <= 8) { roundedSize = 1; while (roundedSize < initialSize) { roundedSize <<= 1; } } else { roundedSize = (initialSize + 7) / 8 * 8; } return roundedSize; } private static int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) { double w = options.outWidth; double h = options.outHeight; int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math .sqrt(w * h / maxNumOfPixels)); int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(Math .floor(w / minSideLength), Math.floor(h / minSideLength)); if (upperBound < lowerBound) { // return the larger one when there is no overlapping zone. return lowerBound; } if ((maxNumOfPixels == -1) && (minSideLength == -1)) { return 1; } else if (minSideLength == -1) { return lowerBound; } else { return upperBound; } }
9.打开相机照片和本机相册选择图片
1、PopActivity File file = new File(Content.CACHE_PATH + "/"+System.currentTimeMillis()+".png"); if(!file.exists()) try { file.createNewFile(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } uri = Uri.fromFile(file); Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); startActivityForResult(intent, TAKE_PHOTO); @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode != RESULT_OK) return; switch (requestCode) { case TAKE_PHOTO: intent.setData(uri); cropBitmap(uri); break; public void cropBitmap(Uri mUri) { Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(mUri, "image/*"); intent.putExtra("crop", "true"); intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); intent.putExtra("outputX", 200); intent.putExtra("outputY", 200); intent.putExtra("outputFormat", "png"); intent.putExtra("noFaceDetection", true); intent.putExtra("return-data", true); startActivityForResult(intent, CROP_PICTURE); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode != RESULT_OK) return; switch (requestCode) { case CROP_PICTURE: if(mark==2){ if(data.getData()!=null){ intent.setData(data.getData()); }else{ intent.putExtras(data.getExtras()); } }else{ intent.putExtras(data.getExtras()); } setResult(RESULT_OK, intent); finish(); break;
2、Activity @Override protected void onActivityResult(int arg0, int arg1, Intent arg2) { // TODO Auto-generated method stub super.onActivityResult(arg0, arg1, arg2); case TAKE_PHOTO: if (arg2 != null) { Bitmap one = null; Uri photoUri = arg2.getData(); L.i(TAG, "photoUri#" + arg2); if (photoUri.toString().contains("content://media")) { Cursor cursor = getContentResolver().query(photoUri, null, null, null, null); cursor.moveToFirst(); String picturePath = cursor .getString(cursor .getColumnIndexOrThrow(MediaStore.Images.Media.DATA)); one = Util.getDiskBitmap(picturePath); cursor.close(); iv3.setImageBitmap(one); String picPath = Util.saveBitmap( "" + System.currentTimeMillis(), Util.comp(one)); String semd = Util.bitmaptoString(one); L.i(TAG, "p#" + picPath); new ImageUpLoader("postImg/picture?uid=" + uid, picPath, handler2).start(); } else { Bundle extra = arg2.getExtras(); if (extra != null) { one = (Bitmap)extra.get("data"); } iv3.setImageBitmap(ImageToRound.toRoundBitmap(one)); String picPath = Util.saveBitmap( "" + System.currentTimeMillis(), Util.comp(one)); L.i(TAG, "p:"+picPath); new ImageUpLoader("postImg/picture?uid=" + uid, picPath, handler2).start(); } } break;
12.Android-Universal-Image-Loader 图片异步加载类库的使用
http://blog.csdn.net/vipzjyno1/article/details/232063871、 private ImageLoader imageLoader; private DisplayImageOptions options; imageLoader = ImageLoader.getInstance(); imageLoader.init(ImageLoaderConfiguration.createDefault(context)); options = new DisplayImageOptions.Builder() .showStubImage(Content.NO_PHOTO) .showImageForEmptyUri(Content.NO_PHOTO) .showImageOnFail(Content.NO_PHOTO).cacheInMemory(true) .cacheOnDisc(true).bitmapConfig(Bitmap.Config.ARGB_8888) .build(); imageLoader.displayImage(url2, vh.touImageView, options); 2、 public static void initImageLoader(Context context) { ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder( context).threadPriority(Thread.NORM_PRIORITY - 2) .denyCacheImageMultipleSizesInMemory() .discCacheFileNameGenerator(new Md5FileNameGenerator()) .tasksProcessingOrder(QueueProcessingType.LIFO) .writeDebugLogs().build(); ImageLoader.getInstance().init(config); } 3、Configuration所有配置简介 .memoryCacheExtraOptions(480, 800) //即保存的每个缓存文件的最大长宽 .threadPriority(Thread.NORM_PRIORITY - 2) //设置图片加载线程的优先级,默认为Thread.NORM_PRIORITY-1 线程池中线程的个数 注:如果设置了taskExecutor或者taskExecutorForCachedImages 此设置无效 .threadPoolSize(3) // 设置显示图片线程池大小,默认为3 注:如果设置了taskExecutor或者taskExecutorForCachedImages 此设置无效 .denyCacheImageMultipleSizesInMemory() // 设置拒绝缓存在内存中一个图片多个大小 默认为允许,(同一个图片URL)根据不同大小的imageview保存不同大小图片 .memoryCache(new LRULimitedMemoryCache(40*1024*1024)) //缓存策略 .memoryCacheSize(50 * 1024 * 1024) //设置内存缓存的大小 .diskCacheFileNameGenerator(new Md5FileNameGenerator()) // 设置硬盘缓存文件名生成规范 默认为new HashCodeFileNameGenerator() .diskCacheSize(200 * 1024 * 1024) //磁盘缓存大小 .tasksProcessingOrder(QueueProcessingType.LIFO) //工作队列 设置图片加载和显示队列处理的类型 默认为QueueProcessingType.FIFO 注:如果设置了taskExecutor或者taskExecutorForCachedImages 此设置无效 .diskCacheFileCount(200) //缓存的文件数量 .diskCache(new UnlimitedDiskCache(cacheDir)) //自定义缓存路径 .taskExecutor(DefaultConfigurationFactory.createExecutor(3,Thread.NORM_PRIORITY - 1, QueueProcessingType.FIFO)) // 设置自定义加载和显示图片的线程池 .taskExecutorForCachedImages(DefaultConfigurationFactory.createExecutor(3,Thread.NORM_PRIORITY - 1, QueueProcessingType.FIFO)) // 设置自定义加载和显示内存缓存或者硬盘缓存图片的线程池 .memoryCache(new LruMemoryCache(2 * 1024 * 1024)) // 设置内存缓存 默认为一个当前应用可用内存的1/8大小的LruMemoryCache .memoryCacheSize(2 * 1024 * 1024) // 设置内存缓存的最大大小 默认为一个当前应用可用内存的1/8 .memoryCacheSizePercentage(13) // 设置内存缓存最大大小占当前应用可用内存的百分比 默认为一个当前应用可用内存的1/8 .discCache(new UnlimitedDiscCache(StorageUtils.getCacheDirectory(getApplicationContext()))) // 设置硬盘缓存默认为StorageUtils.getCacheDirectory(getApplicationContext())即/mnt/sdcard/android/data/包名/cache/ .discCacheSize(50 * 1024 * 1024) // 设置硬盘缓存的最大大小 .discCacheFileCount(100) // 设置硬盘缓存的文件的最多个数 .imageDownloader(new HttpClientImageDownloader(getApplicationContext(),new DefaultHttpClient())) // 设置图片下载器 默认为 DefaultConfigurationFactory.createBitmapDisplayer() .imageDecoder(DefaultConfigurationFactory.createImageDecoder(false)) // 设置图片解码器 ,默认为DefaultConfigurationFactory.createImageDecoder(false) .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // 设置默认的图片显示选项 ,默认为DisplayImageOptions.createSimple() .writeDebugLogs() // 打印DebugLogs .build(); // 建立 4、DisplayImageOptions所有配置简介.showImageOnLoading(R.drawable.ic_chat_def_pic) // 设置图片加载时的默认图片 .showImageOnFail(R.drawable.ic_chat_def_pic_failure) // 设置图片加载失败的默认图片 .showImageForEmptyUri(R.drawable.ic_chat_def_pic) // 设置图片URI为空时默认图片 .resetViewBeforeLoading(false) // 设置是否将View在加载前复位 .delayBeforeLoading(100) // 设置延迟部分时间才开始加载 默认为0 .cacheInMemory(true) // 设置添加到内存缓存 默认为false .cacheOnDisc(true) // 设置添加到硬盘缓存 默认为false .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) // 设置规模类型的解码图像 默认为ImageScaleType.IN_SAMPLE_POWER_OF_2 .bitmapConfig(Bitmap.Config.ARGB_8888) // 设置位图图像解码配置 默认为Bitmap.Config.ARGB_8888 .decodingOptions(new Options()) // 设置选项的图像解码 .displayer(new FadeInBitmapDisplayer(300)) // 设置自定义显示器 默认为DefaultConfigurationFactory.createBitmapDisplayer() .handler(new Handler()) // 设置自定义的handler 默认为new Handler() .build(); // 建立
13、基于LruCache的图片缓存
http://blog.csdn.net/u013064109/article/details/51756551
14、openCV4android
http://blog.csdn.net/hbl_for_android/article/details/51941106 openCV4android常用变换(一)http://blog.csdn.net/hbl_for_android/article/details/51989105 opencv4android常用变换(二)
0 0
- 图片相关
- 图片相关
- 图片相关
- 图片相关
- 图片处理相关
- 图片相关的设置
- .net图片处理相关
- 图片、摄像头相关
- android 图片效果相关
- iphone图片拉伸相关
- 图片相关操作
- IOS图片相关
- 图片操作相关代码
- Android 图片相关小结
- 图片隐写 相关
- Android图片相关学习
- Mantis相关图片
- PB显示图片相关
- COM组件常用接口,以备自用
- 了解身边的超线程、双核、双cpu
- 461. Hamming Distance
- EditText限制输入类型为英数字并限制长度
- windows 远程 Windows命令
- 图片相关
- 抽象类和接口的应用场景
- macbook 下 webstorm 快键键
- 学Javascript的一些感悟
- 有关wince开发的工作小结
- hdu 1536 S-Nim (博弈)
- 判断PC端或移动端跳转至相应页面
- 设计模式四 proxy代理模式
- 天梯赛练习集 L3-006 迎风一刀斩