zoukankan      html  css  js  c++  java
  • Android-加载大图片

    在开发之中会遇到,加载小图片没问题,当加载大图片的时候,内存溢出,为了解决这个问题,Android是提供了API 来处理优化图片的方式解决,就是计算屏幕宽高 和 图片宽高 的缩放比例,进行缩放,这样就不会报内存溢出错误来

      

    activity_image.xml 布局文件:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <ImageView
            android:id="@+id/image_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="readImageMin"
            android:text="读取Sdcard的小图片"
            android:layout_alignParentBottom="true"
            />
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="readImageMax"
            android:text="读取Sdcard的大图片"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            />
    
    </RelativeLayout>

    MyImageActivity.java

    package liudeli.my_media1;
    
    import android.app.Activity;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.os.Bundle;
    import android.os.Environment;
    import android.view.Display;
    import android.view.View;
    import android.widget.ImageView;
    import android.widget.Toast;
    
    import java.io.File;
    
    public class MyImageActivity extends Activity {
    
        private ImageView imageView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.activity_image);
    
            imageView = findViewById(R.id.image_view);
        }
    
        /**
         * 读取Sdcard小图片
         * @param view
         */
        public void readImageMin(View view) {
            File file = new File(Environment.getExternalStorageDirectory(), "mm.jpg");
            if (!file.exists()) {
                Toast.makeText(this, file.getName() + "不存在", Toast.LENGTH_SHORT).show();
                return;
            }
            /**
             * 通过BitmapFactory,去decodeFile加载图片
             */
            Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
            imageView.setImageBitmap(bitmap);
        }
    
        /**
         * 读取Sdcard的大图片
         * @param view
         */
        public void readImageMax(View view) {
    
            /**
             * >>>>>>>> 第一步:只获取图片的宽和高
             */
            BitmapFactory.Options options = new BitmapFactory.Options();
    
            // 设置只获取图片的信息,到时候记得还原恢复成false
            options.inJustDecodeBounds = true;
    
            /*
             * 第一次加载图片,只为获得宽高
             */
            BitmapFactory.decodeFile("/sdcard/big.JPG", options);
    
            // 获取图片的宽高
            int outWidth = options.outWidth;
            int outHeight = options.outHeight;
    
            /**
             * >>>>>>>> 第二步:获取屏幕的宽和高
             */
    
            // 获取手机屏幕的宽高,手机屏幕属于Window
            Display display = getWindow().getWindowManager().getDefaultDisplay();
            int windowWidth = display.getWidth();
            int windowHeight = display.getHeight();
    
            /**
             * >>>>>>>> 第三步:图片宽和高 对比 屏幕宽和高 = 计算宽高的缩放比例
             */
    
            /*
             * 计算宽高的缩放比例
             * valueX 代表横行 宽
             * valueY 代表纵向 高
             */
            int valueX = outWidth / windowWidth;
            int valueY = outHeight / windowHeight;
    
            /**
             * 判断宽和高的缩放比例哪个大,哪个大我就取哪个的值,只要把大的值处理即可
             */
            int value = valueX > valueY ? valueX : valueY;
    
            // 防止加载的图片,比屏幕小,如果比屏幕小,就没有必要缩放了
            if (0 >= value) {
                value = 1;
            }
    
            // 在这里要恢复options.inJustDecodeBounds,才能设置下面的代码,设置false需要加载图片内容啦
            options.inJustDecodeBounds = false;
    
            // 指定缩放比率
            options.inSampleSize = value;
    
            /**
             * 参数一:不推荐/sdcard/big.JPG 这种方式,因为每部手机的这个路径会变的,所以开发中要用Environment
             * 参数二:Options 选项 可以设置图片的比例缩放,从而解决图片内存溢出的问题
             */
            Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/big.JPG", options);
            imageView.setImageBitmap(bitmap);
        }
    }

    Android提供的BitmapFactory这个类,身上有个 decodeFile方法,参数一:加载要现实的图片地址,  参数二:Options 选项 可以设置图片的比例缩放,从而解决图片内存溢出的问题 

    Android系统源码 BitmapFactory.java 的 decodeFile方法:

    public static Bitmap decodeFile(String pathName, Options opts)

    如果加载大图片,不使用Options来处理,会报内存溢出OutOfMemoryError


    效果图:

  • 相关阅读:
    讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(上)
    Sagit.Framework For IOS 开发框架入门教程4:注册页布局-被消灭的变量
    Sagit.Framework For IOS 开发框架入门教程3:Start引导页及框架布局和隐藏事件的内幕
    Sagit.Framework For IOS 开发框架入门开发教程2:一行代码实现引导页
    Sagit.Framework For IOS 开发框架入门开发教程1:框架下载与环境配置
    CYQ.Data 正式支持 DotNET Core 版本发布
    IT连创业系列:App产品上线后,运营怎么搞?(中)
    IT连创业系列:App产品上线后,运营怎么搞?(上)
    分享:苹果APP更新上架被拒的另一种理由(Safety
    IT连创业系列:说说苹果商店AppStore上架App应用前后遇到的那些神坑
  • 原文地址:https://www.cnblogs.com/android-deli/p/10159353.html
Copyright © 2011-2022 走看看