上一篇文章提及了通过调用系统相册或拍照来实现图片的缩放\裁剪。不过这对于笔者项目的要求同样不适合,笔者需要的是通过对手机屏幕整个进行一个截图,并对这个截图进行裁剪操作。

依靠系统功能确实可以实现图片的裁剪,但是不够灵活。这里笔者提供一种较为灵活的做法。

但是这种做法的用户体验没有上篇文章的好,至于使用何种方法,读者应该自己衡量。

同样,我们先看实际效果图。

这里展示的是笔者项目的一小部分(阅读器):

我们点击左下角的剪切按钮

我们通过红色边框的四个角来控制裁剪的大小,移动红色框体来控制裁剪的位置区域。

接下来我们看看源码的实现:

首先点击剪切按钮的时候,我们应该生成一个Bitmap对象,传递给另一个Activty处理

具体做法如下:

cutP.setOnClickListener(new View.OnClickListener() {

public void onClick(View v) {

//将一些按钮隐藏

cutP.setVisibility(View.INVISIBLE);

mTopBarSwitcher.setVisibility(View.INVISIBLE);

mPageSlider.setVisibility(View.INVISIBLE);

back.setVisibility(View.INVISIBLE);

mPageNumberView.setVisibility(View.INVISIBLE);

View view = MuPDFActivity.this.getWindow().getDecorView();

if (false == view.isDrawingCacheEnabled()) {

view.setDrawingCacheEnabled(true);

}

Bitmap bitmap = view.getDrawingCache();

ImageView imgv = new ImageView(MuPDFActivity.this);

imgv.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,

LayoutParams.FILL_PARENT-200));

imgv.setImageBitmap(bitmap);

backBitmap = bitmap;

//传递给另一个Activity进行裁剪

Intent intent = new Intent();

intent.setClass(MuPDFActivity.this, CutActivity.class);

startActivity(intent);

}

});

Tips:这里笔者是将这个截取的Bitmap对象传递给另一个Actvity做相关处理,这里如何在Activity之间进行Bitmap传递呢?这里我们简单的运用java语法特性来完成具体做法如下:

我们在ActvityA中有一个public static Bitmap bitmap对象,当ActivityA跳转到B时,我们直接通过ActivityA.bitmap来获取这个对象。

之后就是如何进行裁剪的操作了。操作在另一个Activity中进行。XML配置文件信息如下:

android:layout_width="match_parent"

android:layout_height="match_parent"

>

android:id="@+id/myCanvas"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:background="#313131"

/>

android:id="@+id/cutCancel"

android:layout_height="wrap_content"

android:layout_width="wrap_content"

android:text="取消"

android:layout_alignParentBottom="true"

android:layout_alignParentLeft="true"/>

android:id="@+id/cutEnsure"

android:layout_height="wrap_content"

android:layout_width="wrap_content"

android:text="确定"

android:layout_alignParentBottom="true"

android:layout_centerInParent="true"/>

android:id="@+id/toPDF"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="ToPDF"

android:layout_alignParentBottom="true"

android:layout_alignParentRight="true"/>

通过配置文件可以看到我们自定义了一个View(ImageView)其实现如下:

package com.artifex.mupdf;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Matrix;

import android.graphics.Paint;

import android.graphics.Rect;

import android.graphics.RectF;

import android.graphics.Bitmap.Config;

import android.graphics.drawable.BitmapDrawable;

import android.util.AttributeSet;

import android.view.MotionEvent;

import android.widget.ImageView;

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 Bitmap bitMap = null; //原始图片

private RectF src = null; //经过比例转换后的裁剪区域

private RectF dst = null; //图片显示区域,也就是drawBitmap函数中的目标dst

private RectF ChooseArea = null; //选择区域

private Paint mPaint = null; //画笔

private Matrix matrix = null; //矩阵

private int mx = 0; //存储触笔移动时,之前�?��的触笔的x坐标

private int my = 0; //存储触笔移动时,之前�?��的触笔的y坐标

private boolean touchFlag = false; //触笔是否在屏幕之�?

private boolean cutFlag = false; //是否点击了menu上的裁剪按钮

private int recFlag = -1; //用来存储触笔点击了哪个小矩形框(改变选择区域大小的小矩形框)

