图片压缩

一、图片的存在形式

1.文件形式(即以二进制形式存在于硬盘上)
2.流的形式(即以二进制形式存在于内存中)
3.Bitmap形式 (位图图像(bitmap), 亦称为点阵图像或绘制图像,是由称作像素(图片元素)的单个点组成的。这些点可以进行不同的排列和染色以构成图样。)

这三种形式的区别: 文件形式和流的形式对图片体积大小并没有影响,也就是说,如果你手机SD卡上的如果是100K,那么通过流的形式读到内存中,也一定是占100K的内存,注意是流的形式,不是Bitmap的形式,当图片以Bitmap的形式存在时,其占用的内存会瞬间变大, 我试过500K文件形式的图片加载到内存,以Bitmap形式存在时,占用内存将近10M,当然这个增大的倍数并不是固定的。

二、Android中图片形式

Android中图片是以位图(BitMap)形式存在的,位图常见的文件格式有:

.bmp
.jpg
.gif
.png

一张图片(BitMap)占用的内存主要和以下几个因数有关:图片长度,图片宽度,单位像素占用的字节数。

一张图片(BitMap)占用的内存=图片长度x图片宽度x单位像素占用的字节数

位图(BitMap)的优缺点:
  位图(BitMap)色彩变化丰富,可以改变任何形状的区域的色彩显示效果,相应的,要实现的效果越复杂,需要的象素数越多,图像文件的大小长宽和体积[存储空间]越大。
  位图的一个缺点是放大和缩小都会引起像素的增加和减小,这样会使得原由的图象的线条和形状变的参差不齐,与原图像相比出现失真;出现”锯齿形“。位图的另一个缺点就是数据量太大(如:长和宽分别为1024像素和768像素得24位色彩深度的图象就需要(1024×768×24÷8)=2304K个字节存储文件)。

三、看代码:

public class HomelActivity extends AppCompatActivity {
    private static final int REQUEST_WRITE = 0;
    @BindView(R.id.but)
    Button but;
    @BindView(R.id.img)
    ImageView img;

    private int width, height;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_homel);
        ButterKnife.bind(this);
        initData();

        //获取系统宽高
        WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
        Display defaultDisplay = wm.getDefaultDisplay();
        width = defaultDisplay.getWidth();
        height = defaultDisplay.getHeight();
    }


//    动态获取权限
    private void check() {
        //判断是否6.0以上的手机     不是就不用
        if (Build.VERSION.SDK_INT >= 23) {
            if (ContextCompat.checkSelfPermission(this,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE) !=
                    PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                        REQUEST_WRITE);
            } else {
//                  writeToSdCard2();
//                writeToSdCard3();
                writeToSdCard();
            }
        }


    }




//    动态获取权限
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_WRITE && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//            writeToSdCard2();
//            writeToSdCard3();
            writeToSdCard();

        }
    }

裁剪压缩 压缩是图片尺寸 基于内存压缩的:







//    //裁剪压缩 压缩是图片尺寸 基于内存压缩的
//    private void writeToSdCard3() {
//        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ava);
//        Matrix martx = new Matrix();
//        martx.setScale(0.1F, 0.1F);
//        Bitmap newBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),
//                martx, true);
//        int mb = newBitmap.getByteCount() / 1024 / 1024;
//        Log.e("TAG", "mb=====" + mb + "----------" +
//                "M宽度为" + newBitmap.getWidth() + "高度为" + newBitmap.getHeight());
//
//
//        img.setImageBitmap(newBitmap);
//    }



二次采样:



