android项目 之 记事本(8) ----- 画板功能之撤销、恢复和清空

Android实现画板工具 (实现涂写、清除、擦除、保存功能) 一. 效果预览: 二. 实现代码: 1. MyPaintToolsActivity: 自定义一个空的Activity为MyPaintToolsActivity,写入下面代码: package com.example.draw; import androidx.appcompat.app.AppCompatActivity; import android.annotation.SuppressLint; import android.content.Intent; import android.gra 阅读详情

        上一节讨论了手写功能中的删除、恢复和清空功能,那么,画板也就是涂鸦怎么能没有撤销、恢复与清空的功能呢,今天就来实现下。

        终于会做gif图了,看下面的动态图,是不是和QQ白板功能很像。

       

        之前就简单的只实现了在画板上绘图的功能,所以当时将自定义view直接写在了activity中,这一节由于要实现撤销、恢复及清空的功能,所以将分离出来,单独写成了一个java文件PaintView.java,在该自定义view中实现画板的基本操作。

         因为将自定义view单独分离出来,所以需要改到activity的布局文件:如下

         activity_paint.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    
     >
   <com.example.notes.PaintView
       android:id="@+id/paint_layout"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       ></com.example.notes.PaintView>
   
    <GridView 
       android:id="@+id/paintBottomMenu" 
       android:layout_width="match_parent"
       android:layout_height="45dp"
       android:numColumns="auto_fit"
       android:background="@drawable/navigationbar_bg"
       android:horizontalSpacing="10dp"
       android:layout_alignParentBottom="true"
       ></GridView>

</RelativeLayout>

         其中com.example.notes.PaintView为自定义view

         

        这节要实现的操作有撤销,恢复,清空和保存,下面分别讨论三个操作的主要思想:

        要实现撤销与恢复,这里有个前提,就是要将每次绘制的路径存入栈中,这里是存入List中。

             1. 撤销功能:

                   前提:将每次绘制的路径存入List中,即存入savePath中

                   步骤:

                           1) 将画布清空,这里可以使用画成的初始化操作
                           2)  将savePath中的最后一个路径保存到另一个List中,即deletePath(用于恢复),并且将此路径从savePath中删除

                           3)  取出savePath中的所有的路径,重绘在画布上面

          

            2. 恢复功能:

                   前提:将每次撤销的路径存入List中,即存入deletePath中

                   步骤:

                           1)  取出deletePath中的最后一个路径,并保存到savePath中

                           2)  将取出的路径重绘在画布上

                           3)  从deletePath中删除最后一个路径      
            

            3.清空功能:

                          1) 直接清空画布,调用画布的初始化操作

                          2)   将两个保存路径的List清空

           

           4.保存功能:

                          1)  获得当前的时间,以时间作为绘图文件名(避免覆盖)

                          2) 因为画布是建立在Bitmap上的,所以将绘制好的BItMap保存在SD卡上

                          3) 返回绘制文件的路径

         

          以上操作并不难,重点是要将画布上绘制的每个路径保存在List中,这里需要注意,当按下时,应该重新创建路径,抬起时,应该将按下时创建的路径设置为null,只有这样,才能保存每个路径。

          下面直接给出自定义view的代码,里面也有注释:

package com.example.notes;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;

/**
*
* @category: View实现涂鸦、撤销以及重做功能
* @author: jesson20121020
* @link: blog.youkuaiyun.com/jesson20121020
* @date: 2014.9.19
*
*/

public class PaintView extends View  {
	
		private Canvas  mCanvas;
		private Path    mPath;
		private Paint   mBitmapPaint;
		private Bitmap  mBitmap;
		private Paint mPaint;
		
    	private ArrayList<DrawPath> savePath;
    	private ArrayList<DrawPath> deletePath;
    	private DrawPath dp;
    	
    	private float mX, mY;
        private static final float TOUCH_TOLERANCE = 4;
        
        private int bitmapWidth;
        private int bitmapHeight;
        
