Chapter 6 Android–ImageView, Bitmap

ImageView, and the TextView and EditText introduced earlier, all inherit from View and are all subclasses of View.

ImageView is a view used to render images. View can be understood as a view or control.

1. Simple to use

Place an image under the drawable-xxhdpi folder:

Set this picture to ImageView in xml, so that you can see this picture on the screen:

 <ImageView
        android:id="@ + id/image_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/girl" />

In addition, you can also set pictures for ImageView in code:

method 1:

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

Method 2:

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

In method 1, a resource Id is passed in through setImageResource(@DrawableRes int resId). In this method, the resource Id will be loaded into a Drawable.

ImageView.java

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

In method 2, first parse the resource ID into a Bitmap, and then set the Bitmap to the ImageView.

imageView.setImageBitmap(bitmap); In this method, the passed bitmap will also be converted into Drawable.

 mDrawable = null;
        if (mRecycleableBitmapDrawable == null) {
            mRecycleableBitmapDrawable = new BitmapDrawable(mContext.getResources(), bm);
        } else {
            mRecycleableBitmapDrawable.setBitmap(bm);
        }
        setImageDrawable(mRecycleableBitmapDrawable);

The above two methods will assign the generated Drawable to the member variable of ImageView: Drawable mDrawable

After the settings are completed, invalidate() is called;

This will call invalidate() of the parent class View,

Parent will be called in View, which is the invalidate() method of ViewRootImpl.

In the invalidate() method of ViewRootImpl, scheduleTraversals will be triggered, the traversal will be executed, and the layout measurement will be re-measured and the draw method will be executed.

So it will eventually be called back to the onDraw method of ImageView, and the drawable.draw method will be called in the ondraw method.

In the draw method, a canvas is passed in, and the drawable will eventually be converted into a bitmap and drawn on the canvas, and then handed to the Native layer for presentation on the screen.

 @Override
    protected void onDraw(Canvas canvas) {
      if (mDrawMatrix == null & amp; & amp; mPaddingTop == 0 & amp; & amp; mPaddingLeft == 0) {
            mDrawable.draw(canvas);
        } else {
           ........
            mDrawable.draw(canvas);
          .........
            
        }
    }

2. Introduction to BitmapFactory related methods:

//Load a Bitmap from the drable directory
BitmapFactory.decodeResource(getResources(), R.drawable.girl);
//Parse the specified file into a Bitmap
BitmapFactory.decodeFile(file);
//Parse from the memory array into a Bitmap
BitmapFactory.decodeByteArray(byteArray,offset,lenght);
//Load a Bitmap from the stream,
 //This can be a file stream, reading a local cache file
//It can also be a network stream, obtained from the network.
BitmapFactory.decodeStream(inputStream);

1) Read a picture from a file. Since it is designed for file io operations, it is best to put it in a child thread.

Example: Read an image into memory through RxJava.

First introduce the Rxjava related jar package in build.gragle:

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

Code:

public void createBitmap(ImageView imageView,String file) {
        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                emitter.onNext(file);
            }
        }).subscribeOn(Schedulers.io()).map(new Function<String, Bitmap>() {

            @Override
            public Bitmap apply(String file) throws Exception {
                return BitmapFactory.decodeFile(file);
            }
        }).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Bitmap>() {
            @Override
            public void accept(Bitmap bitmap) throws Exception {
                imageView.setImageBitmap(bitmap);
            }
        });
    }

2) Get image examples from the Internet:

/**
     * Get network pictures
     *
     * @param imageurl image network address
     * @return Bitmap Return bitmap
     */
    public Bitmap GetImageInputStream(String imageurl) {
        URL url;
        HttpURLConnection connection = null;
        Bitmap bitmap = null;
        try {
            url = new URL(imageurl);
            connection = (HttpURLConnection) url.openConnection();
            connection.setConnectTimeout(6000); //Timeout setting
            connection.setDoInput(true);
            connection.setUseCaches(false); //Set not to use cache
            InputStream inputStream = connection.getInputStream();
 
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize = 2;
            options.inJustDecodeBounds = false;
 
            bitmap = BitmapFactory.decodeStream(inputStream, null, options);
            inputStream.close();
 
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bitmap;
    }

3.BitmapFactory.Options

1) options.inJustDecodeBounds = true; Do not load the image into memory, only get the width and height.

 FileInputStream fis = new FileInputStream("fileName");
        BitmapFactory.Options options = new BitmapFactory.Options();
        //If true, only the size of the image will be loaded, a null value will be returned, and the image will not be loaded into memory.
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(fis, null, options);
        //Get the width and height of the image
        int imgWidth = options.outWidth;
        int imgHeight = options.outHeight;

2) options.inSampleSize = 2; If the setting value is greater than 1, the size of the loaded image is 1/4 of the principle.

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

4. Create Bitmap: Bitmap.createBitmap()

1) Code example: Save View to a bitmap:

 public static Bitmap getBitmapForView(View view) {
        int width = view.getWidth();
        int height = view.getHeight();
        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);//Prepare the picture
        Canvas canvas = new Canvas(bitmap);//Use bitmap as drawing canvas
        view.draw(canvas);//Draw the specific area of the View to this canvas (bitmap),
        return bitmap;//Get the latest canvas
    }

2) Get a bitmap of another size from a bitmap

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

3) Save a bitmap in memory as a local picture:

 Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.girl);
        try {
            FileOutputStream fos = new FileOutputStream("fileName");
            srcBitmap.compress(Bitmap.CompressFormat.JPEG,100,fos);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }