在Android中绘制图片 [英] Draw on Picture in android

查看:301
本文介绍了在Android中绘制图片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在一个自定义的imageview可以绘制线条,问题是绘图区域大小不完全与位图大小。



例如,在其他应用程序中,它如下所示:





但是,在我的应用程序中,

>



这是我的程序,这似乎位图不适合画布。感谢您的帮助

  public class DrawingView extends View {

//绘制路径
private路径drawPath;
//绘画和画布油画
private Paint drawPaint,canvasPaint;
//初始颜色
private int paintColor = 0xFF660000;
// canvas
private Canvas drawCanvas;
// canvas bitmap
private Bitmap canvasBitmap;


public DrawingView(Context context,AttributeSet attrs){
super(context,attrs);
setupDrawing();
}

//设置绘图
private void setupDrawing(){

//准备绘制和设置绘图笔画属性
drawPath = new Path();
drawPaint = new Paint();
drawPaint.setColor(paintColor);
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(15.0f);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
canvasPaint = new Paint(Paint.DITHER_FLAG);
}

//分配给查看的大小
@Override
protected void onSizeChanged(int w,int h,int oldw,int oldh){
super.onSizeChanged(w,h,oldw,oldh);
canvasBitmap = Bitmap.createBitmap(w,h,Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}

//绘制视图 - 将在触摸事件后调用
@Override
protected void onDraw(Canvas canvas){
canvas.drawBitmap (BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher),0,0,canvasPaint);
canvas.drawBitmap(canvasBitmap,0,0,canvasPaint);
canvas.drawPath(drawPath,drawPaint);
}

//注册用户触动作为绘图操作
@Override
public boolean onTouchEvent(MotionEvent event){
float touchX = event.getX );
float touchY = event.getY();
//响应down,move和up事件
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
drawPath.moveTo(touchX,touchY);
break;
case MotionEvent.ACTION_MOVE:
drawPath.lineTo(touchX,touchY);
break;
case MotionEvent.ACTION_UP:
drawPath.lineTo(touchX,touchY);
drawCanvas.drawPath(drawPath,drawPaint);
drawPath.reset();
break;
默认值:
return false;
}
// redraw
invalidate();
return true;

}

//更新颜色
public void setColor(String newColor){
invalidate();
paintColor = Color.parseColor(newColor);
drawPaint.setColor(paintColor);
}

//开始新绘图
public void startNew(){
drawCanvas.drawColor(0,PorterDuff.Mode.CLEAR);
invalidate();
}
}

我发现了类似的教程代码,问题是触摸事件有错误,它计数在操作栏和其余的UI元素,所以触摸是奇怪的。建议查看



http://www.java2s.com/Code/Android/2D-Graphics/DrawonPictureandsave.htm



所以,这个目标主题,是



的解决方案1)可绘图像



能够(可以使用库)(当有效缩放,缩放,非活动缩放,绘制时)



可以参考截图1的想法



感谢您的帮助

解决方案

您可以避免计算样本中其他UI项目的坐标创建自己的ImageView。试试此代码 Activity

  public class DrawOnBitmapActivity extends Activity implements OnClickListener 
{

DrawableImageView choosenImageView;
按钮choosePicture;
button savePicture;

位图bmp;
Bitmap alteredBitmap;

@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

choosenImageView =(DrawableImageView)this.findViewById(R.id.ChoosenImageView);
choosePicture =(Button)this.findViewById(R.id.ChoosePictureButton);
savePicture =(Button)this.findViewById(R.id.SavePictureButton);

savePicture.setOnClickListener(this);
choosePicture.setOnClickListener(this);
}

