热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android简单实现画图功能

这篇文章主要为大家详细介绍了Android简单实现画图功能的方法,以及实现过程中遇到的问题,感兴趣的小伙伴们可以参考一下

如何在图片上画画呢?这里写了一个demo,供大家参考
一、先看一眼工程结构
工程结构:

二、自定义view
这个自定义view实现了保留轨迹的功能,代码如下

package picturegame.view; 
 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Paint.Style; 
import android.util.AttributeSet; 
import android.view.MotionEvent; 
import android.view.View; 
import com.winton.picturegame.R; 
 
public class GameView extends View{ 
   
  private Paint paint = null; // 
   
  private Bitmap originalBitmap = null;//原始图 
   
  private Bitmap new1Bitmap = null; 
   
  private Bitmap new2Bitmap = null; 
   
  private float clickX =0; 
   
  private float clickY=0; 
   
  private float startX=0; 
   
  private float startY=0; 
   
  private boolean isMove = true; 
   
  private boolean isClear = false; 
   
  private int color =Color.RED;//默认画笔颜色为红色 
   
  private float strokeWidth =2.0f;//默认画笔粗度 
   
   
 
  public GameView(Context context) { 
    this(context,null); 
    // TODO Auto-generated constructor stub 
  } 
  public GameView(Context context,AttributeSet atts) { 
    this(context,atts,0); 
    // TODO Auto-generated constructor stub 
  } 
  public GameView(Context context,AttributeSet atts,int defStyle) { 
    super(context,atts,defStyle); 
    // TODO Auto-generated constructor stub 
     
    originalBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.default_pic).copy(Bitmap.Config.ARGB_8888, true);//加载一张背景 
    new1Bitmap=originalBitmap.createBitmap(originalBitmap); 
  } 
 
  //清除函数 
  public void clear(){ 
    isClear =true; 
    new2Bitmap=originalBitmap.createBitmap(originalBitmap); 
    invalidate();//重载 
  } 
   
  public void setStrokeWidth(float width){ 
    this.strokeWidth=width; 
    initPaint(); 
  } 
  @Override 
  protected void onDraw(Canvas canvas) { 
    // TODO Auto-generated method stub 
    super.onDraw(canvas); 
    canvas.drawBitmap(writer(new1Bitmap),0,0, null); 
     
  } 
   
  @Override 
  public boolean onTouchEvent(MotionEvent event) { 
    // TODO Auto-generated method stub 
     
     
    clickX =event.getX(); 
     
    clickY=event.getY(); 
     
    if(event.getAction()==MotionEvent.ACTION_DOWN){ 
      isMove =false; 
      invalidate(); 
      return true; 
    } 
    else if(event.getAction()==MotionEvent.ACTION_MOVE){ 
      isMove =true; 
      invalidate(); 
      return true; 
    } 
     
     
    return super.onTouchEvent(event); 
  } 
   
  /** 
  * @Title: writer 
  * @Description: TODO(生成bitmap) 
  * @param @param pic 
  * @param @return  设定文件 
  * @return Bitmap  返回类型 
  * @throws 
  */ 
  public Bitmap writer(Bitmap pic){ 
    initPaint(); 
     
    Canvas canvas =null; 
    if(isClear){ 
      canvas=new Canvas(new2Bitmap); 
    }else{ 
      canvas=new Canvas(pic); 
    } 
     
    if(isMove){ 
      canvas.drawLine(startX, startY, clickX, clickY, paint);//划线 
    } 
    startX = clickX; 
     
    startY =clickY; 
    if(isClear){ 
      return new2Bitmap; 
    } 
    return pic; 
  } 
   
  private void initPaint(){ 
     
    paint = new Paint();//新建画笔 
     
    paint.setStyle(Style.STROKE);//设置为画线 
     
    paint.setAntiAlias(true);//可以让线条圆滑一些 
     
    paint.setColor(color);//设置画笔颜色 
     
    paint.setStrokeWidth(strokeWidth);//设置画笔线条的粗细 
  } 
   
  /** 
  * @Title: setColor 
  * @Description: TODO(设置线条颜色的对外接口) 
  * @param @param color  设定文件 
  * @return void  返回类型 
  * @throws 
  */ 
  public void setColor(int color){ 
     
    this.color=color; 
    initPaint(); 
  } 
   
   
} 


三、主页面布局文件
主页面布局文件

 
   
   
     
       
     
     
    
       
     
     
     
       
     
     
     
       
     
     
      
       
     
     
       
     
     
      
       
     
   
   
   
   
       
   
  

四、主Activity代码

package com.winton.picturegame; 
 
import picturegame.view.GameView; 
import android.os.Bundle; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.TextView; 
 
import com.winton.basemodule.BaseActivity; 
 
public class MainActivity extends BaseActivity implements OnClickListener { 
 
  private GameView gameview = null; 
  private Button clear = null; 
   
  private TextView tv30,tv25,tv20,tv15,tv10,tv5,tv2; 
 
  @Override 
  protected void onCreate(Bundle savedInstanceState) { 
    // TODO Auto-generated method stub 
    super.onCreate(savedInstanceState); 
  } 
 
