给出一张图片,用户手动选择需要的图片区域进行裁剪获得:
自定义一个继承自ImageView可手动选择裁剪区域的控件Crop_Canvas:
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.WindowManager;
import android.widget.ImageView;
import com.hp.classes.wt.R;
public class Crop_Canvas extends ImageView {
private final static int PRESS_LB = 0;// 表示左下角矩形框
private final static int PRESS_LT = 1;// 表示左上角矩形框
private final static int PRESS_RB = 2;// 表示右下角矩形框
private final static int PRESS_RT = 3;// 表示右上角矩形框
private static final int LEFT_AREA_ALPHA = 50 * 255 / 100; //选择区域外背景
private int mx = 0; // 触笔点击位置的X坐标
private int my = 0; // 触笔点击位置的Y坐标
private int recFlag = -1; // 用来存储触笔点击了哪个小矩形框(改变选择区域大小的小矩形框)
private int width = 0;
private int height = 0;
private Bitmap bitMap = null; // 原始图片
private boolean touchFlag = false; // 触笔是否在选择框内
private boolean firstFlag = false;
private RectF dst = null; // 图片显示区域,也就是drawBitmap函数中的目标dst
private RectF ChooseArea = null; // 选择区域
private RectF recLT = null; // 左上角的小矩形框
private RectF recRT = null; // 右上角的小矩形框
private RectF recLB = null; // 左下角的小矩形框
private RectF recRB = null; // 右下角的小矩形框
private RectF leftRectL = null; //左边阴影矩形
private RectF leftRectR = null; //右边阴影矩形
private RectF leftRectT = null; //顶部阴影矩形
private RectF leftRectB = null; //底部阴影矩形
private Paint mPaint = null; // 选择框边线画笔
private Paint leftAreaPaint = null;//选择区域外的阴影画笔
public Crop_Canvas(Context context, AttributeSet attrs) {
super(context, attrs);
this.init();
}
public Crop_Canvas(Context context) {
super(context);
this.init();
}
public void init() {
WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
this.width = wm.getDefaultDisplay().getWidth() - this.getResources().getDimensionPixelOffset(R.dimen.classes_dp_40);
this.height = wm.getDefaultDisplay().getHeight();
recLT = new RectF();
recLB = new RectF();
recRT = new RectF();
recRB = new RectF();
dst = new RectF();
firstFlag = true;
// 选择框边线画笔
mPaint = new Paint();
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.STROKE); // 将画笔的风格改为空心
// 选择框之外的灰色区域画笔,分成四个矩形框
leftAreaPaint = new Paint();
leftAreaPaint.setStyle(Paint.Style.FILL);
leftAreaPaint.setAlpha(Crop_Canvas.LEFT_AREA_ALPHA);
}
public void setBitmap(Bitmap bitmap) {
this.bitMap = bitmap.copy(Config.ARGB_8888, true);
this.setImageBitmap(bitMap);
leftRectB = new RectF();
leftRectL = new RectF();
leftRectR = new RectF();
leftRectT = new RectF();
}
public void imageScale() {
dst.set(dst.left, dst.top, this.width, this.height);
int centerX = this.width / 2;
int centerY = this.height /2;
ChooseArea = new RectF();
ChooseArea.set(centerX - 300, centerY - 150, centerX + 300, centerY + 150);
this.set_LeftArea_Alpha();
this.setPressRecLoc();
}
public Bitmap getSubsetBitmap() {
float ratioWidth = bitMap.getWidth() / (float) (dst.right - dst.left);
float ratioHeight = bitMap.getHeight() / (float) (dst.bottom - dst.top);
int left = (int) ((ChooseArea.left - dst.left) * ratioWidth);
int right = (int) (left + (ChooseArea.right - ChooseArea.left) * ratioWidth);
int top = (int) ((ChooseArea.top - dst.top) * ratioHeight);
int bottom = (int) (top + (ChooseArea.bottom - ChooseArea.top) * ratioHeight);
firstFlag = true;
set_LeftArea_Alpha();
return Bitmap.createBitmap(bitMap, left, top, right - left, bottom - top);
}
// 获得ChooseArea对象
public RectF getChooseArea() {
return ChooseArea;
}
public void moveChooseArea(int move_x, int move_y) {
if (ChooseArea.left + move_x >= dst.left && ChooseArea.right + move_x <= dst.right && ChooseArea.top + move_y >= dst.top
&& ChooseArea.bottom + move_y <= dst.bottom) {
ChooseArea.set(ChooseArea.left + move_x, ChooseArea.top + move_y, ChooseArea.right + move_x, ChooseArea.bottom + move_y);
} else {
if (ChooseArea.left + move_x < dst.left) {
ChooseArea.set(dst.left, ChooseArea.top, ChooseArea.right + dst.left - ChooseArea.left, ChooseArea.bottom);
}
if (ChooseArea.right + move_x > dst.right) {
ChooseArea.set(ChooseArea.left + dst.right - ChooseArea.right, ChooseArea.top, dst.right, ChooseArea.bottom);
}
if (ChooseArea.top + move_y < dst.top) {
ChooseArea.set(ChooseArea.left, dst.top, ChooseArea.right, ChooseArea.bottom + dst.top - ChooseArea.top);
}
if (ChooseArea.bottom + move_y > dst.bottom) {
ChooseArea.set(ChooseArea.left, ChooseArea.top + dst.bottom - ChooseArea.bottom, ChooseArea.right, dst.bottom);
}
}
this.setPressRecLoc();
mPaint.setColor(Color.GREEN);
this.invalidate();
}
public boolean onTouchEvent(MotionEvent event) {
mPaint.setColor(Color.RED);
if (event.getAction() == MotionEvent.ACTION_DOWN ) {
mx = (int) event.getX();
my = (int) event.getY();
if (this.judgeLocation(mx, my)) {
touchFlag = true;
mPaint.setColor(Color.GREEN);
this.invalidate();
return true;
} else {
if (this.findPresseddst((int) event.getX(), (int) event.getY())) {
touchFlag = true;
mPaint.setColor(Color.RED);
return true;
}
}
}
if (event.getAction() == MotionEvent.ACTION_MOVE && touchFlag) {
// 判断是否点击了哪个个小矩形框
if (this.isOutOfArea((int) event.getX(), (int) event.getY())) {
return true;
}
// 如果选择区域大小跟图像大小一样时,就不能移动
if (ChooseArea.left == dst.left && ChooseArea.top == dst.top && ChooseArea.right == dst.right && ChooseArea.bottom == dst.bottom) {
} else {
this.moveChooseArea((int) event.getX() - mx, (int) event.getY() - my);
mx = (int) event.getX();
my = (int) event.getY();
}
}
if (event.getAction() == MotionEvent.ACTION_UP) {
recFlag = -1;
this.invalidate();
touchFlag = false;
}
return super.onTouchEvent(event);
}
private boolean isOutOfArea(int x, int y) {
switch (recFlag) {
case Crop_Canvas.PRESS_LB:
this.pressLB(x - mx, y - my);
break;
case Crop_Canvas.PRESS_LT:
this.pressLT(x - mx, y - my);
break;
case Crop_Canvas.PRESS_RB:
this.pressRB(x - mx, y - my);
break;
case Crop_Canvas.PRESS_RT:
this.pressRT(x - mx, y - my);
break;
default:
return false;
}
mx = x;
my = y;
this.invalidate();
return true;
}
public boolean findPresseddst(int x, int y) {
boolean returnFlag = false;
if (this.isInRect(x, y, recLB)) {
recFlag = Crop_Canvas.PRESS_LB;
returnFlag = true;
} else if (this.isInRect(x, y, recLT)) {
recFlag = Crop_Canvas.PRESS_LT;
returnFlag = true;
} else if (this.isInRect(x, y, recRB)) {
recFlag = Crop_Canvas.PRESS_RB;
returnFlag = true;
} else if (this.isInRect(x, y, recRT)) {
recFlag = Crop_Canvas.PRESS_RT;
returnFlag = true;
}
return returnFlag;
}
public boolean isInRect(int x, int y, RectF rect) {
if (x >= rect.left - 20 && x <= rect.right + 20 && y > rect.top - 20 && y < rect.bottom + 20) {
return true;
}
return false;
}
private void pressLB(int x, int y) {
float left = ChooseArea.left + x;
float right = ChooseArea.right;
float top = ChooseArea.top;
float bottom = ChooseArea.bottom + y;
if (left <= right - 30 && left >= dst.left && bottom <= dst.bottom && bottom >= top + 30) {
ChooseArea.set(left, top, right, bottom);
} else {
if (left + x < dst.left) {
left = dst.left;
}
if (bottom + y > dst.bottom) {
bottom = dst.bottom;
}
if (ChooseArea.left + x > ChooseArea.right - 30) {
left = ChooseArea.right - 30;
}
if (ChooseArea.bottom + y < ChooseArea.top + 30) {
bottom = ChooseArea.top + 30;
}
ChooseArea.set(left, top, right, bottom);
}
this.setPressRecLoc();
}
private void pressLT(int x, int y) {
float left = ChooseArea.left + x;
float right = ChooseArea.right;
float top = ChooseArea.top + y;
float bottom = ChooseArea.bottom;
if (left <= right - 30 && left >= dst.left && top <= bottom - 30 && top >= dst.top) {
ChooseArea.set(left, top, right, bottom);
} else {
if (left < dst.left) {
left = dst.left;
}
if (top < dst.top) {
top = dst.top;
}
if (left > right - 30) {
left = right - 30;
}
if (top > bottom - 30) {
top = bottom - 30;
}
ChooseArea.set(left, top, right, bottom);
}
this.setPressRecLoc();
}
private void pressRT(int x, int y) {
float left = ChooseArea.left;
float right = ChooseArea.right + x;
float top = ChooseArea.top + y;
float bottom = ChooseArea.bottom;
if (right <= dst.right && right >= left + 30 && top <= bottom - 30 && top >= dst.top) {
ChooseArea.set(left, top, right, bottom);
} else {
if (right > dst.right) {
right = dst.right;
}
if (top < dst.top) {
top = dst.top;
}
if (right < left + 30) {
right = left + 30;
}
if (top > bottom - 30) {
top = bottom - 30;
}
ChooseArea.set(left, top, right, bottom);
}
this.setPressRecLoc();
}
private void pressRB(int x, int y) {
float left = ChooseArea.left;
float right = ChooseArea.right + x;
float top = ChooseArea.top;
float bottom = ChooseArea.bottom + y;
if (right <= dst.right && right >= left + 30 && bottom <= dst.bottom && bottom >= top + 30) {
ChooseArea.set(left, top, right, bottom);
} else {
if (right > dst.right) {
right = dst.right;
}
if (bottom > dst.bottom) {
bottom = dst.bottom;
}
if (right < left + 30) {
right = left + 30;
}
if (bottom < top + 30) {
bottom = top + 30;
}
ChooseArea.set(left, top, right, bottom);
}
this.setPressRecLoc();
}
// 每次改变选择区域矩形的大小或者移动,各角落上的小矩形也要改变它的Location
private void setPressRecLoc() {
recLT.set(ChooseArea.left - 5, ChooseArea.top - 5, ChooseArea.left + 5, ChooseArea.top + 5);
recLB.set(ChooseArea.left - 5, ChooseArea.bottom - 5, ChooseArea.left + 5, ChooseArea.bottom + 5);
recRT.set(ChooseArea.right - 5, ChooseArea.top - 5, ChooseArea.right + 5, ChooseArea.top + 5);
recRB.set(ChooseArea.right - 5, ChooseArea.bottom - 5, ChooseArea.right + 5, ChooseArea.bottom + 5);
}
public boolean judgeLocation(float x, float y) {
float start_x = this.getChooseArea().left;
float start_y = this.getChooseArea().top;
float last_x = this.getChooseArea().right;
float last_y = this.getChooseArea().bottom;
// System.out.println("chubi:" + x + "," + y);
// System.out.println(start_y + "," + last_y);
if (x > start_x + 10 && x < last_x - 10 && y > start_y + 10 && y < last_y - 10) {
return true;
}
return false;
}
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (firstFlag) {
imageScale();
firstFlag = false;
mPaint.setColor(Color.RED);
System.out.println("Width: " + (dst.right - dst.left));
System.out.println("Height: " + (dst.bottom - dst.top));
System.out.println("Width: " + this.getDrawable().getIntrinsicWidth());
System.out.println("Height: " + this.getDrawable().getIntrinsicHeight());
} else {
set_LeftArea_Alpha();
}
canvas.drawRect(ChooseArea, mPaint);
mPaint.setColor(Color.BLUE);
canvas.drawRect(recLT, mPaint);
canvas.drawRect(recLB, mPaint);
canvas.drawRect(recRT, mPaint);
canvas.drawRect(recRB, mPaint);
canvas.drawRect(leftRectL, leftAreaPaint);
canvas.drawRect(leftRectR, leftAreaPaint);
canvas.drawRect(leftRectT, leftAreaPaint);
canvas.drawRect(leftRectB, leftAreaPaint);
}
public void set_LeftArea_Alpha() {
leftRectL.set(dst.left, dst.top, ChooseArea.left, dst.bottom);
leftRectR.set(ChooseArea.right, dst.top, dst.right, dst.bottom);
leftRectT.set(ChooseArea.left, dst.top, ChooseArea.right, ChooseArea.top);
leftRectB.set(ChooseArea.left, ChooseArea.bottom, ChooseArea.right, dst.bottom);
}
}
activity如下:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import com.hp.classes.config.Constants;
import com.hp.classes.tools.CommonUtils;
import com.hp.classes.tools.ImageCache;
import com.hp.classes.ui.BaseActivity;
import com.hp.classes.ui.newui.view.Crop_Canvas;
import com.hp.classes.wt.R;
import com.hp.open.tools.StringUtils;
public class PictrueEditAcitivty extends BaseActivity implements OnClickListener {
private Button btnBack, btnCompleted, btnRotate90;
private String path;
private Crop_Canvas canvas;
private Bitmap backgroudBitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.classes_activity_picture_editing_new);
path = getIntent().getExtras().getString(Constants.WRONG_TITLE_PATH);
if (!StringUtils.isValid(path)) {
return;
}
initView();
}
private void initView() {
btnBack = (Button) findViewById(R.id.btnBack);
btnBack.setOnClickListener(this);
btnCompleted = (Button) findViewById(R.id.btnCompleted);
btnCompleted.setOnClickListener(this);
btnRotate90 = (Button) findViewById(R.id.btnRotate90);
btnRotate90.setOnClickListener(this);
canvas = (Crop_Canvas) findViewById(R.id.myCanvas);
init();
}
private void init() {
try {//对图片实现大小压缩
int screenWidth = getResources().getDisplayMetrics().widthPixels;
int screenHeight = getResources().getDisplayMetrics().heightPixels;
Constants.CACHEIMAGE_SIZE = screenWidth * screenHeight;
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inSampleSize = 1;
opt.inJustDecodeBounds = true;// 为true时,只返回宽高,不返回bitmap
BitmapFactory.decodeFile(path, opt);
int bitmapSize = opt.outHeight * opt.outWidth;
if (bitmapSize > Constants.CACHEIMAGE_SIZE && Constants.CACHEIMAGE_SIZE != 0) {
opt.inSampleSize = bitmapSize / Constants.CACHEIMAGE_SIZE;
}
opt.inJustDecodeBounds = false;
backgroudBitmap = BitmapFactory.decodeFile(path, opt);
canvas.setBitmap(backgroudBitmap);
} catch (Exception e) {
e.printStackTrace();
e.printStackTrace();
ImageCache.getInstance(this).clearCache();
backgroudBitmap = BitmapFactory.decodeFile(path);
canvas.setBitmap(backgroudBitmap);
}
if (backgroudBitmap == null) {
finish();
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnBack:
// 删除图片
CommonUtils.startTakePhotoActivity(this);
break;
case R.id.btnCompleted:
saveTitlePictrue();
break;
case R.id.btnRotate90:
long temp = System.currentTimeMillis();
backgroudRotate90();
break;
default:
break;
}
}
public void saveTitlePictrue() {
// 图片保存的路径,之后将之转换为PDF,并以附件的形似发送邮件
File tmp = new File("/sdcard/lovereader/pic");
tmp.mkdirs();
File f = new File("/sdcard/lovereader/pic/" + "testpic" + ".png");
try {
f.createNewFile();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
FileOutputStream fOut = null;
try {
fOut = new FileOutputStream(f);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
canvas.getSubsetBitmap().compress(Bitmap.CompressFormat.PNG, 100, fOut);
try {
fOut.flush();
} catch (IOException e) {
e.printStackTrace();
}
try {
fOut.close();
} catch (IOException e) {
e.printStackTrace();
}
finish();
}
private void backgroudRotate90() {
Matrix m = new Matrix();
m.setRotate(90, (float) backgroudBitmap.getWidth() / 2, (float) backgroudBitmap.getHeight() / 2);
float targetX, targetY;
targetX = backgroudBitmap.getHeight();
targetY = 0;
final float[] values = new float[9];
m.getValues(values);
float x1 = values[Matrix.MTRANS_X];
float y1 = values[Matrix.MTRANS_Y];
m.postTranslate(targetX - x1, targetY - y1);
Bitmap bm1 = Bitmap.createBitmap(backgroudBitmap.getHeight(), backgroudBitmap.getWidth(), Bitmap.Config.ARGB_8888);
Paint paint = new Paint();
Canvas cv = new Canvas(bm1);
cv.drawBitmap(backgroudBitmap, m, paint);
backgroudBitmap = bm1;
canvas.setBitmap(backgroudBitmap);
}
}
classes_activity_picture_editing_new.xml布局如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/llRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/mask" >
<LinearLayout
android:id="@+id/llRight"
android:layout_width="@dimen/classes_dp_40"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:background="#2b2b2b"
android:gravity="center_horizontal"
android:orientation="vertical" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="0dip"
android:layout_weight="1"
android:gravity="center" >
<Button
android:id="@+id/btnBack"
style="@style/PETextButton"
android:background="@drawable/classes_pe_button_back" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="0dip"
android:layout_weight="1"
android:gravity="center" >
<Button
android:id="@+id/btnCompleted"
style="@style/PETextButton"
android:background="@drawable/classes_pe_button_completed" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="0dip"
android:layout_weight="1"
android:gravity="center" >
<Button
android:id="@+id/btnRotate90"
style="@style/PETextButton"
android:background="@drawable/classes_pe_button_rotate90" />
</LinearLayout>
</LinearLayout>
<com.hp.classes.ui.newui.view.Crop_Canvas
android:id="@+id/myCanvas"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_toLeftOf="@+id/llRight"
android:scaleType="fitXY"
android:background="@color/black" />
</RelativeLayout>