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);
}
@Override
protected 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();
}
@Override
protected 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 model
Intent 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 modify
int 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;
}
@Override
public 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" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="@dimen/canvasHeaderHeight"
android:background="@drawable/label_bground" >
<Button
android: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" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="18dip"
android:text="涂鸦画版"
android:layout_centerInParent="true"
android:textColor="#FFFFFF" />
<Button
android: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>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:background="@drawable/background"
android:gravity="center" >
<LinearLayout
android:id="@+id/canvas_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center" >
</LinearLayout>
<LinearLayout
android: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" >
<GridView
android: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>
<LinearLayout
android: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" >
<ImageView
android:id="@+id/canvas_recover_btn"
android:layout_width="32dip"
android:layout_height="32dip"
android:layout_weight="1"
android:src="@drawable/canvas_recover_selector" />
<ImageView
android:id="@+id/canvas_color_btn"
android:layout_width="32dip"
android:layout_height="32dip"
android:layout_weight="1"
android:src="@drawable/canvas_color_selector" />
<ImageView
android:id="@+id/canvas_picture_btn"
android:layout_width="32dip"
android:layout_height="32dip"
android:layout_weight="1"
android:src="@drawable/canvas_picture_selector" />
<ImageView
android: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);
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(0xFFFFFFFF);// TODO set background color
canvas.drawBitmap(bgBitmap, 0, 0, mPaint);
canvas.drawPath(mPath, mPaint);
}
@Override
protected 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 offscreen
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
pathList.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);
}
@Override
public 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 color
if (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);
else
return 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;
}
Android涂鸦
最新推荐文章于 2021-06-04 00:21:08 发布