package cn.c; import java.io.OutputStream; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.net.Uri; import android.os.Bundle; import android.view.Display; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnTouchListener; import android.widget.Button; import android.widget.ImageView; import android.widget.Toast; /** * 注意: * 1 event.getX()和event.getRawX()方法的区别 * event.getX()是相对于父控件而言 * event.getRawX()是相对于屏幕左上角而言 * 2 在Activity中处理触摸事件采用的是OnTouchEvent() * 在View中处理触摸事件是实现OnTouchListener{}接口 * 覆写其中的onTouch()方法 * 3 Bug的问题: * 计算options.inSampleSize这里有Bug.有的图片过大在 * 设备图片库中是被旋转处理了的(虽然看上去没有).比如一 * 张大图片在图片库中看上去是竖屏的,但得到后在ImageView * 中显示却是横屏的. * 所以这里方便测试直接: * options.inSampleSize=8; * 写死了 * 4 调用bitmap.compress()方法的时候注意若设置格式为PNG,那么则无效. * 因为PNG将始终保持所有数据.JPEG是"有损的"编解码器 */ public class MainActivity extends Activity implements OnTouchListener{ private ImageView mImageView; private Button mButton; private Button mSaveButton; private Bitmap mRawBitmap; private Bitmap mAlteredBitmap; private Paint mPaint; private Canvas mCanvas; private Uri mPhotoFileUri; private final int PICK=88; float downX=0; float downY=0; float upX=0; float upY=0; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mImageView=(ImageView) findViewById(R.id.imageView); mImageView.setOnTouchListener(this); mButton=(Button) findViewById(R.id.button); mButton.setOnClickListener(new ButtonOnClickListener()); mSaveButton=(Button) findViewById(R.id.saveButton); mSaveButton.setOnClickListener(new ButtonOnClickListener()); mPaint=new Paint(); mPaint.setColor(Color.RED); mPaint.setStrokeWidth(5); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode==PICK) { mPhotoFileUri=data.getData(); Display display=getWindowManager().getDefaultDisplay(); float w=display.getWidth(); float h=display.getHeight(); try { BitmapFactory.Options options=new BitmapFactory.Options(); options.inJustDecodeBounds=true; mRawBitmap=BitmapFactory.decodeStream (getContentResolver().openInputStream(mPhotoFileUri), null, options); int widthRation=(int) Math.ceil(options.outHeight/h); int heightRation=(int) Math.ceil(options.outWidth/w); if (heightRation>1&&widthRation>1) { if (heightRation>widthRation) { options.inSampleSize=heightRation; } else { options.inSampleSize=widthRation; } } //Bug所在: options.inSampleSize=8; options.inJustDecodeBounds=false; mRawBitmap=BitmapFactory.decodeStream (getContentResolver().openInputStream(mPhotoFileUri), null, options); mAlteredBitmap=Bitmap.createBitmap (mRawBitmap.getWidth(), mRawBitmap.getHeight(), mRawBitmap.getConfig()); mCanvas=new Canvas(mAlteredBitmap); Matrix matrix=new Matrix(); mCanvas.drawBitmap(mRawBitmap, matrix, mPaint); mImageView.setImageBitmap(mAlteredBitmap); } catch (Exception e) { } } } private class ButtonOnClickListener implements OnClickListener { public void onClick(View v) { switch (v.getId()) { case R.id.button: Intent intent = new Intent( Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent, PICK); break; case R.id.saveButton: try { if (mPhotoFileUri!=null) { OutputStream fos=getContentResolver().openOutputStream(mPhotoFileUri); mAlteredBitmap.compress(CompressFormat.JPEG, 90, fos); fos.close(); Toast.makeText(MainActivity.this, "OK", Toast.LENGTH_SHORT).show(); } } catch (Exception e) { // TODO: handle exception } break; default: break; } } } public boolean onTouch(View v, MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: downX=event.getX(); downY=event.getY(); break; case MotionEvent.ACTION_MOVE: upX=event.getX(); upY=event.getY(); mCanvas.drawLine(downX, downY, upX, upY, mPaint); mImageView.invalidate(); downX=upX; downY=upY; break; case MotionEvent.ACTION_UP: // upX=event.getX(); // upY=event.getY(); // mCanvas.drawLine(downX, downY, upX, upY, mPaint); // mImageView.invalidate(); break; case MotionEvent.ACTION_CANCEL: break; default: break; } return true; } }