public void onClick(View v)
{
if(v == choosePicture)
{
Intent choosePictureIntent = new Intent (
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(choosePictureIntent,0);
}
else if(v == savePicture)
{
if(alteredBitmap!= null)
{
ContentValues contentValues = new ContentValues ;
contentValues.put(Media.DISPLAY_NAME,Draw On Me);

Uri imageFileUri = getContentResolver()。insert(
Media.EXTERNAL_CONTENT_URI,contentValues);
try {
OutputStream imageFileOS = getContentResolver()
.openOutputStream(imageFileUri);
alteredBitmap
.compress(CompressFormat.JPEG,90,imageFileOS);
Toast t = Toast
.makeText(this,Saved!,Toast.LENGTH_SHORT);
t.show();

} catch(Exception e){
Log.v(EXCEPTION,e.getMessage());
}
}
}
}

protected void onActivityResult(int requestCode,int resultCode,
Intent intent){
super.onActivityResult(requestCode,resultCode,intent);

if(resultCode == RESULT_OK){
Uri imageFileUri = intent.getData();
try {
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
bmp = BitmapFactory
.decodeStream(
getContentResolver()。OpenInputStream(
imageFileUri),null,bmpFactoryOptions);

bmpFactoryOptions.inJustDecodeBounds = false;
bmp = BitmapFactory
.decodeStream(
getContentResolver()。openInputStream(
imageFileUri),null,bmpFactoryOptions);

alteredBitmap = Bitmap.createBitmap(bmp.getWidth(),
bmp.getHeight(),bmp.getConfig());

choosenImageView.setNewImage(alteredBitmap,bmp);
}
catch(Exception e){
Log.v(ERROR,e.toString());
}
}
}
}

必须稍微更改 activity_main 布局:

 <?xml version = 1.0encoding =utf-8? 
< LinearLayout xmlns:android =http://schemas.android.com/apk/res/android
android:orientation =vertical
android:layout_width =fill_parent
android:layout_height =fill_parent
>
< Button
android:layout_width =fill_parent
android:layout_height =wrap_content
android:text =Choose Pictureandroid:id =@ + id / ChoosePictureButton/>
< ru.pristalovpavel.drawonimage.DrawableImageView android:layout_width =wrap_content
android:layout_height =wrap_content
android:id =@ + id / ChoosenImageView>
< /ru.pristalovpavel.drawonimage.DrawableImageView>
< Button
android:layout_width =fill_parent
android:layout_height =wrap_content
android:text =Save Pictureandroid:id =@ + id / SavePictureButton/>
< / LinearLayout>

和您的自定义 ImageView

  public class DrawableImageView extends ImageView implements OnTouchListener 
{
float downx = 0;
float downy = 0;
float upx = 0;
float upy = 0;

画布
油漆;
矩阵;

public DrawableImageView(Context context)
{
super(context);
setOnTouchListener(this);
}

public DrawableImageView(Context context,AttributeSet attrs)
{
super(context,attrs);
setOnTouchListener(this);
}

public DrawableImageView(Context context,AttributeSet attrs,
int defStyleAttr)
{
super(context,attrs,defStyleAttr);
setOnTouchListener(this);
}

public void setNewImage(Bitmap alteredBitmap,Bitmap bmp)
{
canvas = new Canvas(alteredBitmap);
paint = new Paint();
paint.setColor(Color.GREEN);
paint.setStrokeWidth(5);
matrix = new Matrix();
canvas.drawBitmap(bmp,matrix,paint);

setImageBitmap(alteredBitmap);
}

@Override
public boolean onTouch(View v,MotionEvent event)
{
int action = event.getAction();

switch(action)
{
case MotionEvent.ACTION_DOWN:
downx = getPointerCoords(event)[0]; // event.getX
downy = getPointerCoords(event)[1]; // event.getY();
break;
case MotionEvent.ACTION_MOVE:
upx = getPointerCoords(event)[0]; // event.getX()
upy = getPointerCoords(event)[1]; // event.getY();
canvas.drawLine(downx,downy,upx,upy,paint);
invalidate();
downx = upx;
downy = upy;
break;
case MotionEvent.ACTION_UP:
upx = getPointerCoords(event)[0]; // event.getX();
upy = getPointerCoords(event)[1]; // event.getY();
canvas.drawLine(downx,downy,upx,upy,paint);
invalidate();
break;
case MotionEvent.ACTION_CANCEL:
break;
默认值:
break;
}
return true;
}

final float [] getPointerCoords(MotionEvent e)
{
final int index = e.getActionIndex();
final float [] coords = new float [] {e.getX(index),e.getY(index)};
Matrix matrix = new Matrix();
getImageMatrix()。invert(matrix);
matrix.postTranslate(getScrollX(),getScrollY());
matrix.mapPoints(coords);
return coords;
}
}

