android手写板

啊,好难看的机器人。。。。

 

应 yzuo_08 要求做了此Demo,跟以前那个手写板Demo不同的是可以将画布的内容保存为图片。

 

附上关键代码:

MainView.java

[java] view plaincopy

  1. package com.tszy.views;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileNotFoundException;  
  5. import java.io.FileOutputStream;  
  6. import java.io.IOException;  
  7.   
  8. import android.content.Context;  
  9. import android.graphics.Bitmap;  
  10. import android.graphics.Bitmap.CompressFormat;  
  11. import android.graphics.Bitmap.Config;  
  12. import android.graphics.Canvas;  
  13. import android.graphics.Color;  
  14. import android.graphics.Paint;  
  15. import android.graphics.Path;  
  16. import android.util.AttributeSet;  
  17. import android.view.MotionEvent;  
  18. import android.view.View;  
  19.   
  20. public class MainView extends View {  
  21.     private Paint paint;  
  22.     private Canvas cacheCanvas;  
  23.     private Bitmap cachebBitmap;  
  24.     private Path path;  
  25.       
  26.     private int clr_bg, clr_fg;  
  27.   
  28.       
  29.     public MainView(Context context, AttributeSet attrs) {  
  30.         super(context, attrs);  
  31.           
  32.         clr_bg = Color.WHITE;  
  33.         clr_fg = Color.CYAN;  
  34.           
  35.         paint = new Paint();  
  36.         paint.setAntiAlias(true); // 抗锯齿  
  37.         paint.setStrokeWidth(3); // 线条宽度  
  38.         paint.setStyle(Paint.Style.STROKE); // 画轮廓  
  39.         paint.setColor(clr_fg); // 颜色  
  40.           
  41.         path = new Path();  
  42.         // 创建一张屏幕大小的位图,作为缓冲  
  43.         cachebBitmap = Bitmap.createBitmap(480, 800, Config.ARGB_8888);  
  44.         cacheCanvas = new Canvas(cachebBitmap);  
  45.         cacheCanvas.drawColor(clr_bg);  
  46.     }  
  47.   
  48.     public MainView(Context context) {  
  49.         super(context);  
  50.     }  
  51.       
  52.     @Override  
  53.     protected void onDraw(Canvas canvas) {  
  54.         canvas.drawColor(clr_bg);  
  55.   
  56.         // 绘制上一次的,否则不连贯  
  57.         canvas.drawBitmap(cachebBitmap, 0, 0, null);  
  58.         canvas.drawPath(path, paint);         
  59.     }  
  60.       
  61.     /** 
  62.      * 清空画布 
  63.      */  
  64.     public void clear() {  
  65.         path.reset();  
  66.         cacheCanvas.drawColor(clr_bg);  
  67.         invalidate();  
  68.     }  
  69.       
  70.     /** 
  71.      * 将画布的内容保存到文件 
  72.      * @param filename 
  73.      * @throws FileNotFoundException 
  74.      */  
  75.     public void saveToFile(String filename) throws FileNotFoundException {  
  76.         File f = new File(filename);  
  77.         if(f.exists())  
  78.             throw new RuntimeException("文件:" + filename + " 已存在!");  
  79.               
  80.         FileOutputStream fos = new FileOutputStream(new File(filename));  
  81.         //将 bitmap 压缩成其他格式的图片数据  
  82.         cachebBitmap.compress(CompressFormat.PNG, 50, fos);  
  83.         try {  
  84.             fos.close();  
  85.         } catch (IOException e) {  
  86.             // TODO Auto-generated catch block  
  87.             e.printStackTrace();  
  88.         }  
  89.     }  
  90.   
  91.     private float cur_x, cur_y;  
  92.     private boolean isMoving;  
  93.     @Override  
  94.     public boolean onTouchEvent(MotionEvent event) {  
  95.         // TODO Auto-generated method stub  
  96.         float x = event.getX();  
  97.         float y = event.getY();  
  98.   
  99.         switch (event.getAction()) {  
  100.             case MotionEvent.ACTION_DOWN : {  
  101.                 cur_x = x;  
  102.                 cur_y = y;  
  103.                 path.moveTo(cur_x, cur_y);  
  104.                 isMoving = true;  
  105.                 break;  
  106.             }  
  107.   
  108.             case MotionEvent.ACTION_MOVE : {  
  109.                 if (!isMoving)  
  110.                     break;  
  111.   
  112.                 // 二次曲线方式绘制  
  113.                 path.quadTo(cur_x, cur_y, x, y);  
  114.                 // 下面这个方法貌似跟上面一样  
  115.                 // path.lineTo(x, y);  
  116.                 cur_x = x;  
  117.                 cur_y = y;  
  118.                 break;  
  119.             }  
  120.   
  121.             case MotionEvent.ACTION_UP : {  
  122.                 // 鼠标弹起保存最后状态  
  123.                 cacheCanvas.drawPath(path, paint);  
  124.                 path.reset();  
  125.                 isMoving = false;  
  126.                 break;  
  127.             }  
  128.         }  
  129.   
  130.         // 通知刷新界面  
  131.         invalidate();  
  132.   
  133.         return true;  
  134.     }  
  135.   
  136. }  

 