private boolean firstFlag = false;

private RectF recLT = null; //左上角的小矩形框

private RectF recRT = null; //右上角的小矩形框

private RectF recLB = null; //左下角的小矩形框

private RectF recRB = null; //右下角的小矩形框

private static final int LEFT_AREA_ALPHA = 50 * 255 / 100;

private RectF leftRectL = null;

private RectF leftRectR = null;

private RectF leftRectT = null;

private RectF leftRectB = 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(){

cutFlag = true;

recLT = new RectF();

recLB = new RectF();

recRT = new RectF();

recRB = new RectF();

dst = new RectF();

mPaint = new Paint();

mPaint.setColor(Color.RED);

mPaint.setStyle(Paint.Style.STROKE); //将画笔的风格改为空心

ChooseArea = new RectF();

this.setPressRecLoc();

src = null;

firstFlag = true;

//选择框之外的灰色区域,分成四个矩形框

leftAreaPaint = new Paint();

leftAreaPaint.setStyle(Paint.Style.FILL);

leftAreaPaint.setAlpha(Crop_Canvas.LEFT_AREA_ALPHA);

}

public void setBitmap(Bitmap bitmap){

BitmapDrawable bd = new BitmapDrawable(bitmap);

src = new RectF(0,0,bd.getIntrinsicWidth(),bd.getIntrinsicHeight());

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(){

matrix = this.getImageMatrix();

matrix.mapRect(dst, src);

int padding = this.getPaddingBottom();

int width = bitMap.getWidth();

int height = bitMap.getHeight();

//dst.set(dst.left+padding,dst.top+padding,dst.right+padding,dst.bottom+padding);

dst.set(dst.left+20,dst.top+20,width-20,height - 40);

ChooseArea = new RectF(dst);

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);

src = new RectF(left,top,right,bottom);

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 && cutFlag){

//System.out.println(event.getX() + "," + event.getY());

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){

this.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源码:

package com.artifex.mupdf.cut;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.util.ArrayList;

import android.app.Activity;

import android.graphics.Bitmap;

import android.os.Bundle;

import android.view.View;

import android.view.View.OnClickListener;

import android.view.Window;

import android.widget.Button;

import com.andorid.shu.love.R;

import com.artifex.mupdf.Crop_Canvas;

import com.artifex.mupdf.MuPDFActivity;

public class CutActivity extends Activity {

private Crop_Canvas canvas = null;

private Bitmap backBitmap;

private Button cancel;

private Button ensure;

private Button toPDF;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

requestWindowFeature(Window.FEATURE_NO_TITLE);

setContentView(R.layout.cut_image);

backBitmap = MuPDFActivity.backBitmap;

init();

cancel = (Button) findViewById(R.id.cutCancel);

cancel.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

CutActivity.this.finish();

}

});

ensure = (Button) findViewById(R.id.cutEnsure);

ensure.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

//图片保存的路径,之后将之转换为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();

}

}

});

toPDF = (Button)findViewById(R.id.toPDF);

toPDF.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

// TODO Auto-generated method stub

ArrayList imageUrllist = new ArrayList();

imageUrllist.add("/sdcard/lovereader/pic/" + "testpic" + ".png");

String pdfUrl = "/sdcard/lovereader/tmp/Foreverlove.pdf";

File tmp = new File("/sdcard/lovereader/tmp");

tmp.mkdirs();

File file = PdfManager.Pdf(imageUrllist, pdfUrl);

try {

file.createNewFile();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

}

private void init() {

canvas = (Crop_Canvas) findViewById(R.id.myCanvas);

Bitmap bitmap = backBitmap;

canvas.setBitmap(bitmap);

}

}

ok,不依靠系统的简单裁剪功能就实现了,这里笔者就不给出源代码下载了,上述代码读者只要自己改改就可以用了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