//    //图片二次采样 (采用两次尝试解析图片  第一次不是完全解析,第一次)
//    public void click() {
////        check();
//
//        //第一次解析图片  并不是直接解析整张图片 直接获取图片的宽和高
//        BitmapFactory.Options options = new BitmapFactory.Options();
//        options.inJustDecodeBounds = true;
//        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ava, options);
//
//        int outWidth = options.outWidth;
//        int outHeight = options.outHeight;
//
//        int scale = 0;
//        if (outWidth > width || outHeight > height) {
//            int scaleWidth = outWidth / width;
//            int scaleHeight = outHeight / height;
//            scale = scaleWidth > scaleHeight ? scaleWidth : scaleHeight;
//        }
//
//        //将压缩比例赋值给options
//        options.inSampleSize = scale;
//        //options.inPreferredConfig = Bitmap.Config.RGB_565;
//
//
//        //3.开始真正解析这个图片
//        options.inJustDecodeBounds = false;
//        bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ava, options);
//
//        img.setImageBitmap(bitmap);
//
//
//
//        //按照图片格式压缩
////        BitmapFactory.Options op = new BitmapFactory.Options();
////        op.inPreferredConfig = Bitmap.Config.RGB_565;
////        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.a, op);
////        img.setImageBitmap(bitmap);
//
//
//    }



从网络获取图片解析并压缩保存到CD卡


//
//    //从网络获取图片解析并压缩
//    private void writeToSdCard2() {
//        if (!Environment.getExternalStorageState().
//                equals(Environment.MEDIA_MOUNTED)) {
//            Toast.makeText(this, "外部存储卡不能用", Toast.LENGTH_LONG).show();
//            return;
//        }
//        final String save_path = Environment.getExternalStorageDirectory() + "/123/aaaaaaaa____aaaaaaaa.jpg";
//
//
//
//        OkHttpClient client = new OkHttpClient.Builder().
//                connectTimeout(5000, TimeUnit.MILLISECONDS).
//                readTimeout(5000, TimeUnit.MILLISECONDS).build();
//        Request request = new Request.Builder().url("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1565603767756&di=9a62675ce0212a8ad7d2e2395b960a32&imgtype=0&src=http%3A%2F%2Fimg2.fengniao.com%2Fg1%2FM00%2F02%2F29%2FCg-4q1V9RwaIa5k9AGH7UztR7qgAAI1kwGKc-IAYftr651.jpg").build();
//        Call call = client.newCall(request);
//        call.enqueue(new Callback() {
//            @Override
//            public void onFailure(Call call, IOException e) {
//                Log.e("TAG", "请求失败" + e.getMessage());
//            }
//
//
//            @Override
//            public void onResponse(Call call, Response response) throws IOException {
//                ResponseBody body = response.body();
//                InputStream inputStream = body.byteStream();
//                final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
//                FileOutputStream fos = new FileOutputStream(save_path);
//                int count = 0;
//                byte[] buffer = new byte[1024];
//                while ((count = inputStream.read(buffer)) != -1) {
//                    fos.write(buffer, 0, count);
//                }
//                boolean flag = bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);
//                Log.e("TAG", flag + "==========");
//            }
//        });
//    }




从assets文件夹,读取图片并压缩到SD卡里:


    //从assets文件夹,读取图片并压缩到SD卡里
    private void writeToSdCard() {
        if (!Environment.getExternalStorageState().
                equals(Environment.MEDIA_MOUNTED)) {
            Toast.makeText(this, "外部存储卡不能用", Toast.LENGTH_LONG).show();
            return;
        }
        String save_path = Environment.getExternalStorageDirectory() + "/123/xxxxxxxxxxxxxxxxx.jpg";

        Bitmap bitmap = null;
        try {
            InputStream inputStream = getAssets().
                    open("a.jpg");
            bitmap = BitmapFactory.decodeStream(inputStream);

            //文件输出流  向sdcard里面写文件
            FileOutputStream fos = new FileOutputStream(save_path);
            int length = 0;
            byte[] buffer = new byte[1024];
            while ((length = inputStream.read(buffer)) != -1) {
                fos.write(buffer, 0, length);
                Log.e("TAG", "aaaaa");
            }
//                                                                                          
            bitmap.compress(Bitmap.CompressFormat.JPEG, 50, fos);

            img.setImageBitmap(bitmap);
        } catch (IOException e) {
            e.printStackTrace();
            Log.e("TAG", "===error======" + e.getLocalizedMessage());
        }
    }


















以上是四种压缩放式!


    private void initData() {

        //按钮点击事件
        but.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
//                //图片二次采样 (采用两次尝试解析图片  第一次不是完全解析,第一次)
//                  click();


                //获取权限
                check();
            }
        });
    }
}

你可能感兴趣的:(图片压缩)