Activity 代码:

[java] view plaincopy

  1. @Override  
  2.     public void onClick(View v) {  
  3.         // TODO Auto-generated method stub  
  4.         switch (v.getId()) {  
  5.             case R.id.iv_btn_clear :  
  6.                 view.clear();  
  7.                 break;  
  8.   
  9.             case R.id.iv_btn_save : {  
  10.                 try {  
  11.                     String sdState = Environment.getExternalStorageState(); // 判断sd卡是否存在  
  12.   
  13.                     // 检查SD卡是否可用  
  14.                     if (!sdState.equals(android.os.Environment.MEDIA_MOUNTED)) {  
  15.                         Toast.makeText(this, "SD卡未准备好!", Toast.LENGTH_SHORT).show();  
  16.                         break;  
  17.                     }  
  18.   
  19.                     //获取系统图片存储路径  
  20.                     File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);  
  21.                     // Make sure the Pictures directory exists.  
  22.                     path.mkdirs();  
  23.                       
  24.                     //根据当前时间生成图片名称  
  25.                     Calendar c = Calendar.getInstance();  
  26.                     String name = ""   
  27.                             + c.get(Calendar.YEAR) + c.get(Calendar.MONTH) + c.get(Calendar.DAY_OF_MONTH)   
  28.                             + c.get(Calendar.HOUR_OF_DAY) + c.get(Calendar.MINUTE) + c.get(Calendar.SECOND)  
  29.                              + ".png";  
  30.                       
  31.                     //合成完整路径,注意 / 分隔符  
  32.                     String string = path.getPath() + "/" + name;  
  33.                     view.saveToFile(string);  
  34.                     Toast.makeText(this, "保存成功!\n文件保存在:" + string, Toast.LENGTH_LONG).show();  
  35.                 } catch (FileNotFoundException e) {  
  36.                     Toast.makeText(this, "保存失败!\n" + e, Toast.LENGTH_LONG).show();  
  37.                 }  
  38.                 break;  
  39.             }  
  40.         }  
  41.     }  

没什么难度,主要是将Bitmap转PNG图片那里,找了一会发现 Canvas 没有直接或间接保存的方法,刚好这里我使用了双缓冲,另一块画布的内容位图自己创建的,很自然想到将这个画布的位图保存为文件即可。

再查看 Bitmap 有个 compress(CompressFormat format, int quality,OutputStream
stream) 方法,很明显将文件输出流传给这个方法就OK

[java] view plaincopy

  1. @Override  
  2.     public void onClick(View v) {  
  3.         // TODO Auto-generated method stub  
  4.         switch (v.getId()) {  
  5.             case R.id.iv_btn_clear :  
  6.                 view.clear();  
  7.                 break;  
  8.   
  9.             case R.id.iv_btn_save : {  
  10.                 try {  
  11.                     String sdState = Environment.getExternalStorageState(); // 判断sd卡是否存在  
  12.   
  13.                     // 检查SD卡是否可用  
  14.                     if (!sdState.equals(android.os.Environment.MEDIA_MOUNTED)) {  
  15.                         Toast.makeText(this, "SD卡未准备好!", Toast.LENGTH_SHORT).show();  
  16.                         break;  
  17.                     }  
  18.   
  19.                     //获取系统图片存储路径  
  20.                     File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);  
  21.                     // Make sure the Pictures directory exists.  
  22.                     path.mkdirs();  
  23.                       
  24.                     //根据当前时间生成图片名称  
  25.                     Calendar c = Calendar.getInstance();  
  26.                     String name = ""   
  27.                             + c.get(Calendar.YEAR) + c.get(Calendar.MONTH) + c.get(Calendar.DAY_OF_MONTH)   
  28.                             + c.get(Calendar.HOUR_OF_DAY) + c.get(Calendar.MINUTE) + c.get(Calendar.SECOND)  
  29.                              + ".png";  
  30.                       
  31.                     //合成完整路径,注意 / 分隔符  
  32.                     String string = path.getPath() + "/" + name;  
  33.                     view.saveToFile(string);  
  34.                     Toast.makeText(this, "保存成功!\n文件保存在:" + string, Toast.LENGTH_LONG).show();  
  35.                 } catch (FileNotFoundException e) {  
  36.                     Toast.makeText(this, "保存失败!\n" + e, Toast.LENGTH_LONG).show();  
  37.                 }  
  38.                 break;  
  39.             }  
  40.         }  
  41.     }  
