Audio and Video: Draw pictures in three ways

Posted by raister on Sat, 25 Jan 2020 04:16:49 +0100

Because video rendering is essentially about displaying pictures one by one, the first step in learning is to learn to display pictures.

This time we use three different ways to display a picture.

ImageView

ImageView is the easiest and most common way to use it.

context?.let {
      image.setImageBitmap(decodeStream(it.assets.open("images/test_image.jpeg")))
}

SurfaceView

We know that View redraws view by refreshing, system redraws screen by sending VSSYNC signal, refresh interval is 16 ms, if we can in 16 msIf the drawing process is very complex and our interface is updated very frequently, it will cause the interface to get stuck and affect the user experience.SurfaceView is provided for Android to solve this problem.

What is the difference between SurfaceView and View?

  1. View is suitable for passively updated scenarios, while SurfaceView is suitable for active updates, such as frequent refreshes of the interface.(See below for specific reasons)
  2. View refreshes the page in the main thread, while SurfaceView opens a sub-thread to refresh the page.(the most essential difference)
  3. View does not have a double buffer mechanism when drawing, while SurfaceView implements a double buffer mechanism at the bottom.

Code

The last one that must be coded [Dog Head]

surfaceView.holder.addCallback(object : SurfaceHolder.Callback {
    override fun surfaceCreated(holder: SurfaceHolder?) {
        holder?.let {
            Thread {
                val canvas = it.lockCanvas()
                val bitmap =
                    decodeStream(context?.assets?.open("images/test_image.jpeg"))
                val bitmapW = bitmap.width
                val bitmapH = bitmap.height
                val src = Rect(0, 0, bitmapW, bitmapH)
                val dst = if (bitmapW > bitmapH) {
                    Rect(
                        0,
                        0,
                        surfaceView.width,
                        (surfaceView.width * (bitmapH.toFloat() / bitmapW)).toInt()
                    )

                } else {
                    Rect(
                        0,
                        0,
                        surfaceView.height * (bitmapW / bitmapH),
                        surfaceView.height
                    )
                }
                canvas.drawColor(Color.parseColor("#ffffff"))
                canvas.drawBitmap(
                    bitmap,
                    src,
                    dst,
                    Paint()
                )
                it.unlockCanvasAndPost(canvas)
            }.start()

        }
    }

    override fun surfaceChanged(
        holder: SurfaceHolder?,
        format: Int,
        width: Int,
        height: Int
    ) {
    }

    override fun surfaceDestroyed(holder: SurfaceHolder?) {
    }

})

Custom View

Custom View is similar to SurfaceView, just look at the code:

class CustomImageView : View {
    constructor(context: Context?) : super(context) {}
    constructor(context: Context?, attrs: AttributeSet?) : super(
        context,
        attrs
    )
    
    constructor(
        context: Context?,
        attrs: AttributeSet?,
        defStyleAttr: Int
    ) : super(context, attrs, defStyleAttr)

    constructor(
        context: Context?,
        attrs: AttributeSet?,
        defStyleAttr: Int,
        defStyleRes: Int
    ) : super(context, attrs, defStyleAttr, defStyleRes)

    private val bitmap: Bitmap =
        BitmapFactory.decodeStream(context?.assets?.open("images/test_image.jpeg"))

    private val src = Rect()
    private val dst = Rect()
    private val paint = Paint()
    
    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        val bitmapW = bitmap.width
        val bitmapH = bitmap.height
        src.set(0, 0, bitmapW, bitmapH)
        if (bitmapW > bitmapH) {
            dst.set(
                0,
                0,
                this.width,
                (this.width * (bitmapH.toFloat() / bitmapW)).toInt()
            )

        } else {
            dst.set(
                0,
                0,
                this.height * (bitmapW / bitmapH),
                this.height
            )
        }
        canvas?.drawBitmap(bitmap, src, dst, paint)
    }
}

Last

OK, the first task is done - the code is updated in GitHub warehouse Medium.New Year's Event. See ~

  • GitHub repository: https://github.com/T-Oner/MediaPractice
    For the latest updates, please follow the WeChat Public Number
Published an original article. Praise 0. Visits 3
Private letter follow

Topics: SurfaceView github Android