android 调用系统的剪切功能,Android实现图片的裁剪(不调用系统功能)相关推荐

  1. linux 短信功能,Android调用系统短信功能发送短信

    Android调用系统短信功能发送短信有两种方法: 第一种,设定发送的号码,和内容,界面没有联系人,群组组等按钮,如下图所示: 代码如下: Uri smsToUri = Uri.parse(" ...

  2. Android屏蔽系统的蓝牙功能

     Android屏蔽系统的蓝牙功能 修改系统权限 1.要root手机 2.安装re管理器 3.进入手机内存 /system/etc/permissions/android.hardware.blu ...

  3. 14.3.1 调用系统的拍照功能

    14.3.1 调用系统的拍照功能 http://book.51cto.com  2010-06-22 14:19  李宁  中国水利水电出版社  我要评论(0) 摘要:<Android/OPho ...

  4. 安卓短信功能全解:调用系统短信功能发送短信、彩信,使用SmsManager发送短信,并监听发送短信的投递情况,使用广播接收器监听接收的短信。

    全栈工程师开发手册 (作者:栾鹏) 安卓教程全解 安卓短信功能全解:调用系统短信功能发送短信.彩信,使用SmsManager发送短信,并监听发送短信的投递情况,使用广播接收器监听接收的短信. 首先需要 ...

  5. android 调用系统图库剪切图片出现黑屏闪退

    项目中经常会遇到在系统图库中选择图片剪切作为头像的需求,调用系统剪切图片的功能魅族手机会黑屏无法载入图片,小米手机会闪退,这是因为大家采用了下面这种写法 由于魅族和小米手机无法直接拿到图片的地址或者将 ...

  6. android不调用系统发送短信,android之两种方式调用短信发送接口

    释放双眼,带上耳机,听听看~! 相信很多程序员在开发程序的时候都会遇到短信调用端口的情况,今天是技术狗小编为大家带来的关于android之两种方式调用短信发送接口,希望对你学习这方面知识有帮助! an ...

  7. android调用系统音频播放器,Android使用Service实现简单音乐播放实例

    Service翻译成中文是服务,熟悉Windows 系统的同学一定很熟悉了.Android里的Service跟Windows里的Service功能差不多,就是一个不可见的进程在后台执行. Androi ...

  8. android打开系统前置摄像头驱动,android 调用系统前置摄像头

    第一种方式是采用MediaStore,调用系统原生的相机. Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.pu ...

  9. Android删除系统的WIFI功能

    1.要root手机 2.安装re管理器 3.进入手机内存/system/bin/wpa_supplicant(文件无后缀). 4.re管理器改成读写模式后,   修改wpa_supplicant文件, ...

最新文章

  1. UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 0: ordinal not in range(128)
  2. iOS开发网络篇—HTTP协议
  3. 不喜欢SAP GUI?那试试用Eclipse进行ABAP开发吧
  4. TCP/UDP编程中的问题汇总
  5. 编程界的“马太效应”,是什么在阻止你变得更加优秀?
  6. Linux网络编程——I/O复用之select详解
  7. 二分查找算法java
  8. C#转C++的一点分享
  9. 错误Cannot resolve org.springframework.data:spring-data-redis:2.2.6 RELEASE
  10. apollo @value没生效_不问不要紧,一文要人命,绝对的面试加分项配置中心Apollo深度解读...
  11. Java多线程基础知识(一)
  12. shell语法中的test命令用法
  13. 借书卡程序设计java_java图书馆借书编程求解
  14. pytorch之tensor操作expand
  15. Python爬取校花网,好看的妹子真多
  16. Axure实战002:APP原型设计思路
  17. 【算法】生成n个互异随机数的初步算法
  18. 记一次quartz定时任务不执行排雷
  19. Introduce Parameter Object (引入参数对象)
  20. 打印机设置为双面打印_hudingyin_新浪博客

热门文章

  1. Android Recovery:功能简介。Recovery模式介绍
  2. 死亡空间2显卡测试软件,恐怖窒息体验 中低端显卡闯荡《死亡空间2》(4)
  3. HashMap详细解析
  4. 【Unity】Unity 生命周期
  5. 【自撰】Springboot集成Zookeeper和Dubbo
  6. 树莓派、51、arduino和树莓派几种常用芯片及开源硬件的比较
  7. 淘宝的ruby镜像已无人维护,使用ruby-china的RubyGems镜像
  8. 暗黑3,diabli iii 美服购买完全攻略,100%成功
  9. 计算机网络 鉴别释义,计算机网络 鉴别
  10. 首家小程序新电商无人商店深圳面世