如何在图片上画画呢?这里写了一个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();
}
}
三、主页面布局文件
主页面布局文件
<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"
android:layout_width=\"fill_parent\"
android:layout_height=\"fill_parent\"
android:gravity=\"center_horizontal\"
android:orientation=\"vertical\" >
<LinearLayout
android:layout_width=\"match_parent\"
android:layout_height=\"50dp\"
android:orientation=\"horizontal\"
>
<LinearLayout
android:layout_width=\"0dp\"
android:layout_height=\"match_parent\"
android:layout_weight=\"1\"
android:gravity=\"center\"
>
<TextView
android:id=\"@+id/tv_30\"
android:layout_width=\"30dp\"
android:layout_height=\"30dp\"
android:background=\"@drawable/bg_notifaction\"
/>
</LinearLayout>
<LinearLayout
android:layout_width=\"0dp\"
android:layout_height=\"match_parent\"
android:layout_weight=\"1\"
android:gravity=\"center\"
>
<TextView
android:id=\"@+id/tv_25\"
android:layout_width=\"25dp\"
android:layout_height=\"25dp\"
android:background=\"@drawable/bg_notifaction\"
/>
</LinearLayout>
<LinearLayout
android:layout_width=\"0dp\"
android:layout_height=\"match_parent\"
android:layout_weight=\"1\"
android:gravity=\"center\"
>
<TextView
android:id=\"@+id/tv_20\"
android:layout_width=\"20dp\"
android:layout_height=\"20dp\"
android:background=\"@drawable/bg_notifaction\"
/>
</LinearLayout>
<LinearLayout
android:layout_width=\"0dp\"
android:layout_height=\"match_parent\"
android:layout_weight=\"1\"
android:gravity=\"center\"
>
<TextView
android:id=\"@+id/tv_15\"
android:layout_width=\"15dp\"
android:layout_height=\"15dp\"
android:background=\"@drawable/bg_notifaction\"
/>
</LinearLayout>
<LinearLayout
android:layout_width=\"0dp\"
android:layout_height=\"match_parent\"
android:layout_weight=\"1\"
android:gravity=\"center\"
>
<TextView
android:id=\"@+id/tv_10\"
android:layout_width=\"10dp\"
android:layout_height=\"10dp\"
android:background=\"@drawable/bg_notifaction\"
/>
</LinearLayout>
<LinearLayout
android:layout_width=\"0dp\"
android:layout_height=\"match_parent\"
android:layout_weight=\"1\"
android:gravity=\"center\"
>
<TextView
android:id=\"@+id/tv_5\"
android:layout_width=\"5dp\"
android:layout_height=\"5dp\"
android:background=\"@drawable/bg_notifaction\"
/>
</LinearLayout>
<LinearLayout
android:layout_width=\"0dp\"
android:layout_height=\"match_parent\"
android:layout_weight=\"1\"
android:gravity=\"center\"
>
<TextView
android:id=\"@+id/tv_2\"
android:layout_width=\"2dp\"
android:layout_height=\"2dp\"
android:background=\"@drawable/bg_notifaction\"
/>
</LinearLayout>
</LinearLayout>
<picturegame.view.GameView
android:layout_width=\"match_parent\"
android:layout_height=\"300dp\"
android:id=\"@+id/gameview\"
/>
<Button
android:layout_width=\"200dp\"
android:layout_height=\"80dp\"
android:text=\"clear\"
android:textColor=\"@color/black\"
android:id=\"@+id/btn_clear\"
/>
</LinearLayout>
四、主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;
}
}
}
五、效果
运行效果图如下
六、疑问
当线条变粗时,线条会出现如上图中不连续的问题。请问高手这个怎么处理呢?我猜测应该要运行算法,但还不知道怎么运行。
文章就为大家介绍到这,其实还有许多知识点小编也不是很清楚,希望大家可以进行补充扩展,共同进步。
本文地址:https://www.stayed.cn/item/18874
转载请注明出处。
本站部分内容来源于网络,如侵犯到您的权益,请 联系我