        public PaintView(Context c) {
            super(c);
            //得到屏幕的分辨率
            DisplayMetrics dm = new DisplayMetrics();
    		((Activity) c).getWindowManager().getDefaultDisplay().getMetrics(dm);
    		
    		bitmapWidth = dm.widthPixels;
    		bitmapHeight = dm.heightPixels - 2 * 45;
            
    		initCanvas();
            savePath = new ArrayList<DrawPath>();
            deletePath = new ArrayList<DrawPath>();
            
        }
        public PaintView(Context c, AttributeSet attrs) {
            super(c,attrs);
            //得到屏幕的分辨率
            DisplayMetrics dm = new DisplayMetrics();
    		((Activity) c).getWindowManager().getDefaultDisplay().getMetrics(dm);
            
    		bitmapWidth = dm.widthPixels;
    		bitmapHeight = dm.heightPixels - 2 * 45;
    		
    		initCanvas();
            savePath = new ArrayList<DrawPath>();
            deletePath = new ArrayList<DrawPath>();
        }
        //初始化画布
        public void initCanvas(){
        	
        	mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setDither(true);
            mPaint.setColor(0xFF00FF00);
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeJoin(Paint.Join.ROUND);
            mPaint.setStrokeCap(Paint.Cap.ROUND);
            mPaint.setStrokeWidth(10);  
            
            mBitmapPaint = new Paint(Paint.DITHER_FLAG);
            
           
            
        	//画布大小 
            mBitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, 
                Bitmap.Config.RGB_565);
            mCanvas = new Canvas(mBitmap);  //所有mCanvas画的东西都被保存在了mBitmap中
            