eclipse中项目的所有源代码:链接



UPDATE:



新的源代码 DrawableImageView



详情请参阅我的博客


I was working on a custom imageview that can draw line on it, the problem is that the drawing area size is not exactly with the bitmap size.

For example, in the other app, it looks like:

However, in my app, it looks like

Here is my program, which seems the bitmap is not fit with the canvas. Thanks for helping

   public class DrawingView extends View {

    //drawing path
    private Path drawPath;
    //drawing and canvas paint
    private Paint drawPaint, canvasPaint;
    //initial color
    private int paintColor = 0xFF660000;
    //canvas
    private Canvas drawCanvas;
    //canvas bitmap
    private Bitmap canvasBitmap;


    public DrawingView(Context context, AttributeSet attrs){
        super(context, attrs);
        setupDrawing();
    }

    //setup drawing
    private void setupDrawing(){

        //prepare for drawing and setup paint stroke properties
        drawPath = new Path();
        drawPaint = new Paint();
        drawPaint.setColor(paintColor);
        drawPaint.setAntiAlias(true);
        drawPaint.setStrokeWidth(15.0f);
        drawPaint.setStyle(Paint.Style.STROKE);
        drawPaint.setStrokeJoin(Paint.Join.ROUND);
        drawPaint.setStrokeCap(Paint.Cap.ROUND);
        canvasPaint = new Paint(Paint.DITHER_FLAG);
    }

    //size assigned to view
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        drawCanvas = new Canvas(canvasBitmap);
    }

    //draw the view - will be called after touch event
    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher), 0, 0, canvasPaint);
        canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
        canvas.drawPath(drawPath, drawPaint);
    }

    //register user touches as drawing action
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float touchX = event.getX();
        float touchY = event.getY();
        //respond to down, move and up events
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            drawPath.moveTo(touchX, touchY);
            break;
        case MotionEvent.ACTION_MOVE:
            drawPath.lineTo(touchX, touchY);
            break;
        case MotionEvent.ACTION_UP:
            drawPath.lineTo(touchX, touchY);
            drawCanvas.drawPath(drawPath, drawPaint);
            drawPath.reset();
            break;
        default:
            return false;
        }
        //redraw
        invalidate();
        return true;

    }

    //update color
    public void setColor(String newColor){
        invalidate();
        paintColor = Color.parseColor(newColor);
        drawPaint.setColor(paintColor);
    }

    //start new drawing
    public void startNew(){
        drawCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
        invalidate();
    }
}

And I found the similar tutorial code, the problem is that the touch event has bug, it count in the action bar and the rest UI element so the touching is weird. Recommend to have a look

http://www.java2s.com/Code/Android/2D-Graphics/DrawonPictureandsave.htm

So, the goal of this topic , is the solution of

1) draw-able image

2) zoom-able and pan-able(can use library) (when active zoom , zoom, when inactive zoom , draw)

can reference the screenshot 1 for the idea

Thanks a lot for helping

解决方案

You can avoid counting coordinates of other UI items in your sample by creation your own ImageView. Try this code for Activity:

public class DrawOnBitmapActivity extends Activity implements OnClickListener
    {

DrawableImageView choosenImageView;
Button choosePicture;
Button savePicture;

Bitmap bmp;
Bitmap alteredBitmap;

@Override
public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    choosenImageView = (DrawableImageView) this.findViewById(R.id.ChoosenImageView);
    choosePicture = (Button) this.findViewById(R.id.ChoosePictureButton);
    savePicture = (Button) this.findViewById(R.id.SavePictureButton);

    savePicture.setOnClickListener(this);
    choosePicture.setOnClickListener(this);
}

