android中怎么画图工具,Android画图工具的制作

Android 项目中使用到画图工具,本文记载如何实现,需详细了解cavas和surfaceviw

1 三星pad

三星pad自带的手写笔可以很好的支持画图,集成三星的sdk

0818b9ca8b590ca3270a3433284dd417.png

以上三星官方提供的库文件,主要代码如下

private SpenNoteDoc mSpenNoteDoc;

private SpenPageDoc mSpenPageDoc;

private SpenSurfaceView mSpenSurfaceView;

final FrameLayout spenViewLayout = (FrameLayout) mainView.findViewById(R.id.spenViewLayout);

mSpenSurfaceView = new SpenSurfaceView(getActivity());

if (mSpenSurfaceView == null) {

Toast.makeText(getActivity(), "Cannot create new SpenView.", Toast.LENGTH_SHORT).show();

}

spenViewLayout.addView(mSpenSurfaceView,0);

ViewTreeObserver vto = spenViewLayout.getViewTreeObserver();

vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

@Override

public void onGlobalLayout() {

spenViewLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);

try {

mSpenNoteDoc = new SpenNoteDoc(getActivity(), spenViewLayout.getWidth(), spenViewLayout.getHeight());

} catch (IOException e) {

e.printStackTrace();

}

mSpenPageDoc = mSpenNoteDoc.appendPage();

mSpenPageDoc.setBackgroundColor(0xFFf0f0f0);

mSpenPageDoc.clearHistory();

mSpenSurfaceView.setPageDoc(mSpenPageDoc, true);

mSpenSurfaceView.setBlankColor(getResources().getColor(android.R.color.white));

mSpenSurfaceView.setToolTypeAction(mFINGERToolType, SpenSurfaceView.ACTION_STROKE);

mSpenSurfaceView.setToolTypeAction(mSPENToolType, SpenSurfaceView.ACTION_STROKE);

SpenSettingPenInfo penInfo = new SpenSettingPenInfo();

penInfo.color = Color.RED;

penInfo.size = (int) MyApplication.getAppContext().getResources().getDimension(R.dimen.mBrushSize_red);

mSpenSurfaceView.setPenSettingInfo(penInfo);

}

});

清空区域

mSpenPageDoc = mSpenNoteDoc.appendPage();

mSpenPageDoc.setBackgroundColor(0xFFf0f0f0);

mSpenSurfaceView.setPageDoc(mSpenPageDoc, true);

SpenObjectTextBox.setInitialCursorPos(SpenObjectTextBox.CURSOR_POS_END);

加载图片

mSpenPageDoc.setBackgroundImage(filepath);

mSpenSurfaceView.update();

mSpenNoteDoc.removePage(0);

三星书写流畅,体验很好。

2 自定义画笔

自定义画笔采用封装SurfaceView

http://www.cnblogs.com/xuling/archive/2011/06/06/android.html

这个例子很好的的解释了 surfaceview

public class PainterCanvas extends SurfaceView implements Callback{

public PainterCanvas(Context context, AttributeSet attrs) {

super(context, attrs);

this.mcontext = context;

SurfaceHolder holder = getHolder();

holder.addCallback(this);

setFocusable(true);

Log.e("xx", "PainterCanvas");

}

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

if (mBitmap == null) {

Log.e("xx", "surfaceChanged1");

mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

bgBitmap = Bitmap.createBitmap(mBitmap);//背景图

bgBitmap.eraseColor(Color.WHITE);

mCanvas = new Canvas(bgBitmap);

getThread().setBitmap(mBitmap, true);

getThread().drawBitmap(bgBitmap,true);

} else {

Log.e("xx", "surfaceChanged2");

getThread().setBitmap(mBitmap, false);

getThread().drawBitmap(bgBitmap,false);

}

public PainterThread getThread() {

if (mThread == null) {

mThread = new PainterThread(getHolder());

}

return mThread;

}    }

public void surfaceCreated(SurfaceHolder holder) {

getThread().on();

getThread().start();

}

public void PaintClean() {

getThread().setBitmap(mBitmap, true);

getThread().drawBitmap(bgBitmap,true);

}

public void surfaceDestroyed(SurfaceHolder holder) {

boolean retry = true;

getThread().off();

while (retry) {

try {

getThread().join();

retry = false;

} catch (InterruptedException e) {

}

}

mThread = null;

}

public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

