4.2.2 在现有图像上绘制

    由于是在Canvas对象上绘制,因此可以使用第三章中描述的技术,在Canvas对象上绘制 一幅图像,然后在该图像上进行绘制。

    下列介绍一个完整的示例。

 1 package com.nthm.androidtest;
 2 
 3 import android.app.Activity;
 4 import android.content.Intent;
 5 import android.graphics.Bitmap;
 6 import android.graphics.BitmapFactory;
 7 import android.graphics.Canvas;
 8 import android.graphics.Color;
 9 import android.graphics.Matrix;
10 import android.graphics.Paint;
11 import android.net.Uri;
12 import android.os.Bundle;
13 import android.view.Display;
14 import android.view.MotionEvent;
15 import android.view.View;
16 import android.view.View.OnClickListener;
17 import android.view.View.OnTouchListener;
18 import android.widget.Button;
19 import android.widget.ImageView;

    活动将实现OnClickListener和OnTouchListener。OnClickListener使得活动可以响应按钮的单击事件;而OnTouchListener使得我们可以使用触摸屏在ImageView上绘制。

1 public class ChoosePictureDraw extends Activity implements OnTouchListener,
2         OnClickListener {

    有两个主要的UI元素。第一个是ImageView,他会显示将要在其上进行绘制的位图对象。第二个是一个按钮,用户可以按下它以从Gallery应用程序中选择图像。

1      private ImageView chooseImageView;
2      private Button choosePicture;

    需要有两个位图对象。第一个包含了选定图像的缩放版本,第二个是可变的版本。首先将第一个位图对象绘制到第二个位图对象中,然后在其上方绘制。

 1      private Bitmap bmp;
 2      private Bitmap alteredBitmap;
 3      private Canvas canvas;
 4      private Paint paint;
 5      private Matrix matrix;
 6     @Override
 7     protected void onCreate(Bundle savedInstanceState) {
 8         super.onCreate(savedInstanceState);
 9         setContentView(R.layout.choosepicturedraw);
10         chooseImageView=(ImageView) findViewById(R.id.ChooseImageView);
11         choosePicture=(Button) findViewById(R.id.ChoosePictureButton);

     在获得ImageView和按钮的引用之后,将每个事件(OnClick和OnTouch)的监听器设置为活动。

1         choosePicture.setOnClickListener(this);
2         chooseImageView.setOnTouchListener(this);
3     }

    onClick方法如下所示。它使用标准的意图,允许用户从Gallery应用程序中选择一幅图像。

1     @Override
2     public void onClick(View v) {
3           Intent choosePictureIntent=new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
4           startActivityForResult(choosePictureIntent, 0);
5     }

   在用户选择图像之后调用onActivityResult方法。它将选择的图像加载到一个位图对象中,并将其缩放至屏幕大小。

 1     @Override
 2     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 3         super.onActivityResult(requestCode, resultCode, data);
 4         if(resultCode==RESULT_OK){
 5             Uri imageFileUri=data.getData();
 6             Display currentDisplay=getWindowManager().getDefaultDisplay();
 7             int dw=currentDisplay.getWidth();
 8             int dh=currentDisplay.getHeight();
 9             try{
10                 BitmapFactory.Options bmpBitmapFactoryOptions=new BitmapFactory.Options();
11                 bmpBitmapFactoryOptions.inJustDecodeBounds=true;
12                 bmp=BitmapFactory.decodeStream(getContentResolver().openInputStream(imageFileUri), null, bmpBitmapFactoryOptions);
13                 int heightRatio=bmpBitmapFactoryOptions.outHeight;
14                 int widthRatio=bmpBitmapFactoryOptions.outWidth;
15                 if(heightRatio>1&&widthRatio>1){
16                     if(heightRatio>widthRatio){
17                         bmpBitmapFactoryOptions.inSampleSize=heightRatio;
18                     }else{
19                         bmpBitmapFactoryOptions.inSampleSize=widthRatio;
20                     }
21                 }
22                 bmpBitmapFactoryOptions.inJustDecodeBounds=false;
23                 bmp=BitmapFactory.decodeStream(getContentResolver().openInputStream(imageFileUri), null, bmpBitmapFactoryOptions);

    在加载位图对象之后,创建一个可变的位图对象alteredBitmap,并在其中绘制第一个位图对象。

 1                 alteredBitmap=Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());
 2                 canvas=new Canvas(alteredBitmap);
 3                 paint=new Paint();
 4                 paint.setColor(Color.GREEN);
 5                 paint.setStrokeWidth(5);
 6                 matrix=new Matrix();
 7                 canvas.drawBitmap(bmp, matrix, paint);
 8                 chooseImageView.setImageBitmap(alteredBitmap);
 9                 chooseImageView.setOnTouchListener(this);
10             }catch(Exception e){
11                 
12             }
13         }
14     }

    现在只是采用之前的相同方式实现onTouch方法。不同于在空白的位图Canvas对象上绘制,现在是在一幅现有的图像上面进行绘制。

 1     private float downx=0;
 2     private float downy=0;
 3     private float upx=0;
 4     private float upy=0;
 5     @Override
 6     public boolean onTouch(View v, MotionEvent event) {
 7         switch (event.getAction()) {
 8         case MotionEvent.ACTION_DOWN:
 9             downx=event.getX();
10             downy=event.getY();
11             break;
12         case MotionEvent.ACTION_MOVE:
13             upx=event.getX();
14             upy=event.getY();
15             canvas.drawLine(downx, downy, upx, upy, paint);
16             chooseImageView.invalidate();
17             downx=upx;
18             downy=upy;
19             break;
20         case MotionEvent.ACTION_UP:
21             upx=event.getX();
22             upy=event.getY();
23             canvas.drawLine(downx, downy, upx, upy, paint);
24             chooseImageView.invalidate();
25             break;
26         case MotionEvent.ACTION_CANCEL:
27             
28             break;
29         default:
30             break;
31         }
32         return true;
33     }
34 
35 }

    下面是用于上述活动的布局XML文件。它在一个标准的LinearLayout中指定这个ImageView和按钮。

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     android:layout_width="match_parent"
 3     android:layout_height="match_parent"
 4     android:orientation="vertical"
 5     >
 6     <Button 
 7         android:id="@+id/ChoosePictureButton"
 8         android:layout_width="fill_parent"
 9         android:layout_height="wrap_content"
10         android:text="Choose Picture"/>
11     <ImageView  
12         android:id="@+id/ChooseImageView"
13         android:layout_width="wrap_content"
14         android:layout_height="wrap_content"
15         android:contentDescription="@string/app_name"/>
16 </LinearLayout>

 

posted on 2014-08-26 16:17  宁静致远,一览众山小  阅读(367)  评论(0编辑  收藏  举报

导航