public void onClick(View v) 
{
    if (v == choosePicture) 
    {
        Intent choosePictureIntent = new Intent(
                Intent.ACTION_PICK,
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(choosePictureIntent, 0);
    } 
    else if (v == savePicture) 
    {
        if (alteredBitmap != null) 
        {
            ContentValues contentValues = new ContentValues(3);
            contentValues.put(Media.DISPLAY_NAME, "Draw On Me");

            Uri imageFileUri = getContentResolver().insert(
                    Media.EXTERNAL_CONTENT_URI, contentValues);
            try {
                OutputStream imageFileOS = getContentResolver()
                        .openOutputStream(imageFileUri);
                alteredBitmap
                        .compress(CompressFormat.JPEG, 90, imageFileOS);
                Toast t = Toast
                        .makeText(this, "Saved!", Toast.LENGTH_SHORT);
                t.show();

            } catch (Exception e) {
                Log.v("EXCEPTION", e.getMessage());
            }
        }
    }
}

protected void onActivityResult(int requestCode, int resultCode,
        Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);

    if (resultCode == RESULT_OK) {
        Uri imageFileUri = intent.getData();
        try {
            BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
            bmpFactoryOptions.inJustDecodeBounds = true;
            bmp = BitmapFactory
                    .decodeStream(
                            getContentResolver().openInputStream(
                                    imageFileUri), null, bmpFactoryOptions);

            bmpFactoryOptions.inJustDecodeBounds = false;
            bmp = BitmapFactory
                    .decodeStream(
                            getContentResolver().openInputStream(
                                    imageFileUri), null, bmpFactoryOptions);

            alteredBitmap = Bitmap.createBitmap(bmp.getWidth(),
                    bmp.getHeight(), bmp.getConfig());

            choosenImageView.setNewImage(alteredBitmap, bmp);
        } 
        catch (Exception e) {
            Log.v("ERROR", e.toString());
        }
    }
}
}

You have to change activity_main layout slightly:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Choose Picture" android:id="@+id/ChoosePictureButton"/>
    <ru.pristalovpavel.drawonimage.DrawableImageView android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:id="@+id/ChoosenImageView">
    </ru.pristalovpavel.drawonimage.DrawableImageView>
     <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Save Picture" android:id="@+id/SavePictureButton"/>
</LinearLayout>

and your custom ImageView:

public class DrawableImageView extends ImageView implements OnTouchListener 
{
    float downx = 0;
    float downy = 0;
    float upx = 0;
    float upy = 0;

    Canvas canvas;
    Paint paint;
    Matrix matrix;

    public DrawableImageView(Context context) 
    {
        super(context);
        setOnTouchListener(this);
    }

    public DrawableImageView(Context context, AttributeSet attrs) 
    {
        super(context, attrs);
        setOnTouchListener(this);
    }

    public DrawableImageView(Context context, AttributeSet attrs,
            int defStyleAttr) 
    {
        super(context, attrs, defStyleAttr);
        setOnTouchListener(this);
    }

    public void setNewImage(Bitmap alteredBitmap, Bitmap bmp)
    {
        canvas = new Canvas(alteredBitmap );
        paint = new Paint();
        paint.setColor(Color.GREEN);
        paint.setStrokeWidth(5);
        matrix = new Matrix();
        canvas.drawBitmap(bmp, matrix, paint);

        setImageBitmap(alteredBitmap);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) 
    {
        int action = event.getAction();

        switch (action) 
        {
        case MotionEvent.ACTION_DOWN:
            downx = getPointerCoords(event)[0];//event.getX();
            downy = getPointerCoords(event)[1];//event.getY();
            break;
        case MotionEvent.ACTION_MOVE:
            upx = getPointerCoords(event)[0];//event.getX();
            upy = getPointerCoords(event)[1];//event.getY();
            canvas.drawLine(downx, downy, upx, upy, paint);
            invalidate();
            downx = upx;
            downy = upy;
            break;
        case MotionEvent.ACTION_UP:
            upx = getPointerCoords(event)[0];//event.getX();
            upy = getPointerCoords(event)[1];//event.getY();
            canvas.drawLine(downx, downy, upx, upy, paint);
            invalidate();
            break;
        case MotionEvent.ACTION_CANCEL:
            break;
        default:
            break;
        }
        return true;
    }

    final float[] getPointerCoords(MotionEvent e)
    {
        final int index = e.getActionIndex();
        final float[] coords = new float[] { e.getX(index), e.getY(index) };
        Matrix matrix = new Matrix();
        getImageMatrix().invert(matrix);
        matrix.postTranslate(getScrollX(), getScrollY());
        matrix.mapPoints(coords);
        return coords;
    }
}

All source code of the project in eclipse: link

UPDATE:

new source code for DrawableImageView!

More information is in my blog.

这篇关于在Android中绘制图片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