import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;

import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.provider.MediaStore.Images;
import android.util.Log;

public class ImageCompress
{
    public static final String CONTENT = "content";
    public static final String FILE = "file";

/**
     * 图片压缩参数
     * 
     * @author Administrator
     * 
     */
    public static class CompressOptions
    {
        public static final int DEFAULT_WIDTH = 400;
        public static final int DEFAULT_HEIGHT = 800;

public int maxWidth = DEFAULT_WIDTH;
        public int maxHeight = DEFAULT_HEIGHT;
        /**
         * 压缩后图片保存的文件
         */
        public File destFile;
        /**
         * 图片压缩格式,默认为jpg格式
         */
        public CompressFormat imgFormat = CompressFormat.JPEG;

/**
         * 图片压缩比例 默认为30
         */
        public int quality = 30;

public Uri uri;
    }

public Bitmap compressFromUri(Context context, CompressOptions compressOptions)
    {
        // uri指向的文件路径
        String filePath = getFilePath(context, compressOptions.uri);

if (null == filePath)
        {
            return null;
        }
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;

Bitmap temp = BitmapFactory.decodeFile(filePath, options);

int actualWidth = options.outWidth;
        int actualHeight = options.outHeight;

int desiredWidth = getResizedDimension(compressOptions.maxWidth, compressOptions.maxHeight, actualWidth, actualHeight);
        int desiredHeight = getResizedDimension(compressOptions.maxHeight, compressOptions.maxWidth, actualHeight, actualWidth);

options.inJustDecodeBounds = false;
        options.inSampleSize = findBestSampleSize(actualWidth, actualHeight, desiredWidth, desiredHeight);

Bitmap bitmap = null;

Bitmap destBitmap = BitmapFactory.decodeFile(filePath, options);

// If necessary, scale down to the maximal acceptable size.
        if (destBitmap.getWidth() > desiredWidth || destBitmap.getHeight() > desiredHeight)
        {
            bitmap = Bitmap.createScaledBitmap(destBitmap, desiredWidth, desiredHeight, true);
            destBitmap.recycle();
        } 
        else
        {
            bitmap = destBitmap;
        }

// compress file if need
        if (null != compressOptions.destFile)
        {
            compressFile(compressOptions, bitmap);
        }

return bitmap;
    }

/**
     * compress file from bitmap with compressOptions
     * 
     * @param compressOptions
     * @param bitmap
     */
    private void compressFile(CompressOptions compressOptions, Bitmap bitmap)
    {
        OutputStream stream = null;
        try
        {
            stream = new FileOutputStream(compressOptions.destFile);
        } 
        catch (FileNotFoundException e)
        {
            Log.e("ImageCompress", e.getMessage());
        }

bitmap.compress(compressOptions.imgFormat, compressOptions.quality,
                stream);
    }

private static int findBestSampleSize(int actualWidth, int actualHeight, int desiredWidth, int desiredHeight)
    {
        double wr = (double) actualWidth / desiredWidth;
        double hr = (double) actualHeight / desiredHeight;
        double ratio = Math.min(wr, hr);
        float n = 1.0f;
        while ((n * 2) <= ratio)
        {
            n *= 2;
        }

return (int) n;
    }

private static int getResizedDimension(int maxPrimary, int maxSecondary, int actualPrimary, int actualSecondary)
    {
        // If no dominant value at all, just return the actual.
        if (maxPrimary == 0 && maxSecondary == 0)
        {
            return actualPrimary;
        }

// If primary is unspecified, scale primary to match secondary's scaling
        // ratio.
        if (maxPrimary == 0)
        {
            double ratio = (double) maxSecondary / (double) actualSecondary;
            return (int) (actualPrimary * ratio);
        }

if (maxSecondary == 0)
        {
            return maxPrimary;
        }

double ratio = (double) actualSecondary / (double) actualPrimary;
        int resized = maxPrimary;
        if (resized * ratio > maxSecondary)
        {
            resized = (int) (maxSecondary / ratio);
        }
        return resized;
    }

/**
     * 获取文件的路径
     * 
     * @param scheme
     * @return
     */
    private String getFilePath(Context context, Uri uri)
    {
        String filePath = null;

if (CONTENT.equalsIgnoreCase(uri.getScheme()))
        {
            Cursor cursor = context.getContentResolver().query(uri, new String[] { Images.Media.DATA }, null, null, null);

if (null == cursor)
            {
                return null;
            }

try
            {
                if (cursor.moveToNext())
                {
                    filePath = cursor.getString(cursor.getColumnIndex(Images.Media.DATA));
                }
            } 
            finally
            {
                cursor.close();
            }
        }

// 从文件中选择
        if (FILE.equalsIgnoreCase(uri.getScheme()))
        {
            filePath = uri.getPath();
        }

return filePath;
    }
}

ImageCompress.java

调用方式:

Object srcPath; // 源图片,可以是sdcard文件路径,也可以是图片库的Uri
String dstPath; // 压缩后的保存路径
CompressOptions options = new CompressOptions();
options.destFile = new File(dstPath);
options.maxWidth = 1000;
options.maxHeight = 1280;
options.uri = (srcPath instanceof Uri) ? ((Uri)srcPath) : Uri.fromFile(new File(srcPath.toString()));