//Log.e("xx", "开始。。。。");

//sb = new StringBuffer();

getThread().drawBegin();

break;

case MotionEvent.ACTION_MOVE:

//Log.e("xx", "进行中。。。。");

getThread().draw((int) event.getX(), (int) event.getY());

break;

case MotionEvent.ACTION_UP:

case MotionEvent.ACTION_CANCEL:

//Log.e("xx", "结束。。。。");

getThread().drawEnd();

break;

}

return true;

}

public void drawBitmap(Bitmap bitmap) {

Matrix matrix = center(bitmap, true, true);

//Matrix matrix  =new Matrix();

mCanvas.drawBitmap(bitmap, matrix, null);

if (bitmap != null && !bitmap.isRecycled()) {

bitmap.isRecycled();

bitmap = null;

}

//getThread().drawBitmap(bgBitmap,false);

}

}

PainterThread中主要封装了一个mCanvas,在onTouchEvent中调用该cavas实现画笔,

public PainterThread(SurfaceHolder surfaceHolder) {

mHolder = surfaceHolder;

mBrushSize = 5;

mBrush = new Paint();

mBrush.setAntiAlias(true);

mBrush.setColor(Color.RED);

mBrush.setStrokeWidth(mBrushSize);

mBrush.setStrokeCap(Cap.ROUND);

// 重置坐标点

mLastBrushPointX = -1;

mLastBrushPointY = -1;

}

将surfaceHolder作为参数传给PainterCanvas

canvas = mHolder.lockCanvas();

synchronized (mHolder) {

if (canvas != null) {

//if (bgBitmap != null) {

canvas.drawBitmap(bgBitmap, 0, 0, null);

//}

canvas.drawBitmap(mBitmap, 0, 0, null);

}

}

} catch (Exception e) {

e.printStackTrace();

Log.e("paiters", "e.printStackTrace()");

} finally {

if (canvas != null) {

mHolder.unlockCanvasAndPost(canvas);

}

}

canvas绘制完成,PainterCanvas刷新显示。用于在图片上做批注。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在信号处理领域,DOA(Direction of Arrival)估计是一项关键技术,主要用于确定多个信号源到达接收阵列的方向。本文将详细探讨三种ESPRIT(Estimation of Signal Parameters via Rotational Invariance Techniques)算法在DOA估计的实现,以及它们在MATLAB环境的具体应用。 ESPRIT算法是由Paul Kailath等人于1986年提出的,其核心思想是利用阵列数据的旋转不变性来估计信号源的角度。这种算法相比传统的 MUSIC(Multiple Signal Classification)算法具有较低的计算复杂度,且无需进行特征值分解,因此在实际应用颇具优势。 1. 普通ESPRIT算法 普通ESPRIT算法分为两个主要步骤:构造等效旋转不变系统和估计角度。通过空间平移(如延时)构建两个子阵列,使得它们之间的关系具有旋转不变性。然后,通过对子阵列数据进行最小二乘拟合,可以得到信号源的角频率估计,进一步转换为DOA估计。 2. 常规ESPRIT算法实现 在描述提到的`common_esprit_method1.m`和`common_esprit_method2.m`是两种不同的普通ESPRIT算法实现。它们可能在实现细节上略有差异,比如选择子阵列的方式、参数估计的策略等。MATLAB代码通常会包含预处理步骤(如数据归一化)、子阵列构造、旋转不变性矩阵的建立、最小二乘估计等部分。通过运行这两个文件,可以比较它们在估计精度和计算效率上的异同。 3. TLS_ESPRIT算法 TLS(Total Least Squares)ESPRIT是对普通ESPRIT的优化,它考虑了数据噪声的影响,提高了估计的稳健性。在TLS_ESPRIT算法,不假设数据噪声是高斯白噪声,而是采用总最小二乘准则来拟合数据。这使得算法在噪声环境下表现更优。`TLS_esprit.m`文件应该包含了TLS_ESPRIT算法的完整实现,包括TLS估计的步骤和旋转不变性矩阵的改进处理。 在实际应用,选择合适的ESPRIT变体取决于系统条件,例如噪声水平、信号质量以及计算资源。通过MATLAB实现,研究者和工程师可以方便地比较不同算法的效果,并根据需要进行调整和优化。同时,这些代码也为教学和学习DOA估计提供了一个直观的平台,有助于深入理解ESPRIT算法的工作原理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值