美文网首页
图片压缩

图片压缩

作者: 龙_君 | 来源:发表于2019-08-13 11:55 被阅读0次

    一、图片的存在形式

    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();
                }
            });
        }
    }
    
    

    相关文章

      网友评论

          本文标题:图片压缩

          本文链接:https://www.haomeiwen.com/subject/pjevjctx.html