Bitmap bitMap = new ImageCompress().compressFromUri(context, options);

Android图片压缩的更多相关文章

  1. Android 图片压缩、照片选择、裁剪,上传、一整套图片解决方案

    1.Android一整套图片解决方案 http://mp.weixin.qq.com/s?__biz=MzAxMTI4MTkwNQ==&mid=2650820998&idx=1& ...

  2. android图片压缩方法

    android 图片压缩方法: 第一:质量压缩法: private Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = ...

  3. android图片压缩的3种方法实例

    android 图片压缩方法: 第一:质量压缩法: private Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = ...

  4. Android 图片压缩器

    概述 Android 图片压缩器:一款高效的图片压缩器库,支持批量压缩,异步压缩.多线程多任务压缩,压缩比设置等特性. 详细 代码下载:http://www.demodashi.com/demo/12 ...

  5. Android 图片压缩各种方式

       前言:由于公司项目当中需要用到压缩这块的相应技术,之前也做过的图片压缩都不是特别的理想, 所以这次花了很多心思,仔细研究和在网上找到了很多相对应的资料.为了就是 以后再做的时候直接拿来用就可以了 ...

  6. Android图片压缩上传(二)

    之前有用到libjpeg,还是有一定的局限性,最近用了一个新的方式,效果还是挺不错,随着作者的版本更新,Bug也随之变少,目前项目中运用已上线. 1.之前的方式Android图片压缩,不失真,上线项目 ...

  7. Android图片压缩方法总结

    本文总结Android应用开发中三种常见的图片压缩方法,分别是:质量压缩法.比例压缩法(根据路径获取图片并压缩)和比例压缩法(根据Bitmap图片压缩).   第一:质量压缩方法:   ? 1 2 3 ...

  8. 性能优化——Android图片压缩与优化的几种方式

    图片优化压缩方式大概可以分为以下几类:更换图片格式,质量压缩,采样率压缩,缩放压缩,调用jpeg压缩等1.设置图片格式Android目前常用的图片格式有png,jpeg和webp,png:无损压缩图片 ...

  9. android图片压缩总结

    一.bitmap 图片格式介绍 android中图片是以bitmap形式存在的,那么bitmap所占内存,直接影响到了应用所占内存大小,首先要知道bitmap所占内存大小计算方式: bitmap内存大 ...

随机推荐

  1. 【无聊放个模板系列】HDU 1269 (SCC)

    #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #inc ...

  2. 汇编语言中,SP,BP ,SI,DI作用?

    这个很简单: sp:表示栈顶指针,指向栈顶地址.与SS相配合使用.ss为栈段. bp:是基址指针,段地址默认在SS中.可以定位物理地址,比如:"mov ax,[bp+si+6]/mov ax ...

  3. ANDROID_MARS学习笔记_S02_005_AppWidget1

    一.AppWidget介绍 1.要在手机生成AppWidget需的东西 (1)AppWidgetProviderInfo a).res\xml\example_appwidget_info.xml b ...

  4. Android SeekBar实现音量调节

    SeekBar可以通过滑块的位置来标识数值----而且拖动条允许用户拖动滑块来改变值,因此拖动条通常用于对系统的某种数值进行调节,比如调节音量等. SeekBar允许用户改变拖动条的滑块外观,改变滑块 ...

  5. Markdown简单语法总结

    . 标题 # 一级标题 ## 二级标题 ### 三级标题 #### 四级标题 ##### 五级标题 ###### 六级标题 2. 列表 无序列表 * 西瓜 * 葡萄 * 香蕉 - 西瓜 - 葡萄 - ...

  6. 《linux程序设计》笔记 第一章 入门

    linux程序存放位置linux主要有一下几个存放程序的目录: /bin    系统启动程序目录 /usr/bin 用户使用的标准程序 /usr/local/bin   用于存放软件安装目录 /usr ...

  7. 学习笔记-[Maven实战]-第三章:Maven使用入门(1)

    说明:[Maven实战]一书还介绍了怎么样手工创建Maven工程,学习这本书是为了能尽快在工作中使用,就忽略了手工建工程的部分 如果想了解这部分的内容,可以自己看看书 开始: 1.新建一个maven工 ...

  8. VisualC#数据库高级教程文档分享

    这一节我们演示下怎样使用VS2010创建与发布MVC3建立的网站.使用VS2010创建MVC3.0网站,需要下载MVC3.0的安装包,这个大家可以去网络上下载.     1.项目创建         ...

  9. Memcached‘process_bin_delete’函数安全漏洞

    漏洞名称: Memcached‘process_bin_delete’函数安全漏洞 CNNVD编号: CNNVD-201401-174 发布时间: 2014-01-15 更新时间: 2014-01-1 ...

  10. AFNetworking 2.0 获取json数据时,返回 NSLocalizedDescription=Request failed: unacceptable content-type: text/html, 解决方法.

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; manager.responseSe ...