Android 实现压缩图片到任意尺寸

之前写过一篇博客,讲的是如何利用Picasso 来实现压缩图片到任意尺寸:

https://blog.csdn.net/wei1583812/article/details/55271209

后来我用安卓的原生方法实现了压缩图片到任意尺寸,比picasso 要快很多,且不用导入picasso 。不过picasso 也是用的我说的这种方法,只不过是因为它在处理中中转了几层,导致慢了一些。话不多说,贴代码,可以直接拿去用:

public class BitmapUtils {

    /**
     * 返回图片宽高数组,第0个是宽,第1个是高
     */
    public static int[] getBitmapWidthHeight(final String path) {
        BitmapFactory.Options options = new BitmapFactory.Options();

        /**
         * 最关键在此,把options.inJustDecodeBounds = true;
         * 这里再decodeFile(),返回的bitmap为空,但此时调用options.outHeight时,已经包含了图片的高了
         */
        options.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeFile(path, options); // 此时返回的bitmap为null
        int[] size = new int[2];
        size[0] = options.outWidth;
        size[1] = options.outHeight;
        return size;
    }

    public static String getPathByUri(Context context, Uri uri) {
        Activity activity = null;
        if (context instanceof Activity) {
            activity = (Activity) context;
        }

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

        String path = null;
        if (uri == null) {
            return path;
        }
        if ("content".equals(uri.getScheme())) {
            String[] projection = {MediaStore.Images.Media.DATA};
            Cursor cursor = activity.managedQuery(uri, projection, null, null, null);
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            path = cursor.getString(column_index);
        } else if ("file".equals(uri.getScheme())) {
            path = uri.getPath();
        }
        return path;
    }

    /**
     * 此方法仅仅用于计算createScaledBitmap() 方法获取Bitmap 时的缩放比例。
     * 目的是为了防止OOM
     */
    private static int getOptionSize(final float size) {
        int optionSize = 1;
        if (size >= 2f && size < 4f) {
            optionSize = 2;
        } else if (size >= 4f && size < 8f) {
            optionSize = 4;
        } else if (size >= 8f && size < 16) {
            optionSize = 8;
        } else if (size >= 16f) {
            optionSize = 16;
        }
        return optionSize;
    }

    /**
     * 保存图片到sdcard
     */
    public static void saveBitmap(final Bitmap bmp, final MyCallback callback) {
        if (callback != null) {
            callback.onPrepare();
        }

        new Thread(new Runnable() {
            @Override
            public void run() {
                String fileName = System.currentTimeMillis() + ".jpg";
                File file = new File(BaseSDCardUtils.SDCARD_PATH, fileName);
                try {
                    FileOutputStream fos = new FileOutputStream(file);
                    bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);
                    fos.flush();
                    fos.close();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();

                    if (callback != null) {
                        callback.onError();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    if (callback != null) {
                        callback.onError();
                    }
                }
                String path = file.getAbsolutePath();

                if (callback != null) {
                    callback.onSucceed(path);
                }

            }
        }).start();

    }

    /**
     * 按原图比例缩放裁剪图片
     *
     * @param activity   BaseLibActivity
     * @param imagePath  图片的路径
     * @param imageWidth 想要被缩放到的target图片宽度,我会根据此宽度和原图的比例,去计算target图片高度
     * @param callback   回调监听
     */
    public static void createScaledBitmap(final BaseLibActivity activity, final String imagePath, final int imageWidth, final MyCallback callback) {
        if (callback == null) {
            throw new NullPointerException("MyCallback must not null");
        }
        callback.onPrepare();

        if (TextUtils.isEmpty(imagePath) || !(new File(imagePath).exists())) {
            callback.onError();
            return;
        }

        //原图宽度大于传入的宽度才压缩,否则不压缩,直接返回原图路径
        final int[] size = getBitmapWidthHeight(imagePath);
        if (size[0] <= imageWidth) {
            callback.onSucceed(imagePath);
            return;
        }

        new Thread() {
            @Override
            public void run() {
                super.run();

                int imageHeight = (int) (size[1] * 1f * imageWidth * 1f / size[0] * 1f);
                float scale = size[0] * 1f / imageWidth * 1f;

                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = getOptionSize(scale);
                Bitmap targetBitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeFile(imagePath, options), imageWidth, imageHeight, true);

                saveBitmap(targetBitmap, new MyCallback() {
                    @Override
                    public void onPrepare() {

                    }

                    @Override
                    public void onSucceed(final Object path) {
                        if (activity != null && !activity.isFinishing()) {
                            activity.runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    callback.onSucceed(path);
                                }
                            });
                        }
                    }

                    @Override
                    public void onError() {
                        if (activity != null && !activity.isFinishing()) {
                            activity.runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    callback.onError();
                                }
                            });
                        }
                    }
                });
            }
        }.start();
    }


    /**
     * 按原图比例缩放裁剪图片
     *
     * @param activity   BaseLibActivity
     * @param imageUri   图片的Uri
     * @param imageWidth 想要被缩放到的target图片宽度,我会根据此宽度和原图的比例,去计算target图片高度
     * @param callback   回调监听
     */
    public static void createScaledBitmap(final BaseLibActivity activity, final Uri imageUri, int imageWidth, final MyCallback callback) {
        final String imagePath = getPathByUri(activity, imageUri);
        createScaledBitmap(activity, imagePath, imageWidth, callback);
    }

    /**
     * 返回bitmap 所占内存的大小
     */
    public static int getBitmapBytes(Bitmap bitmap) {
        return bitmap.getByteCount();
    }
}
回调接口类:
public interface MyCallback {
    void onPrepare();
    void onSucceed(Object object);
    void onError();
}

使用方法:

        BitmapUtils.createScaledBitmap(getContext(),imageUri,700, new MyCallback() {
            @Override
            public void onPrepare() {
            }

            @Override
            public void onSucceed(Object object) {
                String imagePath = (String) object;
            }

            @Override
            public void onError() {
            }
        });


        BitmapUtils.createScaledBitmap(getContext(),"/scard/images/13343222.png",700, new MyCallback() {
            @Override
            public void onPrepare() {
            }

            @Override
            public void onSucceed(Object object) {
                String imagePath = (String) object;
            }

            @Override
            public void onError() {
            }
        });

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值