1.Activity:package com.example.hello;import java.beans.PropertyChangeEvent;import java.beans.PropertyChangeListener;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.util.ArrayList;import java.util.List;import com.example.hello.adapter.ColorAdapter;import com.example.hello.ui.CanvasView;import com.example.hello.utils.BitmapUtil;import com.example.hello.utils.CanvasGlobelManager;import com.example.hello.utils.ColorType;import android.app.Activity;import android.app.AlertDialog;import android.app.Dialog;import android.content.ContentResolver;import android.content.DialogInterface;import android.content.Intent;import android.graphics.Bitmap;import android.graphics.Color;import android.graphics.drawable.ColorDrawable;import android.net.Uri;import android.os.Bundle;import android.util.DisplayMetrics;import android.view.Display;import android.view.KeyEvent;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup.LayoutParams;import android.view.Window;import android.view.WindowManager;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.Button;import android.widget.GridView;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.Toast;public class CanvasActivity extends Activity implements OnClickListener {private CanvasView canvasView;private Button saveButton;private Button cancelButton;private ImageView recoverButtton;private ImageView colorButtton;private ImageView pictureButtton;private ImageView releaseButtton;private boolean isShowColorCanvas = false;private LinearLayout canvasViewLayout;private View colorLayout;private GridView colorsGridView;private static final int ACTIVITY_GET_IMAGE = 0;private static final int ACTIVITY_FROM_CAMERA = 1;static List<Integer> colors = new ArrayList<Integer>();private ColorAdapter colorsAdapter;static {colors.add(R.drawable.canvas_color_grid_black_selector);colors.add(R.drawable.canvas_color_grid_blue_selector);colors.add(R.drawable.canvas_color_grid_green_selector);colors.add(R.drawable.canvas_color_grid_purple_selector);colors.add(R.drawable.canvas_color_grid_red_selector);colors.add(R.drawable.canvas_color_grid_yellow_selector);colors.add(R.drawable.canvas_color_grid_white_selector);}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.canvas_activity);this.saveButton = (Button) findViewById(R.id.save_btn);this.cancelButton = (Button) findViewById(R.id.save_btn);this.recoverButtton = (ImageView) findViewById(R.id.canvas_recover_btn);this.colorButtton = (ImageView) findViewById(R.id.canvas_color_btn);this.pictureButtton = (ImageView) findViewById(R.id.canvas_picture_btn);this.releaseButtton = (ImageView) findViewById(R.id.canvas_release_btn);this.canvasViewLayout = (LinearLayout) findViewById(R.id.canvas_layout);this.saveButton.setOnClickListener(this);this.cancelButton.setOnClickListener(this);this.recoverButtton.setOnClickListener(this);this.colorButtton.setOnClickListener(this);this.pictureButtton.setOnClickListener(this);this.releaseButtton.setOnClickListener(this);this.releaseButtton.setClickable(false);this.invalidateCanvasView();}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (requestCode == ACTIVITY_GET_IMAGE) {if (data != null) {try {Uri uri = data.getData();ContentResolver resolver = this.getContentResolver();byte[] buffer = BitmapUtil.getBytesFromInputStream(resolver.openInputStream(Uri.parse(uri.toString())));Bitmap upBitmap = BitmapUtil.getPicFromBytes(buffer, null);this.canvasView.updateImage(upBitmap);} catch (Exception e) {Toast.makeText(this, "The image not found, Please try again", 1).show();e.printStackTrace();}}}}public void onClick(View v) {switch (v.getId()) {case R.id.save_btn:Bitmap bitmap = this.canvasView.saveBitmap();// Show the image in dialog if (bitmap != null) {Dialog d = new Dialog(CanvasActivity.this);ImageView imageView = new ImageView(CanvasActivity.this);imageView.setImageBitmap(bitmap);LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);d.addContentView(imageView, layoutParams);d.show();} else {Toast.makeText(CanvasActivity.this, "图片保存失败", 1).show();}// Create a JPEG ant save it to local. try {bitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(new File("mnt/sdcard/arun.jpg")));} catch (FileNotFoundException e) {e.printStackTrace();}break;case R.id.back_btn:CanvasGlobelManager.getInstanse().resetColorsSelectedItem();this.finish();break;case R.id.canvas_recover_btn:this.canvasView.clear();break;case R.id.canvas_color_btn:this.showColorView();break;case R.id.canvas_picture_btn:final CharSequence[] picItems = { "本地图片", "拍照" };AlertDialog dlg = new AlertDialog.Builder(CanvasActivity.this).setTitle("选择图片类型").setItems(picItems, new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int picItem) {if (picItem == 0) {Intent getImage = new Intent(Intent.ACTION_GET_CONTENT);getImage.addCategory(Intent.CATEGORY_OPENABLE);getImage.setType("image/*");startActivityForResult(getImage, ACTIVITY_GET_IMAGE);} else {// TODO No have complete the modelIntent getImageByCamera = new Intent("android.media.action.IMAGE_CAPTURE");startActivityForResult(getImageByCamera, ACTIVITY_FROM_CAMERA);}}}).create();dlg.show();break;case R.id.canvas_release_btn:if (this.canvasView.getPathsSize() > 0)this.canvasView.releaseLastPath();else {this.releaseButtton.setClickable(false);}break;default:break;}}private void showColorView() {this.colorLayout = this.findViewById(R.id.color_grid_view_layout);this.colorsGridView = (GridView) this.findViewById(R.id.color_grid_view);this.colorsGridView.setSelector(new ColorDrawable(Color.TRANSPARENT));// colorsGridView.setStretchMode(GridView.NO_STRETCH);colorsGridView.setNumColumns(colors.size());colorsAdapter = new ColorAdapter(this, R.layout.color_grid_view_row, colors);this.colorsGridView.setAdapter(colorsAdapter);this.controlShowColorCanvas();this.colorsGridView.setOnItemClickListener(new OnItemClickListener() {public void onItemClick(AdapterView<?> arg0, View view, int postion, long arg3) {CanvasGlobelManager.getInstanse().setColorsSelectedItem(postion);switch (postion) {case 0:canvasView.setColor(ColorType.COLOR_BLACK);break;case 1:canvasView.setColor(ColorType.COLOR_BLUE);break;case 2:canvasView.setColor(ColorType.COLOR_GREEN);break;case 3:canvasView.setColor(ColorType.COLOR_PURPLE);break;case 4:canvasView.setColor(ColorType.COLOR_RED);break;case 5:canvasView.setColor(ColorType.COLOR_YELLOW);break;case 6:canvasView.setColor(ColorType.COLOR_WHITE);break;default:break;}controlShowColorCanvas();}});}private void invalidateCanvasView() {Display display = getWindowManager().getDefaultDisplay();int height = display.getHeight();int width = display.getWidth();DisplayMetrics dm = new DisplayMetrics();dm= getResources().getDisplayMetrics();display.getMetrics(dm);int heightPixels = dm.heightPixels;int widthPixels = dm.widthPixels;// TODO the height will be modifyint canvasViewHeight = height - 60 - 40;this.canvasView = new CanvasView(this, canvasViewHeight, width);canvasViewLayout.addView(this.canvasView);this.canvasView.addpropertChange(new PropertyChangeListener() {//监听path列表中是否还有path ,如果没有,则撤销不可点击public void propertyChange(PropertyChangeEvent event) {if ((Integer) event.getNewValue() > 0) {releaseButtton.setClickable(true);}}});}private void controlShowColorCanvas() {if (!isShowColorCanvas && this.colorLayout != null) {this.colorLayout.setVisibility(View.VISIBLE);this.colorButtton.setImageResource(R.drawable.canvas_color_image1);} else {this.colorLayout.setVisibility(View.GONE);this.colorButtton.setImageResource(R.drawable.canvas_color_image);}this.isShowColorCanvas = !isShowColorCanvas;}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_BACK) {CanvasGlobelManager.getInstanse().resetColorsSelectedItem();this.finish();}return super.onKeyDown(keyCode, event);}}2.layout:<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical" ><RelativeLayoutandroid:layout_width="fill_parent"android:layout_height="@dimen/canvasHeaderHeight"android:background="@drawable/label_bground" ><Buttonandroid:id="@+id/back_btn"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentLeft="true"android:layout_marginLeft="2dip"android:background="@drawable/label_save_bg"android:gravity="center"android:text="取消"android:textColor="#FFFFFF" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:gravity="center"android:textSize="18dip"android:text="涂鸦画版"android:layout_centerInParent="true"android:textColor="#FFFFFF" /><Buttonandroid:id="@+id/save_btn"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:layout_marginRight="2dip"android:background="@drawable/label_save_bg"android:gravity="center"android:text="发送"android:textColor="#FFFFFF" /></RelativeLayout><RelativeLayoutandroid:layout_width="fill_parent"android:layout_height="0dip"android:layout_weight="1"android:background="@drawable/background"android:gravity="center" ><LinearLayoutandroid:id="@+id/canvas_layout"android:layout_width="fill_parent"android:layout_height="fill_parent"android:gravity="center" ></LinearLayout><LinearLayoutandroid:id="@+id/color_grid_view_layout"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignBottom="@id/canvas_layout"android:layout_alignParentBottom="true"android:background="@drawable/scroll_background"android:orientation="horizontal"android:visibility="gone" ><GridViewandroid:id="@+id/color_grid_view"android:layout_width="fill_parent"android:layout_height="fill_parent"android:gravity="center"android:layout_gravity="center"android:layout_marginTop="@dimen/canvasColorGridMargin"android:layout_marginBottom="@dimen/canvasColorGridMargin"android:horizontalSpacing="@dimen/canvasColorGridMargin"android:divider="@android:color/transparent" ></GridView></LinearLayout></RelativeLayout><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="@dimen/canvasFootHeight"android:layout_gravity="center_horizontal"android:gravity="center_vertical"android:background="@drawable/canvas_foot_background"android:orientation="horizontal" ><ImageViewandroid:id="@+id/canvas_recover_btn"android:layout_width="32dip"android:layout_height="32dip"android:layout_weight="1"android:src="@drawable/canvas_recover_selector" /><ImageViewandroid:id="@+id/canvas_color_btn"android:layout_width="32dip"android:layout_height="32dip"android:layout_weight="1"android:src="@drawable/canvas_color_selector" /><ImageViewandroid:id="@+id/canvas_picture_btn"android:layout_width="32dip"android:layout_height="32dip"android:layout_weight="1"android:src="@drawable/canvas_picture_selector" /><ImageViewandroid:id="@+id/canvas_release_btn"android:layout_width="32dip"android:layout_height="32dip"android:layout_weight="1"android:src="@drawable/canvas_release_selector" /></LinearLayout></LinearLayout>3. 画板:package com.example.hello.ui;import java.beans.PropertyChangeListener;import java.beans.PropertyChangeSupport;import java.util.ArrayList;import java.util.EventListener;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.Path;import android.util.Log;import android.view.MotionEvent;import android.view.View;import com.example.hello.R;import com.example.hello.utils.ColorType;public class CanvasView extends View implements EventListener {private Bitmap bgBitmap;private Bitmap mBitmap;private Canvas mCanvas;private Path mPath;@SuppressWarnings("unused")private Paint mBitmapPaint;// 预定义两个Paint,背景和Bitmap分开画private Paint mPaint;private boolean isOverRawXY = false;/** It will set the mPaint color after release path*/private int currentColor = ColorType.COLOR_BLACK;ArrayList<CanvasPath> pathList = new ArrayList<CanvasPath>(40);PropertyChangeSupport support = null;/** CanvasView组件大小*/private int viewHeight = 0;private int viewWidth = 0;/** 画图离顶部的距离*/private int top = 0;private int left = 0;public CanvasView(Context c, int height, int width) {super(c);mPaint = new Paint();support = new PropertyChangeSupport(this);bgBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);mCanvas = new Canvas();mCanvas.setBitmap(bgBitmap);mPath = new Path();mBitmapPaint = new Paint(Paint.DITHER_FLAG);mPaint.setAntiAlias(true);mPaint.setDither(true);mPaint.setColor(this.currentColor);mPaint.setStyle(Paint.Style.STROKE);mPaint.setStrokeJoin(Paint.Join.ROUND);mPaint.setStrokeCap(Paint.Cap.ROUND);mPaint.setStrokeWidth(5);this.viewHeight = height;this.viewWidth = width;Log.i("sys", "原始高" + this.viewHeight + "宽" + this.viewWidth);this.drawMBitmapByResource(R.drawable.background);}private void drawMBitmapByResource(int id) {this.mBitmap = BitmapFactory.decodeResource(getResources(), id);drawMBitmap();}private void drawMBitmap() {this.measureXY();this.mCanvas.drawBitmap(this.mBitmap, this.left, this.top, this.mPaint);}/*** 缩小图片,使用期Scale方式*/private void measureXY() {// 初始大小float oldWidth = this.mBitmap.getWidth();float oldHeight = this.mBitmap.getHeight();this.left = (int) ((this.viewWidth - oldWidth) / 2);this.top = (int) ((this.viewHeight - oldHeight) / 2);Matrix matrix = null;if (left < 0 || top < 0) {matrix = new Matrix();Log.i("sys", "原" + oldWidth + "-" + oldHeight);// 创建操作图片用的matrix对象boolean isVertical = left > top;float scaleXY = 0f;if (isVertical) {// 计算宽高缩放率scaleXY = ((float) this.viewHeight) / oldHeight;this.left = (int) ((this.viewWidth - scaleXY * oldWidth) / 2);this.top = 0;} else {scaleXY = ((float) this.viewWidth) / oldWidth;this.left = 0;this.top = (int) ((this.viewHeight - scaleXY * oldHeight) / 2);}// 缩放图片动作matrix.setScale(scaleXY, scaleXY);this.mBitmap = Bitmap.createBitmap(this.mBitmap, 0, 0, (int) (oldWidth), (int) (oldHeight), matrix, true);}}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);}@Overrideprotected void onDraw(Canvas canvas) {canvas.drawColor(0xFFFFFFFF);// TODO set background colorcanvas.drawBitmap(bgBitmap, 0, 0, mPaint);canvas.drawPath(mPath, mPaint);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// widthMeasureSpec = widthMeasureSpec - 2 * spacWidth ;// heightMeasureSpec = heightMeasureSpec - 2 * spacHeight;super.onMeasure(widthMeasureSpec, heightMeasureSpec);}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 offscreenmCanvas.drawPath(mPath, mPaint);// kill this so we don't double drawpathList.add(new CanvasPath(mPath, mPaint.getColor(), this.isOverRawXY));mPath = new Path();// mPath.reset()不可行,int size = this.pathList.size();this.support.fireIndexedPropertyChange("length", 0, size - 1, size);}@Overridepublic boolean onTouchEvent(MotionEvent event) {float x = event.getX();float y = event.getY();if (this.isNullBitmap() || x < this.left || y < this.top || x > this.left + this.mBitmap.getWidth() || y > this.top + this.mBitmap.getHeight())this.isOverRawXY = true;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 super.onTouchEvent(event);}public Bitmap saveBitmap() {Log.i("sys", "开始X:"+left+"Y:"+top);Log.i("sys", "计算后开始X:"+(this.viewWidth-mBitmap.getWidth())/2+"Y:"+(this.viewHeight-mBitmap.getHeight())/2);if ((this.top > 0 || this.left > 0) && !this.isOverRawXY && !this.isNullBitmap()) {return Bitmap.createBitmap(this.bgBitmap, this.left, this.top, this.mBitmap.getWidth(), this.mBitmap.getHeight());// 注意:后来两个参数不是指结束位置,而是指要取的图片长度}return this.bgBitmap;}public void clear() {mCanvas.drawColor(0xFFFFFFFF);invalidate();this.mBitmap = null;this.pathList.clear();}public void setColor(int color) {this.mPaint.setColor(color);this.currentColor = color;}public void updateImage(Bitmap bitmap) {this.isOverRawXY = false;this.clear();this.mBitmap = bitmap;this.drawMBitmap();}public void releaseLastPath() {this.isOverRawXY = false;this.mCanvas.drawColor(0xFFFFFFFF);// set background colorif (this.mBitmap != null)this.mCanvas.drawBitmap(this.mBitmap, this.left, this.top, this.mPaint);int size = this.pathList.size();for (int i = 0; i < size - 1; i++) {CanvasPath canvasPath = this.pathList.get(i);this.mPaint.setColor(canvasPath.colorId);this.mCanvas.drawPath(canvasPath.path, this.mPaint);if (canvasPath.isTrue) {this.isOverRawXY = true;}}this.mPaint.setColor(this.currentColor);this.pathList.remove(size - 1);invalidate();}public boolean isNullBitmap() {if (this.mBitmap != null) {return false;}return true;}public int getPathListSize() {return this.pathList.size();}public void addpropertChange(PropertyChangeListener pl) {support.addPropertyChangeListener(pl);}public void removePropertChangListener(PropertyChangeListener PL) {support.removePropertyChangeListener(PL);}private class CanvasPath {private Path path;private int colorId;private boolean isTrue;public CanvasPath(Path path, int colorId, boolean isTrue) {this.path = path;this.colorId = colorId;this.isTrue = isTrue;}}}3. 全局数据保存,用于当前使用画笔颜色:package com.example.hello.utils;public class CanvasGlobelManager {private static CanvasGlobelManager instance = null;private int colorsSelectedItem = 0;static {instance = new CanvasGlobelManager();}private CanvasGlobelManager() {}public static CanvasGlobelManager getInstanse() {return instance;}public synchronized int getColorsSelectedItem() {return this.colorsSelectedItem;}public synchronized void setColorsSelectedItem(int colorsSelected) {this.colorsSelectedItem = colorsSelected;}public synchronized void resetColorsSelectedItem() {this.colorsSelectedItem = 0;}}4.工具类:package com.example.hello.utils;import java.io.IOException;import java.io.InputStream;import java.nio.ByteBuffer;import android.graphics.Bitmap;import android.graphics.BitmapFactory;public class BitmapUtil {public static byte[] getBytesFromInputStream(InputStream is) throws IOException {int total = 0;byte[] bytes = new byte[2048];ByteBuffer byteBuffer = ByteBuffer.allocate(3500000);while (true) {int read = is.read(bytes);if (read == -1)break;byteBuffer.put(bytes, 0, read);total += read;}byte[] content = new byte[total];byteBuffer.flip();byteBuffer.get(content, 0, total);return content;}public static Bitmap getPicFromBytes(byte[] bytes, BitmapFactory.Options opts) {if (bytes != null)if (opts != null)return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, opts);elsereturn BitmapFactory.decodeByteArray(bytes, 0, bytes.length);return null;}}import android.graphics.Color;public class ColorType {// COLOR_BLACK,COLOR_BLUE,COLOR_GREEN,COLOR_PURPLE,COLOR_RED,COLOR_YELLOW, COLOR_WHITE;public static final int COLOR_BLACK = Color.BLACK;public static final int COLOR_BLUE = Color.BLUE;public static final int COLOR_GREEN = Color.GREEN;public static final int COLOR_PURPLE = Color.rgb(0x99, 0x32, 0xCD);public static final int COLOR_RED = Color.RED;public static final int COLOR_YELLOW = Color.YELLOW;public static final int COLOR_WHITE = Color.WHITE;}


更多相关文章

  1. android左右滑动翻页查看图片
  2. Android内存缓存图片的标准方法
  3. android Drawable 缩放
  4. Android根据不同语言切换图片
  5. Android 图片处理工具类汇总
  6. android里图片下载工具类AsyncImageLoader分析
  7. android 自由缩放图片
  8. android中实现图片的上下移动
  9. android图片压缩并转为base64字符串

随机推荐

  1. Android/OPhone开发完全讲义(china-pub首
  2. 豪赌Web apps,谷歌Chrome开发工具直通Andr
  3. android 依赖冲突解决
  4. Android通讯录数据库介绍与基本操作(增删
  5. RxJava2+Retrofit2+okHttp的二次封装
  6. Android中的网络时间同步
  7. Android 简单热修复(上)——Java类加载器
  8. Android AutoLayout全新的适配方式 堪称
  9. 使用GDB调试Android NDK native(C/C++)程
  10. Android 的广播机制