博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用开源项目CropImage实现图片的裁剪(不推荐)
阅读量:6914 次
发布时间:2019-06-27

本文共 16018 字,大约阅读时间需要 53 分钟。

  

  之前介绍过一个截图的办法(),这里再分享个开源项目。它也是截图,但是效果不是很好,首先还是对于小图片没有进行考虑,然后裁剪框也没有正对图片的大小做适配。虽然其代码比较简单,但我还是不推荐用这个做复杂的裁剪。然而里面有个“裁剪框不动,图片可缩放”的效果还是很实用的。因此,我还是来介绍一下。

首先还是导入项目,然后在项目中新建一个类,主要是用来继承Application。便于以后保存到sd卡中

package com.kale.cropimagetest;import android.app.Application;/** * @author:Jack Tony * @tips  :在application标签下要有这个内部类的名字 * 如:android:name="com.kale.cropimagetest.DemoApp" *  
* @date :2014-8-9 */public class App extends Application{ private static App instance; @Override public void onCreate() { super.onCreate(); instance = this; } public static App getInstance() { return instance; }}

 

写好后,在manifest中的application中写上这个类 

android:name="com.kale.cropimagetest.App"
……

 

然后在建立一个类,用来保存截图。根据实际需要可以自行修改

package com.kale.cropimagetest;import java.io.BufferedReader;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.RandomAccessFile;import android.graphics.Bitmap;import android.os.Environment;/** *  * 与文件相关的类,主要负责文件的读写 *  * @author 杨龙辉 2012.04.07 *  *//** * @author:Jack Tony * @tips  : 需要有读取sd卡的权限 * @date  :2014-8-9 */public final class FileUtil{    // ------------------------------ 手机系统相关 ------------------------------    public static final String NEWLINE = System.getProperty("line.separator");// 系统的换行符    public static final String APPROOT = "UMMoka";// 程序的根目录    public static final String ASSERT_PATH="file:///android_asset";//apk的assert目录    public static final String RES_PATH="file:///android_res";//apk的assert目录        //----------------------------------存放文件的路径后缀------------------------------------    public static final String CACHE_IMAGE_SUFFIX=File.separator + APPROOT+ File.separator + "images" + File.separator;    public static final String CACHE_VOICE_SUFFIX=File.separator + APPROOT+ File.separator + "voice" + File.separator;    public static final String CACHE_MATERIAL_SUFFIX=File.separator + APPROOT + File.separator + "material" + File.separator;    public static final String LOG_SUFFIX=File.separator + APPROOT + File.separator + "Log" + File.separator;    // ------------------------------------数据的缓存目录-------------------------------------------------------    public static String SDCARD_PAHT ;// SD卡路径    public static String LOCAL_PATH ;// 本地路径,即/data/data/目录下的程序私有目录    public static String CURRENT_PATH = "";// 当前的路径,如果有SD卡的时候当前路径为SD卡,如果没有的话则为程序的私有目录        static    {        init();    }    public static void init()    {        SDCARD_PAHT = Environment.getExternalStorageDirectory().getPath();// SD卡路径        LOCAL_PATH =  App.getInstance().getApplicationContext().getFilesDir().getAbsolutePath();// 本地路径,即/data/data/目录下的程序私有目录                if(android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))        {            CURRENT_PATH = SDCARD_PAHT;        }         else        {            CURRENT_PATH = LOCAL_PATH;        }    }    /**     * 得到与当前存储路径相反的路径(当前为/data/data目录,则返回/sdcard目录;当前为/sdcard,则返回/data/data目录)     * @return     */    public static String getDiffPath()    {        if(CURRENT_PATH.equals(SDCARD_PAHT))        {            return LOCAL_PATH;        }        return SDCARD_PAHT;    }            public static String getDiffPath(String pathIn)    {        return pathIn.replace(CURRENT_PATH, getDiffPath());    }    // ------------------------------------文件的相关方法--------------------------------------------    /**     * 将数据写入一个文件     *      * @param destFilePath     *            要创建的文件的路径     * @param data     *            待写入的文件数据     * @param startPos     *            起始偏移量     * @param length     *            要写入的数据长度     * @return 成功写入文件返回true,失败返回false     */    public static boolean writeFile(String destFilePath, byte[] data, int startPos, int length)    {        try        {            if (!createFile(destFilePath))            {                return false;            }            FileOutputStream fos = new FileOutputStream(destFilePath);            fos.write(data, startPos, length);            fos.flush();            if (null != fos)            {                fos.close();                fos = null;            }            return true;        } catch (FileNotFoundException e)        {            e.printStackTrace();        } catch (IOException e)        {            e.printStackTrace();        }        return false;    }    /**     * 从一个输入流里写文件     *      * @param destFilePath     *            要创建的文件的路径     * @param in     *            要读取的输入流     * @return 写入成功返回true,写入失败返回false     */    public static boolean writeFile(String destFilePath, InputStream in)    {        try        {            if (!createFile(destFilePath))            {                return false;            }            FileOutputStream fos = new FileOutputStream(destFilePath);            int readCount = 0;            int len = 1024;            byte[] buffer = new byte[len];            while ((readCount = in.read(buffer)) != -1)            {                fos.write(buffer, 0, readCount);            }            fos.flush();            if (null != fos)            {                fos.close();                fos = null;            }            if (null != in)            {                in.close();                in = null;            }            return true;        } catch (IOException e)        {            e.printStackTrace();        }        return false;    }        public static boolean appendFile(String filename,byte[]data,int datapos,int datalength)    {        try {                        createFile(filename);                        RandomAccessFile rf= new RandomAccessFile(filename, "rw");            rf.seek(rf.length());            rf.write(data, datapos, datalength);            if(rf!=null)            {                rf.close();            }                    } catch (Exception e) {            e.printStackTrace();        }        return true;    }    /**     * 读取文件,返回以byte数组形式的数据     *      * @param filePath     *            要读取的文件路径名     * @return     */    public static byte[] readFile(String filePath)    {        try        {            if (isFileExist(filePath))            {                FileInputStream fi = new FileInputStream(filePath);                return readInputStream(fi);            }        } catch (FileNotFoundException e)        {            e.printStackTrace();        }        return null;    }    /**     * 从一个数量流里读取数据,返回以byte数组形式的数据。     * 
* 需要注意的是,如果这个方法用在从本地文件读取数据时,一般不会遇到问题,但如果是用于网络操作,就经常会遇到一些麻烦(available()方法的问题)。所以如果是网络流不应该使用这个方法。 * @param in * 要读取的输入流 * @return * @throws IOException */ public static byte[] readInputStream(InputStream in) { try { ByteArrayOutputStream os = new ByteArrayOutputStream(); byte[] b = new byte[in.available()]; int length = 0; while ((length = in.read(b)) != -1) { os.write(b, 0, length); } b = os.toByteArray(); in.close(); in = null; os.close(); os = null; return b; } catch (IOException e) { e.printStackTrace(); } return null; } /** * 读取网络流 * @param in * @return */ public static byte[] readNetWorkInputStream(InputStream in) { ByteArrayOutputStream os=null; try { os = new ByteArrayOutputStream(); int readCount = 0; int len = 1024; byte[] buffer = new byte[len]; while ((readCount = in.read(buffer)) != -1) { os.write(buffer, 0, readCount); } in.close(); in = null; return os.toByteArray(); } catch (IOException e) { e.printStackTrace(); }finally{ if(null!=os) { try { os.close(); } catch (IOException e) { e.printStackTrace(); } os = null; } } return null; } /** * 将一个文件拷贝到另外一个地方 * @param sourceFile 源文件地址 * @param destFile 目的地址 * @param shouldOverlay 是否覆盖 * @return */ public static boolean copyFiles(String sourceFile, String destFile,boolean shouldOverlay) { try { if(shouldOverlay) { deleteFile(destFile); } FileInputStream fi = new FileInputStream(sourceFile); writeFile(destFile, fi); return true; } catch (FileNotFoundException e) { e.printStackTrace(); } return false; } /** * 判断文件是否存在 * * @param filePath * 路径名 * @return */ public static boolean isFileExist(String filePath) { File file = new File(filePath); return file.exists(); } /** * 创建一个文件,创建成功返回true * * @param filePath * @return */ public static boolean createFile(String filePath) { try { File file = new File(filePath); if (!file.exists()) { if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } return file.createNewFile(); } } catch (IOException e) { e.printStackTrace(); } return true; } /** * 删除一个文件 * * @param filePath * 要删除的文件路径名 * @return true if this file was deleted, false otherwise */ public static boolean deleteFile(String filePath) { try { File file = new File(filePath); if (file.exists()) { return file.delete(); } } catch (Exception e) { e.printStackTrace(); } return false; } /** * 删除 directoryPath目录下的所有文件,包括删除删除文件夹 * @param directoryPath */ public static void deleteDirectory(File dir) { if (dir.isDirectory()) { File[] listFiles = dir.listFiles(); for (int i = 0; i < listFiles.length ; i++) { deleteDirectory(listFiles[i]); } } dir.delete(); } /** * 字符串转流 * @param str * @return */ public static InputStream String2InputStream(String str) { ByteArrayInputStream stream = new ByteArrayInputStream(str.getBytes()); return stream; } /** * 流转字符串 * @param is * @return */ public static String inputStream2String(InputStream is) { BufferedReader in = new BufferedReader(new InputStreamReader(is)); StringBuffer buffer = new StringBuffer(); String line = ""; try { while ((line = in.readLine()) != null) { buffer.append(line); } } catch (IOException e) { e.printStackTrace(); } return buffer.toString(); } //批量更改文件后缀 public static void reNameSuffix(File dir,String oldSuffix,String newSuffix) { if (dir.isDirectory()) { File[] listFiles = dir.listFiles(); for (int i = 0; i < listFiles.length ; i++) { reNameSuffix(listFiles[i],oldSuffix,newSuffix); } } else { dir.renameTo(new File(dir.getPath().replace(oldSuffix, newSuffix))); } } public static void writeImage(Bitmap bitmap,String destPath,int quality) { try { FileUtil.deleteFile(destPath); if (FileUtil.createFile(destPath)) { FileOutputStream out = new FileOutputStream(destPath); if (bitmap.compress(Bitmap.CompressFormat.JPEG,quality, out)) { out.flush(); out.close(); out = null; } } } catch (IOException e) { e.printStackTrace(); } } }

 