  @Override 
  public void initView() { 
    // TODO Auto-generated method stub 
    setContentView(R.layout.activity_main); 
     
    gameview=(GameView)findViewById(R.id.gameview); 
    clear =(Button)findViewById(R.id.btn_clear); 
    tv30=(TextView)findViewById(R.id.tv_30); 
    tv25=(TextView)findViewById(R.id.tv_25); 
    tv20=(TextView)findViewById(R.id.tv_20); 
    tv15=(TextView)findViewById(R.id.tv_15); 
    tv10=(TextView)findViewById(R.id.tv_10); 
    tv5=(TextView)findViewById(R.id.tv_5); 
    tv2=(TextView)findViewById(R.id.tv_2); 
  } 
 
  @Override 
  public void initListener() { 
    // TODO Auto-generated method stub 
    clear.setOnClickListener(this); 
    tv30.setOnClickListener(this); 
    tv25.setOnClickListener(this); 
    tv20.setOnClickListener(this); 
    tv15.setOnClickListener(this); 
    tv10.setOnClickListener(this); 
    tv5.setOnClickListener(this); 
    tv2.setOnClickListener(this); 
     
  } 
 
  @Override 
  public void initData() { 
    // TODO Auto-generated method stub 
     
  } 
  @Override 
  public void onClick(View v) { 
    // TODO Auto-generated method stub 
    if(v==clear){ 
      gameview.clear(); 
      return; 
    } 
    if(v==tv30){ 
      gameview.setStrokeWidth(30f); 
      return; 
    } 
    if(v==tv25){ 
      gameview.setStrokeWidth(25f); 
      return; 
    } 
    if(v==tv20){ 
      gameview.setStrokeWidth(20f); 
      return; 
    } 
    if(v==tv15){ 
      gameview.setStrokeWidth(15f); 
      return; 
    } 
    if(v==tv10){ 
      gameview.setStrokeWidth(10f); 
      return; 
    } 
    if(v==tv5){ 
      gameview.setStrokeWidth(5f); 
      return; 
    } 
    if(v==tv2){ 
      gameview.setStrokeWidth(2f); 
      return; 
    } 
     
  } 
    
} 

五、效果
运行效果图如下

六、疑问
当线条变粗时,线条会出现如上图中不连续的问题。请问高手这个怎么处理呢?我猜测应该要运行算法,但还不知道怎么运行。

文章就为大家介绍到这,其实还有许多知识点小编也不是很清楚,希望大家可以进行补充扩展,共同进步。


推荐阅读
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • Android LED 数字字体的应用与实现
    本文介绍了一种适用于 Android 应用的 LED 数字字体(digital font),并详细描述了其在 UI 设计中的应用场景及其实现方法。这种字体常用于视频、广告倒计时等场景,能够增强视觉效果。 ... [详细]
  • RecyclerView初步学习(一)
    RecyclerView初步学习(一)ReCyclerView提供了一种插件式的编程模式,除了提供ViewHolder缓存模式,还可以自定义动画,分割符,布局样式,相比于传统的ListVi ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 解决JAX-WS动态客户端工厂弃用问题并迁移到XFire
    在处理Java项目中的JAR包冲突时,我们遇到了JaxWsDynamicClientFactory被弃用的问题,并成功将其迁移到org.codehaus.xfire.client。本文详细介绍了这一过程及解决方案。 ... [详细]
  • 本文介绍如何使用布局文件在Android应用中排列多行TextView和Button,使其占据屏幕的特定比例,并提供示例代码以帮助理解和实现。 ... [详细]
  • 计算机网络复习:第五章 网络层控制平面
    本文探讨了网络层的控制平面,包括转发和路由选择的基本原理。转发在数据平面上实现,通过配置路由器中的转发表完成;而路由选择则在控制平面上进行,涉及路由器中路由表的配置与更新。此外,文章还介绍了ICMP协议、两种控制平面的实现方法、路由选择算法及其分类等内容。 ... [详细]
  • 本文将介绍如何使用 Go 语言编写和运行一个简单的“Hello, World!”程序。内容涵盖开发环境配置、代码结构解析及执行步骤。 ... [详细]
  • 线性Kalman滤波器在多自由度车辆悬架主动控制中的应用研究
    本文探讨了线性Kalman滤波器(LKF)在不同自由度(2、4、7)的车辆悬架系统中进行主动控制的应用。通过详细的仿真分析,展示了LKF在提升悬架性能方面的潜力,并总结了调参过程中的关键要点。 ... [详细]
  • 本文探讨了Hive中内部表和外部表的区别及其在HDFS上的路径映射,详细解释了两者的创建、加载及删除操作,并提供了查看表详细信息的方法。通过对比这两种表类型,帮助读者理解如何更好地管理和保护数据。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • C++实现经典排序算法
    本文详细介绍了七种经典的排序算法及其性能分析。每种算法的平均、最坏和最好情况的时间复杂度、辅助空间需求以及稳定性都被列出,帮助读者全面了解这些排序方法的特点。 ... [详细]
  • 本文介绍了多个关于JavaScript的书籍资源、实用工具和编程实例,涵盖从入门到进阶的各个阶段,帮助读者全面提升JavaScript编程能力。 ... [详细]
  • 分享一个简化版的Silverlight链接图项目:Link Map Simplified
    本文介绍了一个使用Silverlight开发的可视化工具,主要用于展示和操作复杂的实体关系图(Graph)。该工具在犯罪调查系统中得到了广泛应用,帮助用户直观地获取和理解相关信息。 ... [详细]
author-avatar
鬎瀰_418
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有