时间: 2024-09-03 11:01:26

android手写板的相关文章

android 仿qq手写板涂鸦

以前博客的链接:点击打开链接   附上关键代码: MainView.java [java] view plaincopy package com.tszy.views;      import java.io.File;   import java.io.FileNotFoundException;   import java.io.FileOutputStream;   import java.io.IOException;      import android.content.Contex

Android编程实现手绘及保存为图片的方法(附demo源码下载)_Android

本文实例讲述了Android编程实现手绘及保存为图片的方法.分享给大家供大家参考,具体如下: 运行效果图预览: 应 yzuo_08 要求做了此Demo,跟以前那个手写板Demo不同的是可以将画布的内容保存为图片. 附上关键代码: MainView.java package com.tszy.views; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; impor

Android Studio 在 win7 下的安装和设置

首先完成android studio下载 http://developer.android.com/sdk/installing/studio.html 其次下载jdk1.7.0_01,并且完成安装: 下面开始进行安装和设置: 由于studio支持系统位数是64位,而我自己所用电脑是32位的,所以安装完成以后出现启动不了,解决方法如下: 用文本工具打开studio.bat 其中找到 SET BITS=IF EXIST "%JRE%\lib\amd64" SET BITS=64 把IF

Android 4.0设计规范10大改变

在拜读和翻译了Android design设计指导后,对比Android 4.0与Android2.3及之前版本的app设计指导,总结了Android 4.0设计的10大改变: 1. 导航栏 (详见模式PATTERNS>导航Navigation) 由之前的物理按键导航(返回.菜单.搜索.主页)变成了嵌入屏幕的虚拟按键(返回.主页.最近任务).   左侧为早期有4个物理按键的手机,右侧为新版只有3个虚拟按钮的手机 把菜单项和搜索项从导航栏去掉,把之前通过长按主页键才出现的最近任务直接展示在导航栏中

拉近与Android的差距:为iOS5设计消息通知

  通知中心作为iOS5的重大更新内容之一,可以将用户的iOS设备里的所有的通知集中放在一个地方,大大方便用户查看和管理.如果用户收到一封新邮 件.一条短信,或者是一个添加好友的请求,无论在任何界面下(包括游戏等全屏应用),用户都可以通过从屏幕顶部向下滑,将通知中心"拉下来",用户可以在 这里查看到所有的通知.所以苹果在iOS5的介绍中说到通知中心是你随时掌握最新生活资讯的绝佳途径. 可能出现通知的场景 一般在下面的场景中iOS应用程序会通知用户有有意思的事情发生了: 1. 收到一条消

Android界面与交互设计原则:以用户为中心

译者按: 在iOS HIG已经强大经典了N年之后,Android终于推出了一套比较系统的HIG(大概是为了配合Android 4.0 Ice Cream Sandwich).仔细比较两套HIG的"设计原则"部分,发现完全是截然不同的两种风格.iOS HIG走的是更专业型的路线,描述严谨且有不少的专业词汇(比如Metaphors.Consistency之类的).而Android则显得亲民许多,不仅描述方式简要易懂,配图鲜明直观,甚至还用了"me"作为了一系列要点的标题

串口-如何通过android截取收银机的打印数据,组装后上传到后台服务器,然后把数据传到打印机打印小票?

问题描述 如何通过android截取收银机的打印数据,组装后上传到后台服务器,然后把数据传到打印机打印小票? 如题.举个例子,收银机连接打印机实现收银.打印小票,现在想在中间接个硬件Android系统,截取打印数据上传到后台服务器,不对现有收银系统改造,不能影响正常收银. 注:该硬件两端通过串口/并口/usb连接收银机与打印机 解决方案 用小票打印机打印 解决方案二: 这种需要抓包的,安卓不可能.... 解决方案三: 这个你需要截取他的网络包就行了.

Android上webview界面切换动画效果

使用Android上的webview控件时需要跳转到下一个html时,要求当前界面缓缓的向左移动,下一个html界面缓缓的从右边出现.这与常规动画不同,一般方式将无法制作出动画.主要实现方法可以先保存上一个网页的快照,与将要跳转的页面结合起来,制作相关动画. 下面是主要代码: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 4

android webview定制contextmenu

问题描述 android webview定制contextmenu 10C 如何实现图种的webview的上下文菜单.需求是获取选中的内容,进行操作. 解决方案 http://www.2cto.com/kf/201310/248762.html 解决方案二: android的ContextMenuAndroid ContextMenuandroid ContextMenu 解决方案三: webview里的问题是可以实现你说的功能,不需要单独设置. 解决方案四: 你把属性设置对就不会错了 解决方案