            mCanvas.drawColor(Color.WHITE);
            mPath = new Path();
            mBitmapPaint = new Paint(Paint.DITHER_FLAG);
            
        }
        
        
        @Override
        protected void onDraw(Canvas canvas) {   
        	
            canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);     //显示旧的画布       
            if (mPath != null) {
    			// 实时的显示
    			canvas.drawPath(mPath, mPaint);
    		}
        }
        //路径对象 
        class DrawPath{
        	Path path;
        	Paint paint;
        }
        
        /**
    	 * 撤销的核心思想就是将画布清空,
    	 * 将保存下来的Path路径最后一个移除掉,
    	 * 重新将路径画在画布上面。
    	 */
        public void undo(){
        	
        	System.out.println(savePath.size()+"--------------");
        	if(savePath != null && savePath.size() > 0){
        		//调用初始化画布函数以清空画布
        		initCanvas();
        		
            	//将路径保存列表中的最后一个元素删除 ,并将其保存在路径删除列表中
            	DrawPath drawPath = savePath.get(savePath.size() - 1);
            	deletePath.add(drawPath);
            	savePath.remove(savePath.size() - 1);
            	
            	//将路径保存列表中的路径重绘在画布上
            	Iterator<DrawPath> iter = savePath.iterator();		//重复保存
    			while (iter.hasNext()) {
    				DrawPath dp = iter.next();
    				mCanvas.drawPath(dp.path, dp.paint);
    				
    			}
    			invalidate();// 刷新
        	}
        }
        /**
    	 * 恢复的核心思想就是将撤销的路径保存到另外一个列表里面(栈),
    	 * 然后从redo的列表里面取出最顶端对象,
    	 * 画在画布上面即可
    	 */
        public void redo(){
        	if(deletePath.size() > 0){
        		//将删除的路径列表中的最后一个,也就是最顶端路径取出(栈),并加入路径保存列表中
        		DrawPath dp = deletePath.get(deletePath.size() - 1);
        		savePath.add(dp);
        		//将取出的路径重绘在画布上
        		mCanvas.drawPath(dp.path, dp.paint);
        		//将该路径从删除的路径列表中去除
        		deletePath.remove(deletePath.size() - 1);
        		invalidate();
        	}
        }
        /*
         * 清空的主要思想就是初始化画布
         * 将保存路径的两个List清空
         * */
        public void removeAllPaint(){
        	//调用初始化画布函数以清空画布
    		initCanvas();
    		invalidate();//刷新
    		savePath.clear();
    		deletePath.clear();
        }
        
       /* 
        * 保存所绘图形
        * 返回绘图文件的存储路径
        * */
        public String saveBitmap(){
      		//获得系统当前时间,并以该时间作为文件名
      		SimpleDateFormat   formatter   =   new   SimpleDateFormat   ("yyyyMMddHHmmss");  
            Date   curDate   =   new   Date(System.currentTimeMillis());//获取当前时间 
            String   str   =   formatter.format(curDate);  
            String paintPath = "";
            str = str + "paint.png";
            File dir = new File("/sdcard/notes/");
            File file = new File("/sdcard/notes/",str);
            if (!dir.exists()) { 
            	dir.mkdir(); 
            } 
            else{
            	if(file.exists()){
            		file.delete();
            	}
            }
            
    		try {
    			FileOutputStream out = new FileOutputStream(file);
    			mBitmap.compress(Bitmap.CompressFormat.PNG, 100, out); 
    			out.flush(); 
    			out.close(); 
    			//保存绘图文件路径
    			paintPath = "/sdcard/notes/" + str;
    			
    	
    		} catch (FileNotFoundException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} 
            
    		return paintPath;
      	}
        
        
        private void touch_start(float x, float y) {
            mPath.reset();//清空path
            mPath.moveTo(x, y);
            mX = x;
            mY = y;
        }
        private void touch_move(float x, float y) {
            float dx = Math.abs(x - mX);
            float dy = Math.abs(y - mY);
            if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
                //mPath.quadTo(mX, mY, x, y);
                 mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);//源代码是这样写的,可是我没有弄明白,为什么要这样?
                mX = x;
                mY = y;
            }
        }
        private void touch_up() {
            mPath.lineTo(mX, mY);
            mCanvas.drawPath(mPath, mPaint);
            savePath.add(dp);
            mPath = null;
            
        }
        
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            float x = event.getX();
            float y = event.getY();
            
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    
                    mPath = new Path();
                    dp = new DrawPath();
                    dp.path = mPath;
                    dp.paint = mPaint;
                    
                    touch_start(x, y);
                    invalidate(); //清屏
                    break;
                case MotionEvent.ACTION_MOVE:
                    touch_move(x, y);
                    invalidate();
                    break;
                case MotionEvent.ACTION_UP:
                    touch_up();
                    invalidate();
                    break;
            }
            return true;
        }
  
}

          

            接下来,就是在Activity中调用自定义的View中的这些操作方法:

	private PaintView paintView;
         private GridView paint_bottomMenu;
	paint_bottomMenu = (GridView)findViewById(R.id.paintBottomMenu);
	paint_bottomMenu.setOnItemClickListener(new MenuClickEvent());
		
	paintView = (PaintView)findViewById(R.id.paint_layout);
          //设置菜单项监听器
  	 class MenuClickEvent implements OnItemClickListener{

  		@Override
  		public void onItemClick(AdapterView<?> parent, View view, int position,
  				long id) {
  			Intent intent;
  			switch(position){
  			//画笔大小
  			case 0:
  				
  				break;
  			//颜色
  			case 1:
  				
  				break;
  			//撤销
  			case 2:
  				paintView.undo();
  				break;
  			//恢复 
  			case 3:
  				paintView.redo();
  				break;
  			//清空
  			case 4 :
  				paintView.removeAllPaint();
  				break;
  			
  			default :
  				break;
  			
  			}
  		
  		}
 
  	}

          这里因为有保存文件,所以要有读写SD卡的权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

         

         至此,已完成了画板的撤销,恢复,清空,保存的功能,至于其他的功能,以后慢慢实现。




       

 

 

 

