Java 将位图加载到画布并在其上绘制
我喜欢做一个应用程序,像一个小油漆,我必须得到一个位图,画在画布上,然后,画在它上面(与菲格)。。。所以,我实际上有这个代码:Java 将位图加载到画布并在其上绘制,java,android,bitmap,android-canvas,draw,Java,Android,Bitmap,Android Canvas,Draw,我喜欢做一个应用程序,像一个小油漆,我必须得到一个位图,画在画布上,然后,画在它上面(与菲格)。。。所以,我实际上有这个代码: import java.io.File; import java.io.FileOutputStream; import java.util.ArrayList; import android.content.Context; import android.graphics.BitmapFactory; import android.graphics.Canvas;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Environment;
import android.util.Log;
import android.graphics.Bitmap;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
public class DrawView extends View implements OnTouchListener {
private Canvas mCanvas;
private Path mPath;
public Paint mPaint;
private ArrayList<Path> paths = new ArrayList<Path>();
private boolean start = true;
public DrawView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener((OnTouchListener) this);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(4);
mPaint.setDither(true);
mPaint.setFilterBitmap(true);
mCanvas = new Canvas();
mPath = new Path();
paths.add(mPath);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
@Override
protected void onDraw(Canvas canvas) {
for (Path p : paths) {
canvas.drawPath(p, mPaint);
}
if (start) {
Bitmap bmp = BitmapFactory.decodeResource(getResources(),
R.drawable.v01);
canvas.drawBitmap(bmp, 0, 0, mPaint);
start = false;
}
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private void touch_start(float x, float y) {
mPath.reset();
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 + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
mPath = new Path();
paths.add(mPath);
}
public boolean onTouch(View arg0, MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
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;
}
}
导入java.io.File;
导入java.io.FileOutputStream;
导入java.util.ArrayList;
导入android.content.Context;
导入android.graphics.BitmapFactory;
导入android.graphics.Canvas;
导入android.graphics.Color;
导入android.graphics.Paint;
导入android.graphics.Path;
导入android.os.Environment;
导入android.util.Log;
导入android.graphics.Bitmap;
导入android.view.MotionEvent;
导入android.view.view;
导入android.view.view.OnTouchListener;
公共类DrawView扩展了视图实现OnTouchListener{
私人帆布mCanvas;
专用路径mPath;
公共油漆;
私有ArrayList路径=新ArrayList();
private boolean start=true;
公共绘图视图(上下文){
超级(上下文);
设置聚焦(真);
setFocusableInTouchMode(真);
this.setOnTouchListener((OnTouchListener)this);
mPaint=新油漆();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(油漆、样式、笔划);
mPaint.setStrokeJoin(油漆.连接.圆形);
mPaint.setStrokeCap(油漆盖圆形);
mPaint.设定行程宽度(4);
mPaint.setDither(true);
mPaint.setFilterBitmap(true);
mCanvas=新画布();
mPath=新路径();
路径。添加(mPath);
}
@凌驾
已更改尺寸的受保护空心(整数w、整数h、整数oldw、整数oldh){
super.onSizeChanged(w,h,oldw,oldh);
}
@凌驾
受保护的void onDraw(画布){
用于(路径p:路径){
画布绘制路径(p,mPaint);
}
如果(启动){
位图bmp=BitmapFactory.decodeResource(getResources(),
R.可拉深(v01);
drawBitmap(bmp,0,0,mPaint);
开始=错误;
}
}
私人浮动mX,我的;
专用静态最终浮动接触公差=4;
专用无效触摸启动(浮动x、浮动y){
mPath.reset();
移动到(x,y)的速度;
mX=x;
mY=y;
}
私有无效触摸移动(浮动x、浮动y){
float dx=Math.abs(x-mX);
float dy=Math.abs(y-mY);
如果(dx>=接触公差| | dy>=接触公差){
兆帕四分之一秒(mX,mY,(x+mX)/2,(y+mY)/2);
mX=x;
mY=y;
}
}
私人空间修补(){
mPath.lineTo(mX,mY);
//将路径提交到我们的屏幕外
mCanvas.drawPath(mPath,mPaint);
//杀了它,这样我们就不会重复抽签了
mPath=新路径();
路径。添加(mPath);
}
公共布尔onTouch(视图arg0,运动事件){
float x=event.getX();
float y=event.getY();
开关(event.getAction()){
case MotionEvent.ACTION\u DOWN:
触摸启动(x,y);
使无效();
打破
case MotionEvent.ACTION\u移动:
触摸移动(x,y);
使无效();
打破
case MotionEvent.ACTION\u UP:
润色;
使无效();
打破
}
返回true;
}
}
有了这段代码,我可以画在画布上,并得到位图的第一种方式。。。但是,如果我触摸,位图会消失,这是因为在每次onTouch事件中,我都会根据路径再次绘制。。。我怎么做我喜欢的呢?我的意思是,得到位图,然后在上面画 如果将canvas.drawBitmap()移到if语句之外,应该可以使用。继续解码,但将实际的绘图移出。我不确定您的问题是什么。每次运行
onDraw
时都必须重新绘制位图,否则将什么都没有。你有没有注意到任何性能损失
您不必做的是在每个上解码资源,使其无效
将bmp声明为全局变量
Bitmap bmp;
将位图存储在构造函数上:
DrawView(Context context){
...
bmp = BitmapFactory.decodeResource(getResources(),
R.drawable.v01);
}
并删除绘制方法上的if。你不想让if出现。每次调用invalidate时都必须重新绘制位图。但这不应导致任何性能问题
canvas.drawBitmap(bmp, 0, 0, mPaint);
这将使您的查看速度非常慢,但如果删除if(start)
语句,则位图不会消失
一个稍微好一点的方法是将canvas.drawBitmap()
置于if(start)
方法之外,但这仍然很慢,因为每次触摸屏幕时都会绘制位图
实际上,这是因为每次调用onDraw()
时,都会向您传递一个空白位图。这意味着您必须在每次调用onDraw时重新绘制所有内容,但由于您只是第一次设置位图,因此当再次调用on draw时,位图不会再次添加,因此会消失。解决了此问题,我使用此代码可以加载图像并在其上绘制
DrawView.java
package com.example.com.dibuja;
import java.util.ArrayList;
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.Path;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
public class DrawView extends View implements OnTouchListener {
private Canvas mCanvas;
private Path mPath;
public Paint mPaint;
private ArrayList<Path> paths = new ArrayList<Path>();
Bitmap bmp;
public DrawView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
bmp = BitmapFactory.decodeResource(getResources(), R.drawable.v01);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.BLUE);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(6);
mCanvas = new Canvas();
mPath = new Path();
paths.add(mPath);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(bmp, 0, 0, mPaint);
for (Path p : paths) {
canvas.drawPath(p, mPaint);
}
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 0;
Draw dw = new Draw();
private void touch_start(float x, float y) {
mPath.reset();
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 + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
mPath = new Path();
paths.add(mPath);
}
@Override
public boolean onTouch(View arg0, MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
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;
}
}
DrawView.java
包com.example.com.dibuja;
导入java.util.ArrayList;
导入android.content.Context;
导入android.graphics.Bitmap;
导入android.graphics.BitmapFactory;
导入android.graphics.Canvas;
导入android.graphics.Color;
导入android.graphics.Paint;
导入android.graphics.Path;
导入android.view.MotionEvent;
导入android.view.view;
导入android.view.view.OnTouchListener;
公共类DrawView扩展了视图实现OnTouchListener{
私人帆布mCanvas;
专用路径mPath;
公共油漆;
私有ArrayList路径=新ArrayList();
位图bmp;
公共绘图视图(上下文){
超级(上下文);
设置聚焦(真);
setFocusableInTouchMode(真);
this.setOnTouchListener(this);
bmp=BitmapFactory.decodeResource(getResources(),R.drawable.v01);
mPaint=新油漆();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.BLUE);
mPaint.setStyle(油漆、样式、笔划);
mPaint.setStrokeJoin(油漆.连接.圆形);
mPaint.setStrokeCap(油漆盖圆形);
mPaint.设定行程宽度(6);
mCanvas=新画布();
mPath=新路径();
路径。添加(mPath);
}
@凌驾
受保护voi