• 第六篇Android--ImageView、Bitmap


    ImageView,和前面介绍的TextView、EditText,都继承自View都是View的子类。

    ImageView 是用于呈现图片的视图。View可以理解为一个视图或控件。

    1.简单使用

       在drawable-xxhdpi文件夹下放一张图片:

       

      xml中把这张图片设置给ImageView,这样就可以在屏幕上看到这张图:

    1. <ImageView
    2. android:id="@+id/image_view"
    3. android:layout_width="wrap_content"
    4. android:layout_height="wrap_content"
    5. android:src="@drawable/girl" />

      另外也可以在代码中给ImageView设置图片:

         方法1:

    1. imageView = findViewById(R.id.image_view);
    2. imageView.setImageResource(R.drawable.girl);

         方法2:

    1. Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.girl);
    2. imageView.setImageBitmap(bitmap);

       方法1中通过:setImageResource(@DrawableRes int resId)方式,传入一个资源Id,在该方法内会把资源Id加载成一个Drawable。

           ImageView.java中

    1. try {
    2. d = mContext.getDrawable(mResource);
    3. } catch (Exception e) {
    4. Log.w(LOG_TAG, "Unable to find resource: " + mResource, e);
    5. // Don't try again.
    6. mResource = 0;
    7. }

       方法2中,先把资源Id解析成一个Bitmap,然后把Bitmap设置给ImageView。

          imageView.setImageBitmap(bitmap); 这个方法中,也会把传进来的bitmap转换成Drawable。

    1. mDrawable = null;
    2. if (mRecycleableBitmapDrawable == null) {
    3. mRecycleableBitmapDrawable = new BitmapDrawable(mContext.getResources(), bm);
    4. } else {
    5. mRecycleableBitmapDrawable.setBitmap(bm);
    6. }
    7. setImageDrawable(mRecycleableBitmapDrawable);

      以上两种方式都会把生成的Drawable赋值给ImageView的成员变量:Drawable  mDrawable

       设置完成后,都调用了invalidate();

                            这会调用父类View的invalidate(),

                            在View中会调用Parent,也就是ViewRootImpl的invalidate()方法。

                            在ViewRootImpl的invalidate()方法中,会触发scheduleTraversals,执行遍历,重新               进行布局layout测量measure绘制draw方法。

      所以最终会回调到了ImageView的onDraw方法中,ondraw方法中会调用drawable.draw方法。

           在draw方法中,传递进来一个画布canvas,最终会把该drawable转成一个bitmap绘制在canvas上,然后交给Native层,在屏幕上进行呈现。

    1. @Override
    2. protected void onDraw(Canvas canvas) {
    3. if (mDrawMatrix == null && mPaddingTop == 0 && mPaddingLeft == 0) {
    4. mDrawable.draw(canvas);
    5. } else {
    6. ........
    7. mDrawable.draw(canvas);
    8. .........
    9. }
    10. }

       2.BitmapFactory相关方法介绍:

    1. //从drable目录下加载一个Bitmap
    2. BitmapFactory.decodeResource(getResources(), R.drawable.girl);
    3. //把指定文件解析成一个Bitmap
    4. BitmapFactory.decodeFile(file);
    5. //从内存数组中解析成一个Bitmap
    6. BitmapFactory.decodeByteArray(byteArray,offset,lenght);
    7. //从流中加载一个Bitmap,
    8. //这个可以是一个文件流,读取本地的一个缓存文件
    9. //也可以是一个网络流,从网络获取。
    10. BitmapFactory.decodeStream(inputStream);

       1)从文件中读取一张图片,由于设计到文件io操作,最好是放在子线程中。

            示例:通过RxJava读取一张图片到内存。

            首先在build.gragle引入Rxjava相关jar包:

    1. implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
    2. implementation 'io.reactivex.rxjava2:rxjava:2.2.4'

           代码实现:

    1. public void createBitmap(ImageView imageView,String file) {
    2. Observable.create(new ObservableOnSubscribe<String>() {
    3. @Override
    4. public void subscribe(ObservableEmitter<String> emitter) throws Exception {
    5. emitter.onNext(file);
    6. }
    7. }).subscribeOn(Schedulers.io()).map(new Function<String, Bitmap>() {
    8. @Override
    9. public Bitmap apply(String file) throws Exception {
    10. return BitmapFactory.decodeFile(file);
    11. }
    12. }).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Bitmap>() {
    13. @Override
    14. public void accept(Bitmap bitmap) throws Exception {
    15. imageView.setImageBitmap(bitmap);
    16. }
    17. });
    18. }

      2)从网络获取图片示例:

    1. /**
    2. * 获取网络图片
    3. *
    4. * @param imageurl 图片网络地址
    5. * @return Bitmap 返回位图
    6. */
    7. public Bitmap GetImageInputStream(String imageurl) {
    8. URL url;
    9. HttpURLConnection connection = null;
    10. Bitmap bitmap = null;
    11. try {
    12. url = new URL(imageurl);
    13. connection = (HttpURLConnection) url.openConnection();
    14. connection.setConnectTimeout(6000); //超时设置
    15. connection.setDoInput(true);
    16. connection.setUseCaches(false); //设置不使用缓存
    17. InputStream inputStream = connection.getInputStream();
    18. BitmapFactory.Options options = new BitmapFactory.Options();
    19. options.inSampleSize = 2;
    20. options.inJustDecodeBounds = false;
    21. bitmap = BitmapFactory.decodeStream(inputStream, null, options);
    22. inputStream.close();
    23. } catch (Exception e) {
    24. e.printStackTrace();
    25. }
    26. return bitmap;
    27. }

    3.BitmapFactory.Options

         1)options.inJustDecodeBounds = true;不把图加载到内存,只获取宽高。 

    1. FileInputStream fis = new FileInputStream("fileName");
    2. BitmapFactory.Options options = new BitmapFactory.Options();
    3. //true则只加载图片的大小,返回一个null值,不会把图片加载到内存
    4. options.inJustDecodeBounds = true;
    5. BitmapFactory.decodeStream(fis, null, options);
    6. //得到图片的宽高
    7. int imgWidth = options.outWidth;
    8. int imgHeight = options.outHeight;

       2) options.inSampleSize = 2; 设置值大于1,加载的图片大小是原理的4分之1,

    1. BitmapFactory.Options options = new BitmapFactory.Options();
    2. options.inSampleSize = 2;
    3. Bitmap bitmap = BitmapFactory.decodeFile(imageFile,options);

    4.创建Bitmap:Bitmap.createBitmap()

       1)代码示例:把View保存到一个bitmap:

    1. public static Bitmap getBitmapForView(View view) {
    2. int width = view.getWidth();
    3. int height = view.getHeight();
    4. Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);//准备图片
    5. Canvas canvas = new Canvas(bitmap);//将bitmap作为绘制画布
    6. view.draw(canvas);//讲View特定的区域绘制到这个canvas(bitmap)上去,
    7. return bitmap;//得到最新的画布
    8. }

      2)从一个bitmap得到另外一个大小的bitmap

    1. Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.girl);
    2. int x = 0;
    3. int y = 0 ;
    4. float rate = 1.5f;
    5. int width = (int) (srcBitmap.getWidth()*rate);
    6. int height = (int) (srcBitmap.getHeight()*rate);
    7. Bitmap bitmap = Bitmap.createBitmap(srcBitmap,x,y,width,height);

    3)将内存中的一个bitmap保存为一张本地图片:

    1. Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.girl);
    2. try {
    3. FileOutputStream fos = new FileOutputStream("fileName");
    4. srcBitmap.compress(Bitmap.CompressFormat.JPEG,100,fos);
    5. } catch (FileNotFoundException e) {
    6. e.printStackTrace();
    7. }
  • 相关阅读:
    矩阵分解PCA,SVD
    [LeetCode]-链表-2
    python珍藏宝藏学习资料
    微信小程序 实现滑块是矩形的slider组件
    【无标题】
    【Docker】非root用户加入docker用户组省去sudo (三)
    【工具免费】喜马拉雅 x2m转m4a,xm转mp3的简单方法!
    pytorch 模型复现
    Linux激活Linux系统中交换空间
    汇智动力《软件测试课程V8.0版本》正式发布!
  • 原文地址:https://blog.csdn.net/niuyongzhi/article/details/133793382