Android 记事本功能的简单实现,成为阿里P7Android架构师到底有多难 if (itemView == null){ throw new IllegalArgumentException(“item View can not be null!”); } this.itemView = itemView; itemIcon = itemView.findViewById(R.id.rand_icon); itemNoteTitle = itemView.findViewById(R.id.item_note_title); itemNoteDate = itemView.find 阅读详情

相关推荐

Android画板开发之撤销反撤销功能

主要为大家详细介绍了Android画板开发之撤销,反撤销功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

安卓——EditText的撤销与反撤销功能实现

在使用记事本等文本类app时,我们常常能看到编辑框的文本可以。那如何实现这样的功能呢?今天我会一步步讲明我实现此功能的步骤。当然文末会有完整代码和我放在JitPack的依赖库,大家如果比较匆忙的话,可以直接查看目录3和4,以下的实现步骤是我对该知识点的梳理和实现逻辑,大家可看可不看。

薪火_的博客 1126

android原生代码记事本

1、android简单记事本demo 2、可增加一条记事文本 3、可以编辑点击的当前记事项 4、可以关键字搜索文本

Android MVP模式实战练习之一步一步打造一款简易便笺app(一)

介绍相信做开发的我们,都是知道MVP模式的,该模式将提供数据的(M)Model和显示视图的(V)View互相隔离,使用(P)Presenter作为控制层来联系M和V。介绍MVP的文章也是相当多的,不过还是自己动手写一写收获更大。本文便是使用mvp模式一步一步去打造一款简易的便笺app 谷歌为了让我们能好好学习mvp模式,出品了一个开源项目android-architecture,该项目使用了不同

勇朝陈的博客 4460

Keil MDK安装NRF52832开发环境全攻略(附系统时间错误解决方案)

本文详细介绍了如何使用Keil MDK搭建NRF52832开发环境,包括基础软件安装、项目配置关键步骤以及常见问题解决方案。特别针对系统时间错误导致的编译失败问题提供了实用解决方法,帮助开发者快速上手NRF52832开发。

weixin_29168153的博客 505

概率整形 Peobabilistic Shaping PS 第一节

概率整形概述 概率整形(Peobabilistic Shaping, PS)是一种针对于调制格式的优化技术,它为光通信通信提供了非常高的灵活性,但不会增加系统复杂性。尤其是光通信中的非线性问题会限制功率,使得PS就像为光通信量身定做的一样。 PS技术能够在不增加发送功率的前提下,获得高频谱效率和传输容量。2016年在使用PS技术的实验中实现了6600km单模光纤的65Tbit/s数据的传输。 到目前位置PS技术的研究主要集中在具有相干检测的单载波光纤传输。 概率整形的基本原理 概率整形技术就是通过在编码前

Explore_OuO的博客 8126

备忘录模式实现画图板撤销操作

设计模式给人以抽象的概念,容易让初学者望而却步。本文将通过一个图形界面实现画板的撤销操作,让读者对于设计模式之一的“备忘录模式”有一个直观的感受。

littleschemer的博客 3043

【自然语言处理(NLP)实战】LSTM网络实现中文文本情感分析(手把手与教学超详细)

在当今数字化时代,人们在社交媒体、评论平台以及各类在线交流中产生了海量的文本数据。这些数据蕴含着丰富的情感信息,从而成为了深入理解用户态度、市场趋势,甚至社会情绪的宝贵资源。自然语言处理(NLP)的发展为我们提供了强大的工具,使得对文本情感进行分析成为可能。在这个领域中,长短时记忆网络(LSTM)凭借其能够捕捉文本序列中长距离依赖关系的能力,成为了情感分析任务中的一项重要技术。通过详细的步骤和示例代码,深入了解如何处理中文文本数据、构建LSTM模型、进行训练和评估。

halo的博客 2万+

Android背景颜色恢复,android 自定义 画板 实现粗细,颜色,橡皮,撤销恢复等