这样准备工作就做好了。下面就是项目的使用了~

1.建立布局文件

注意:<com.open.crop.CropImageView ……/>,不同的效果要用不同的控件来实现。如:CropImageView ,CropImageView2,CropImageView3,CropImageView4

 

2.处理裁剪事务。

想用别的控件的话,这里用到的类的名字换一下就行,比如

final CropImageView mCropImage=(CropImageView)findViewById(R.id.cropImg);

final CropImageView2 mCropImage=(CropImageView2)findViewById(R.id.cropImg);

final CropImageView3 mCropImage=(CropImageView3)findViewById(R.id.cropImg);

final CropImageView4 mCropImage=(CropImageView4)findViewById(R.id.cropImg);

package com.kale.cropimagetest;import android.app.Activity;import android.content.Intent;import android.graphics.Bitmap;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import com.open.crop.CropImageView;public class CropImageTest01 extends Activity{    @Override    protected void onCreate(Bundle savedInstanceState) {        // TODO 自动生成的方法存根        super.onCreate(savedInstanceState);        setContentView(R.layout.test01);        final CropImageView mCropImage=(CropImageView)findViewById(R.id.cropImg);        //设置要裁剪的图片和默认的裁剪区域        mCropImage.setDrawable(getResources().getDrawable(R.drawable.right),300,300);                findViewById(R.id.save).setOnClickListener(new OnClickListener() {                        /* (非 Javadoc)             * @see android.view.View.OnClickListener#onClick(android.view.View)             * 开启一个新线程来保存图片             */            @Override            public void onClick(View v) {                                new Thread(new Runnable(){                    @Override                    public void run() {                        //得到裁剪好的图片                        Bitmap bitmap = mCropImage.getCropImage();                                                FileUtil.writeImage(bitmap, FileUtil.SDCARD_PAHT+"/crop.png", 100);                                                Intent mIntent=new Intent();                        mIntent.putExtra("cropImagePath", FileUtil.SDCARD_PAHT+"/crop.png");                        setResult(RESULT_OK, mIntent);                        finish();                    }                }).start();            }        });    }}

 

最后在主Activity中接收图片的路径,载入显示截图即可。

package com.kale.cropimagetest;import android.app.Activity;import android.content.Intent;import android.graphics.drawable.BitmapDrawable;import android.os.Bundle;import android.view.View;import android.widget.ImageView;public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }    public void buttonListener(View v) {        Intent intent = new Intent();        Class
cls = null; switch (v.getId()) { case R.id.crop01_button: cls = CropImageTest01.class; break; case R.id.crop02_button: cls = CropImageTest02.class; break; case R.id.crop03_button: cls = CropImageTest03.class; break; case R.id.crop04_button: cls = CropImageTest04.class; break; default: break; } intent.setClass(getApplicationContext(), cls); startActivityForResult(intent, 100); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { ImageView iv = (ImageView) findViewById(R.id.imageView); if (requestCode == 100 && resultCode == RESULT_OK) { String path = data.getStringExtra("cropImagePath"); iv.setImageDrawable(BitmapDrawable.createFromPath(path)); } super.onActivityResult(requestCode, resultCode, data); }}

 

源码下载:

 

转载地址:http://ioncl.baihongyu.com/

你可能感兴趣的文章
mountmust
查看>>
如何判断一个String字符是否在string[]数组里
查看>>
[zz]hdfs-over-ftp安装
查看>>
iOS学习:UILabel和sizeWithFont方法
查看>>
《人生的智慧》第一章 基本的划分
查看>>
ecshop商品颜色尺寸仿淘宝选择功能教程
查看>>
AJAX实用教程——开篇
查看>>
数据库插入数据返回当前主键ID值方法
查看>>
浅谈三层架构
查看>>
Linux下使用openssl生成证书
查看>>
java设计优化-享元模式
查看>>
Android 获取文件大小
查看>>
linux删除或隐藏命令历史记录history
查看>>
java.lang.OutOfMemoryError: Java heap space
查看>>
认证 (authentication) 和授权 (authorization) 的区别
查看>>
Linux查看磁盘空间大小命令
查看>>
计算机软件著作权查询网址
查看>>
一起谈.NET技术,.Net4.0 Parallel编程(四)Task 上
查看>>
自定义Status Bar的基本方法
查看>>
react动画难写?试试react版transformjs
查看>>