zoukankan      html  css  js  c++  java
  • 用开源项目CropImage实现图片的裁剪(不推荐)

      

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

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

    package com.kale.cropimagetest;
    
    import android.app.Application;
    
    /**
     * @author:Jack Tony
     * @tips  :在application标签下要有这个内部类的名字
     * 如:android:name="com.kale.cropimagetest.DemoApp"
     *  <application
            android:name="com.kale.cropimagetest.DemoApp"
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
     * @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"
     <application
            android:allowBackup="true"
            android:name="com.kale.cropimagetest.App"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
    ……

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

    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数组形式的数据。
         * </br></br>
         * 需要注意的是,如果这个方法用在从本地文件读取数据时,一般不会遇到问题,但如果是用于网络操作,就经常会遇到一些麻烦(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

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
        
        <com.open.crop.CropImageView
            android:id="@+id/cropImg"
            android:layout_weight="1.0"
            android:layout_width="match_parent"
            android:layout_height="0dp"/>
        
        <Button 
             android:id="@+id/save"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:text="save"/>
    </LinearLayout>

    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://download.csdn.net/detail/shark0017/7733207

  • 相关阅读:
    当Android端,访问WEB service 时,同样的增删改,如果我在一个函数中,实现三个业务(同一函数三个业务是相对独立的,没有交集),和用三个函数实现三个业务,哪一个比较好
    study1
    .net软件工程师面试总结(1)
    pandas 读取文件常见错误
    贝叶斯检查器
    python读取文件异常处理
    knn算法 数字文字图片识别
    饼图简单绘制
    Python自动采集数据简单操作
    数据异常值分析和处理
  • 原文地址:https://www.cnblogs.com/tianzhijiexian/p/3900695.html
Copyright © 2011-2022 走看看