自定义画板类:python/*** Created by zjp on 2018/8/14.*/public class TaletteViews extends View {private Paint mPaint;private Path mPath;private float mLastX;private float mLastY;private Bitmap mBufferBitmap;p...

weixin_35569211的博客 179

智能车轮腿组‘定点排雷’科目全解析:从雷区识别到姿态控制

本文深入解析了智能车竞赛轮腿穿越组‘定点排雷’科目的核心技术。从构建鲁棒的视觉识别系统,到融合编码器与IMU进行厘米级定位,再到实现框内高精度旋转的姿态控制,提供了一套完整的从感知到执行的闭环技术方案,助力参赛队伍攻克这一高难度科目。

weixin_29161719的博客 640

【AVRCP】规范精讲[19]: 媒体属性全解析,让你的蓝牙设备显示完整歌曲信息

AVRCP协议中的媒体属性是蓝牙音频设备传输歌曲元数据的关键,包含标题、艺术家、专辑等32位ID标识的键值对信息。规范要求字符串属性必须使用UTF-8编码,但乱码问题频发(如中文显示异常),主因是设备未遵循编码标准或使用GBK等非规范格式。常见问题包括信息不全(仅显示标题)、封面缺失(因带宽限制或格式不支持)及更新延迟(通知机制未启用)。解决方案包括强制UTF-8编码、优化封面大小(如300x300像素JPEG)、主动请求缺失属性。Android示例代码展示了通过广播接收器解析媒体属性的方法。

byte轻骑兵的技术小窝 1万+

自定义view实现涂鸦(画板)功能

自定义view实现涂鸦功能,包括撤销、恢复、重做、保存以及橡皮擦(在风格中实现)功能,小模块包括画笔颜色调整、画笔尺寸调整、画笔类型(包括正常画笔以及橡皮擦功能),之后又陆续实现了画圆、画矩形以及画箭头的功能,这里我们先完成前面的需求 撤销: /** * 撤销 * 撤销的核心思想就是将画布清空, * 将保存下来的Path路径最后一个移除掉, * 重新将路

微草还在成长中 1万+

2ED2410-EM的使用

2ED2410-EM的使用

让你爱上电路设计 972

android项目 之 记事本(6)----- 添加手写

实现类似手机QQ白板中手写功能,而且是全屏手写,实时刷新

jesson20121020的专栏 4279

binning模式下和normal模式下相同曝光参数相同场景加权亮度差异消除方案优化(一)

摘要:针对ISP参数设置中浮点权重系数需转换为整数的问题,提出整数邻域搜索方案。该方法在浮点最优解附近(±1/±2)进行局部搜索,通过逐阶微调找到误差最小的整数权重组合,避免直接取整导致的误差反弹(误差从0.8%降至0.35%)。方案结合范围约束(1~15)和单调性约束(暗端递减、亮端递增),兼顾计算效率(单图耗时<10ms)与硬件兼容性,显著优于暴力搜索和简单取整,满足工程落地需求。

大熊 97

fanuc机器人KAREL中 函数的应用

本次课程讲解编程的思路。很多的同学都玩过积木,一个一个的模块逐渐累积起来,通过彼此之间的相互联系,最终形成一个完整的整体。其实编程也是这样。 将一个对象根据其特点进行模块化拆分,尤其是一些特点非常相似的内容,将其变成一个模块。然后通过传递参数,实现不同的功能,这就是模块化编程。

haier123888的博客 2744

自定义SurfaceView通过Canvas、Path、Paint实现画板、画布

三个方法,一下是完整代码+注释。

u013208026的博客 867

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

android 记事本demo_android开发中如何实现手写输入的记事本

展开全部实现手写功能的主要步骤:1. 自定义两个View,一个是TouchView,用于在上面画图,另一个是EditText,用于将手写的字显32313133353236313431303231363533e4b893e5b19e31333337613236示在其中,并且,要将两个自定义View通过FrameLayout帧式布局重叠在起,以实现全屏手写的功能。2 在TouchView中实现写字,并...

weixin_39612220的博客 765

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Android 开发 - 一些画板第三方库(DrawBoard、FingerPaintView、PaletteLib)

Android 开发 - 一些画板第三方库(DrawBoard、FingerPaintView、PaletteLib)

weixin_52173250的博客 1424

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

支持笔锋效果的手写签字控件

基于安卓的手写签字控件,支持笔锋 github:https://github.com/GdinKing/HandWrite 功能 空白画板手写,田字格逐字手写 实现笔锋效果 支持橡皮擦,撤回/恢复,清空画布功能 画笔颜色大小设置 支持传入初始图片 画布大小设置,文字区域截取 主题颜色设置 支持传入初始显示图片 适配横竖屏布局 示例 用法 请下载github源码参考示例...

king的专栏 5157

android 自定义画图,Android 自定义view,画图板练习

项目中想要推动一个简易画图板的需求,功能并不复杂,就是6个很常见的功能画图板陈小默同学有一个比较复杂,强大,高效的CrazyPalette,同学间商业互吹下,哈哈。里面基本常见的操作都有,代码写的很高,只是用的Kotlin,不过我应该的也是一个简单的绘图板,我参考了他的一些想法以及另外一篇android项目 之 记事本 ----- 画板功能之撤销、恢复和清空,做了一个简单的PaintView之前在...

weixin_34739646的博客 379

Android 自定义view画图板练习

项目中想要实现一个简易画图板的需求,功能并不复杂,就是6个很常用的功能 画图板 陈小默同学有一个比较复杂,强大,高效的CrazyPalette,同学间商业互吹下,哈哈。里面基本常用的操作都有,代码写的很好,只是用的Kotlin,不过我需要的只是一个简单的绘图板,我参考了他的一些思路以及另外一篇android项目 之 记事本 ----- 画板功能之撤销、恢复和清空,做了一个简单的PaintV...

mm_name_zhang的博客 482

Android 自定义view,画图板练习

项目中想要实现一个简易画图板的需求,功能并不复杂,就是6个很常用的功能 画图板 陈小默同学有一个比较复杂,强大,高效的CrazyPalette,同学间商业互吹下,哈哈。里面基本常用的操作都有,代码写的很好,只是用的Kotlin,不过我需要的只是一个简单的绘图板,我参考了他的一些思路以及另外一篇android项目 之 记事本 ----- 画板功能之撤销、恢复和清空,做了一个简单的PaintV...

qq_32138419的博客 339

HarmonyOS API 23 ArkTS 实战:实现一个轻量级手绘涂鸦画板应用

本文基于HarmonyOS NEXT 6.1 + API 23纯血架构,完整实现轻量级手绘涂鸦画板实训项目。项目深度吃透API23单向数据流、强类型ArkTS编程、ArkGraphics2D原生Canvas图形渲染、多点触摸事件调度、路径结构化存储、渲染性能节流、图形资源生命周期管控七大核心新特性,摆脱传统画板Demo线条卡顿、撤销逻辑简陋、渲染频繁闪烁、参数不同步等缺陷,完整实现自由手绘、多色画笔、笔触调节、单步撤销、一键清空画布、触摸异常处理全链路业务。

qyszwq的博客 402

android项目 之 记事本(6)----- 加入手写

想必大家都用过QQ的白板功能,里面主要有两项,一个是涂鸦功能,事实上类似于上节的画板功能,而还有一个就是手写,那记事本怎么能没有这个功能呢,今天就来为我们的记事本加入手写功能。 先上图,看看效果: 看了效果图,是不是心动了呢?那就赶紧着手做吧,事实上,手写功能并不难实现,大体就是全屏书写,定时发送handle消息,更新activi...

weixin_30563319的博客 130
上一篇: 数据结构(C实现)------- 双向链表
下一篇: 数据结构(C实现)------- 顺序栈
jesson20121020
博客等级 码龄15年 361粉丝 99原创
评论 7
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值