Android 图片优化 【 图片的二次采样】

图片优化,Android支持图片类型:

 PNG:   支持透明度,占用空间大
 JPEG: 不支持透明
 WEBP :  支持透明,占用空间小
 gif:   android本身的不支持
 
 1. 开发中图片处理
 drawable/mipmap :  官方建议把启动图标放入mip 下,其他放入 drawable, 开发只要一套最大图片即可,
 
  xxxdpi  3840*2016 
  xxhdpi  1920*1080
  xhdpi   1280*720
  hdpi    800*480
  
  2. 超大图片加载方法

  RGB_565 :  一个像素点占2个 字节
 ARGB_8888:  一个像素点占4个字节
 
 图片大小计算=  宽度* 高度*  每个像素字节数
 
 从上面原理优化图片:
 1. 尺寸压缩
 2. 质量压缩
 3. 内存重用

1. 图片的二次采样,避免图片太大OOM

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
public class MainActivity extends AppCompatActivity {

 private ImageView showImg;
    WindowManager wm=null;
    int WindowHeight;
    int WindowWidth;
   String filepath="/sdcard/1moviestest/large.png";


private int  MY_PERMISSIONS_REQUEST_CALL_PHONE=1000;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

 // 权限申请
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED)
        {
            ActivityCompat.requestPermissions(MainActivity.this,
                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},MY_PERMISSIONS_REQUEST_CALL_PHONE);
        } else
        {
        }
    }

 // 权限回调
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
    {

        if (requestCode == MY_PERMISSIONS_REQUEST_CALL_PHONE)
        {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
            {
            } else
            {
                // Permission Denied
                Toast.makeText(MainActivity.this, "Permission Denied", Toast.LENGTH_SHORT).show();
            }
            return;
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
	
	 // 避免图片太大挂了
    // 默认情况下 每个 anroid 给应用分配最大 堆大小16M (VM heap)
    public void sendNotification(View view) {

 //得到手机宽高
        wm=(WindowManager) getSystemService(WINDOW_SERVICE);
        WindowHeight=wm.getDefaultDisplay().getHeight();
        WindowWidth=wm.getDefaultDisplay().getWidth();


        showImg = findViewById(R.id.showImg);

        // 设置为true,那么不解析图片,获取图片部分信息
        BitmapFactory.Options opts=new BitmapFactory.Options();
        // 如果这里设置为true,那么就不为图片分配内存,而是起到对图片测量的公共
        // 查看bitmap信息,获取图片的头部信息
        opts.inJustDecodeBounds=true;
        BitmapFactory.decodeFile(filepath,opts);
        int imageHeight=opts.outHeight;
        int imageWidth=opts.outWidth;
        Log.e("Tag", "图片的高:"+imageHeight+ "WindowHeight:"+WindowHeight);
        Log.e("Tag", "图片的宽:"+imageWidth +"  WindowWidth:"+WindowWidth);
        // 得到手机屏幕的宽高
        double scaleX=imageWidth*1.0/WindowWidth;
        double scaleY=imageHeight*1.0/WindowHeight;
        double scale=1;
        // 按照大的来缩放,避免显示到屏幕外面
        if(scaleX>scaleY && scaleY>=1){
            scale=scaleX;
        }
        if(scaleY>scaleX && scaleX>=1){
            scale=scaleY;
        }
        Log.e("Tag", "double-->scale: "+ scale +"scale:"+(int)scale);
        // 解析图片, 正在把图片加载到内存中
        opts.inJustDecodeBounds=false;


        // 1. 减低图片的采样率,图片大小,从图片大小入手
        opts.inSampleSize=(int)scale;
        // 2. 从图片质量入手
        //  RGB_565 :  一个像素点占2个 字节
        // ARGB_8888:  一个像素点占4个字节
        opts.inPreferredConfig= Bitmap.Config.RGB_565;
        Bitmap bitmap=BitmapFactory.decodeFile(filepath,opts);
        showImg.setImageBitmap(bitmap);
      
    }


} 

  图片头信息读取Api:

    通过api:ExifInterface
         比如拍摄时间
        ExifInterface exif= null;
        try {
            exif = new ExifInterface("/sdcard/1.jpg");
        } catch (IOException e) {
            Log.e("Tag", "图片异常");
            e.printStackTrace();
        }
        String time=exif.getAttribute(ExifInterface.TAG_DATETIME); //通过getAttribute()获取照片的属性:时间、
        Log.e("Tag", "拍摄时间:"+time);
        String type=exif.getAttribute(ExifInterface.TAG_MODEL);
        String location = exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE);
        Log.e("Tag", "相机是:"+type);
        Log.e("Tag", "拍摄地点:"+location);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值