【HDR学习】利用SurfaceView显示图片

1.SurfaceView概述

SurfaceView从Android 1.0(API level 1)时就有 。它继承自类View,因此它本质上是一个View。但与普通View不同的是,它有自己的Surface,这个Surface在WMS中有自己对应的WindowState,在SF中也会有自己的Layer。

也就是说,虽然在App端它仍在View hierachy中,但在Server端(WMS和SF),它与宿主窗口是分离的。这样的好处是对这个Surface的渲染可以放到单独线程去做,渲染时可以有自己的GL context。这对于一些游戏、视频等性能相关的应用非常有益,因为它不会影响主线程对事件的响应。但它也有缺点,因为这个Surface不在View hierachy中,它的显示也不受View的属性控制,所以不能进行平移,缩放等变换,也不能放在其它ViewGroup中,一些View中的特性也无法使用。

SurfaceView属于View的子类它是专门为制作游戏而产生的,它的功能非常强大,最重要的是它支持OpenGL ES库,2D和3D的效果都可以实现。创建SurfaceView的时候需要实现SurfaceHolder.Callback接口,它可以用来监听SurfaceView的状态,比如:SurfaceView的改变 、SurfaceView的创建 、SurfaceView 销毁等。

SurfaceView、SurfaceHolder、Surface的关系可以概括为以下几点:

  • SurfaceView是拥有独立绘图层的特殊View。
  • Surface就是指SurfaceView所拥有的那个绘图层,其实它就是内存中的一段绘图缓冲区。
  • SurfaceView中具有两个Surface,也就是我们所说的双缓冲机制
  • SurfaceHolder顾名思义就是Surface的持有者,SurfaceView就是通过过SurfaceHolder来对Surface进行管理控制的。并且SurfaceView.getHolder方法可以获取SurfaceView相应的SurfaceHolder。
  • Surface是在SurfaceView所在的Window可见的时候创建的。我们可以使用SurfaceHolder.addCallback方法来监听Surface的创建与销毁的事件。

2.SurfaceView使用

下面,我们用SurfaceView来显示一张图片。

代码示例:

public class HdrPictureSurfaceView extends SurfaceView implements SurfaceHolder.Callback {

    private SurfaceHolder mHolder;
    private Canvas mCanvas;
    private Paint mPaint;
    private Paint mFontPaint;
    private Rect mSrcRect;
    private Rect mDstRect;
    private static Integer mHeight;
    private static Integer mWidth;
    private static Context mContext;

    public HdrPictureSurfaceView(Context context) {
        this(context, null);
    }

    public HdrPictureSurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        try (TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.HdrPictureSurfaceView)) {
            mIsHardwareAccel = attributes.getBoolean(R.styleable.HdrPictureSurfaceView_isHardwareAccel, false);
        }
        mContext = context;
        init();
    }

    private void init() {
        mHolder = getHolder();
        mHolder.setFormat(PixelFormat.RGBA_F16);
        mHolder.addCallback(this);

        mSrcRect = new Rect();
        mDstRect = new Rect();
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);//创建画笔

        mFontPaint = new Paint();
        mFontPaint.setStyle(Paint.Style.FILL);
        mFontPaint.setColor(Color.CYAN);
        mFontPaint.setStrokeWidth(12);
        mFontPaint.setTextSize(50);

        WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
        mWidth = wm.getDefaultDisplay().getWidth();
        mHeight = wm.getDefaultDisplay().getHeight();
    }

    @Override
    public void surfaceCreated(@NonNull SurfaceHolder holder) {
        Log.i(TAG, "surfaceCreated");
        drawImage();
    }

    @Override
    public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
        Log.i(TAG, "surfaceChanged");
    }

    @Override
    public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
        Log.i(TAG, "surfaceDestroyed");
    }

    protected void drawImage() {
        Log.i(TAG, "drawImage...");
        Bitmap bitmap;
        synchronized (mLock) {
            bitmap = mBitmaps.get(mBitmapIndex);  //根据实际情况由image获取
        }
        if (mIsHardwareAccel) {
            mCanvas = mHolder.lockHardwareCanvas();
        } else {
            mCanvas = mHolder.lockCanvas();
        }
        boolean hardwareAccelerated = mCanvas.isHardwareAccelerated();
        Log.i(TAG, "drawImage(): hardwareAccelerated=" + hardwareAccelerated);
        if (mCanvas != null) {
            mCanvas.drawColor(Color.BLACK);
            mSrcRect.set(0, 100, bitmap.getWidth(), bitmap.getHeight());
            mDstRect.set(0, 100, mWidth, bitmap.getHeight() * mWidth / bitmap.getWidth());
            mCanvas.drawBitmap(bitmap, mSrcRect, mDstRect, mPaint);//将bitmap画到画布上
        }
        if (mIsHardwareAccel) {
            mCanvas.drawText("硬件加速Canvas", 0.f, 50.f, mFontPaint);
        } else {
            mCanvas.drawText("普通Canvas", 0.f, 50.f, mFontPaint);
        }
        mHolder.unlockCanvasAndPost(mCanvas);//解锁画布同时提交
    }

}


参考:surfaceView原理
 

猜你喜欢

转载自blog.csdn.net/cocoduco/article/details/130352354
HDR
今日推荐