我怎样才能让一个SurfaceView大于屏幕? [英] How can I make a SurfaceView larger than the screen?

查看:1145
本文介绍了我怎样才能让一个SurfaceView大于屏幕?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想有效地使一个简单的数字变焦的相机preVIEW,所以我想我会简单地调整我的SurfaceView是大于屏幕。其他问题(如<一个href="http://stackoverflow.com/questions/3813049/how-to-create-a-view-that-is-bigger-than-the-screen">3813049)似乎表明,这很容易,所以我创建样本code以下,我希望让我看到只有一半​​的图像的水平(因为SurfaceView是两倍宽屏幕),并具有图像只占用屏幕的一半水平,然而,它运行在能够看到整个图像水平方向而水平地填充所述屏幕(当定位到SDK版本4在我的雷电与Android 2.2.1)的结果。该SurfaceView似乎表现为旨在垂直(当我使其小于屏幕),而Android不会让我做SurfaceView大于屏幕。

我如何能实现数码变焦? (不,我不能使用Camera.Parameters.setZoom,这不仅是不支持的Andr​​oid 1.6,但不同的摄像头支持和实施这一不同)

 公共类MagnifyTestActivity扩展活动实现SurfaceHolder.Callback {
    私人MagnificationView米preVIEW;
    私人SurfaceHolder mHolder;
    私人相机mCamera = NULL;

    @覆盖
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        米preVIEW =新MagnificationView(本);
        的setContentView(M preVIEW);
        mHolder = M preview.getHolder();
        mHolder.addCallback(本);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    公共类MagnificationView延伸SurfaceView {
        公共MagnificationView(上下文的背景下){
            超(上下文);
        }

        @覆盖
        保护无效onMeasure(INT widthMeasureSpec,诠释heightMeasureSpec){
            显示显示= getWindowManager()getDefaultDisplay()。
            INT宽度= display.getWidth()* 2;
            INT高度= display.getHeight()/ 2;
            widthMeasureSpec = MeasureSpec.makeMeasureSpec(宽,MeasureSpec.EXACTLY);
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(高度,MeasureSpec.EXACTLY);
            super.onMeasure(widthMeasureSpec,heightMeasureSpec);
        }
    }

    公共无效surfaceCreated(SurfaceHolder持有者){
        mCamera = Camera.open();
        尝试 {
            mCamera.set previewDisplay(保持器);
        }赶上(IOException异常E){
            e.printStackTrace();
        }
    }

    公共无效surfaceDestroyed(SurfaceHolder持有者){
        mCamera.stop preVIEW();
        mCamera.release();
        mCamera = NULL;
    }

    公共无效surfaceChanged(SurfaceHolder持有人,INT格式,INT W,INT高){
        mHolder.setFixedSize(W,H);
        mCamera.start preVIEW();
    }
}
 

更新:基于@Pulkit塞提的反应,有可能以拉伸/放大SurfaceView垂直,只是不是水平。要垂直放大的SurfaceView,只需更换display.getHeight()/ 2 display.getHeight()* 2以上。还观察到,改变宽度不产生任何水平放大,无论是在我的code或Pulkit的。

解决方案

  // Activity类

公共类CameraActivity扩展活动实现SurfaceListener {

    私有静态最后字符串变量=CameraActivity;

    相机mCamera;
    相机preVIEW米preVIEW;
    私人的FrameLayout mCamera preVIEW;


    @覆盖
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        的setContentView(R.layout.activity_camera);

        mCamera = getCameraInstance();
        米preVIEW =新相机preVIEW(这一点,mCamera);

        mCamera preVIEW =(的FrameLayout)findViewById(R.id.camera_ preVIEW);
        mCamera preview.addView(M preVIEW);


    }

    @覆盖
    保护无效的onPause(){
        super.onPause();

        releaseCamera();
    }

    私人摄像机getCameraInstance(){
        摄像头摄像头= NULL;
        尝试 {
            相机= Camera.open();
        }赶上(例外五){

        }
        返回摄像头;
    }

    私人无效releaseCamera(){
        如果(NULL!= mCamera){
            mCamera.release();
        }

        mCamera = NULL;
    }

    @覆盖
    公共无效surfaceCreated(){

        //更改这些伴侣
        INT宽= 1000;
        INT高= 1000;
        //设置父窗口PARAMS
        getWindow()的setLayout(宽度,高度)。

        RelativeLayout.LayoutParams PARAMS =新RelativeLayout.LayoutParams(
                宽度,高度);
        mCamera preview.setLayoutParams(PARAMS);
        mCamera preview.requestLayout();
    }
}

// preVIEW类

公共类相机preVIEW延伸SurfaceView工具
        SurfaceHolder.Callback {

    私有静态最后字符串变量=相机preVIEW;

    语境mContext;
    相机mCamera;
    SurfaceHolder mHolder;

    公共接口SurfaceListener {
        公共无效surfaceCreated();
    }
    SurfaceListener监听;


    公共摄像头preVIEW(上下文的背景下,相机摄像头){
        超(上下文);

        mContext =背景;
        监听=(SurfaceListener)mContext;
        mCamera =摄像头;

        mHolder = getHolder();
        mHolder.addCallback(本);

        //需提前3.0 HC
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    @覆盖
    公共无效surfaceCreated(SurfaceHolder持有者){

        尝试 {
            mCamera.set previewDisplay(保持器);

            参数PARAMS = mCamera.getParameters();
            //改变这里的参数
            mCamera.setParameters(PARAMS);

            mCamera.start preVIEW();

            listener.surfaceCreated();

        }赶上(例外五){
            // TODO:处理异常
        }
    }

    公共无效surfaceDestroyed(SurfaceHolder持有者){
        //空。以释放相机preVIEW在您的活动的照顾。
    }

    公共无效surfaceChanged(SurfaceHolder持有人,INT格式,INT W,INT高){
        //如果你的preVIEW可以改变或旋转,把这些事件的关心在这里。
        //确保调整或重新格式化之前停止preVIEW。

        Log.i(TAG,表面改称为);
        如果(mHolder.getSurface()== NULL){
            // preVIEW表面不存在
            返回;
        }

        在进行更改之前//停止preVIEW
        尝试 {
            mCamera.stop preVIEW();
        }赶上(例外五){
            //忽略:试图阻止一个不存在的preVIEW
        }

        //设置preVIEW大小并进行调整大小,旋转或
        //重新格式化的变化在这里
        mCamera.setDisplayOrientation(90);

        //启动preVIEW使用新设置
        尝试 {
            mCamera.set previewDisplay(mHolder);
            mCamera.start preVIEW();

        }赶上(例外五){
            Log.d(TAG,错误启动摄像头preVIEW:+ e.getMessage());
        }
    }

}

//布局文件
&LT; XML版本=1.0编码=UTF-8&GT?;
&LT; RelativeLayout的的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:layout_width =match_parent
    机器人:layout_height =match_parent&GT;

    &LT;的FrameLayout
        机器人:ID =@ + ID / camera_ preVIEW
        机器人:layout_width =300dp
        机器人:layout_height =400dp
        机器人:layout_centerHorizo​​ntal =真
        机器人:paddingTop =10dp&GT;
    &LT; /的FrameLayout&GT;

&LT; / RelativeLayout的&GT;
 

I would like to effectively make a simple digital zoom for the camera preview, so I thought I would simply resize my SurfaceView to be larger than the screen. Other questions (such as 3813049) seem to indicate that this is easy, so I created the sample code below which I expect to let me see only half of the image horizontally (since the SurfaceView is twice as wide as the screen) and have the image only take up half of the screen horizontally. However, running it (when targeted to SDK version 4 on my Thunderbolt with Android 2.2.1) results in being able to see the whole image horizontally while filling the screen horizontally. The SurfaceView appears to behave as intended vertically (when I make it smaller than the screen), but Android won't allow me to make the SurfaceView larger than the screen.

How can I implement a digital zoom? (No, I cannot use Camera.Parameters.setZoom; not only is this not supported by Android 1.6, but different cameras support and implement this differently)

public class MagnifyTestActivity extends Activity implements SurfaceHolder.Callback {
    private MagnificationView mPreview;
    private SurfaceHolder mHolder;
    private Camera mCamera = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPreview = new MagnificationView(this);
        setContentView(mPreview);
        mHolder = mPreview.getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public class MagnificationView extends SurfaceView {
        public MagnificationView(Context context) {
            super(context);
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            Display display = getWindowManager().getDefaultDisplay();
            int width = display.getWidth()*2;
            int height = display.getHeight()/2;
            widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }

    public void surfaceCreated(SurfaceHolder holder) {
        mCamera = Camera.open();
        try {
            mCamera.setPreviewDisplay(holder);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        mCamera.stopPreview();
        mCamera.release();
        mCamera = null;
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        mHolder.setFixedSize(w, h);
        mCamera.startPreview();
    }
}

UPDATE: Based on @Pulkit Sethi's response, it is possible to stretch/magnify the SurfaceView vertically, just not horizontally. To magnify the SurfaceView vertically, simply replace display.getHeight()/2 with display.getHeight()*2 above. Also observe that changing the width doesn't produce any horizontal magnification, either in my code or in Pulkit's.

解决方案

//Activity class

public class CameraActivity extends Activity implements SurfaceListener {

    private static final String TAG = "CameraActivity";

    Camera mCamera;
    CameraPreview mPreview;
    private FrameLayout mCameraPreview;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        setContentView(R.layout.activity_camera);

        mCamera = getCameraInstance();
        mPreview = new CameraPreview(this, mCamera);

        mCameraPreview = (FrameLayout) findViewById(R.id.camera_preview);
        mCameraPreview.addView(mPreview);


    }

    @Override
    protected void onPause() {
        super.onPause();

        releaseCamera();
    }

    private Camera getCameraInstance() {
        Camera camera = null;
        try {
            camera = Camera.open();
        } catch (Exception e) {

        }
        return camera;
    }

    private void releaseCamera() {
        if (null != mCamera) {
            mCamera.release();
        }

        mCamera = null;
    }

    @Override
    public void surfaceCreated() {

        //Change these mate
        int width = 1000;
        int height = 1000;
        // Set parent window params
        getWindow().setLayout(width, height);

        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                width, height);
        mCameraPreview.setLayoutParams(params);
        mCameraPreview.requestLayout();
    }
}

// Preview class

public class CameraPreview extends SurfaceView implements
        SurfaceHolder.Callback {

    private static final String TAG = "CameraPreview";

    Context mContext;
    Camera mCamera;
    SurfaceHolder mHolder;

    public interface SurfaceListener{
        public void surfaceCreated();
    }
    SurfaceListener listener;


    public CameraPreview(Context context, Camera camera) {
        super(context);

        mContext = context;
        listener = (SurfaceListener)mContext;
        mCamera = camera;

        mHolder = getHolder();
        mHolder.addCallback(this);

        // Required prior 3.0 HC
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {

        try {
            mCamera.setPreviewDisplay(holder);

            Parameters params = mCamera.getParameters();
            //Change parameters here
            mCamera.setParameters(params);

            mCamera.startPreview();

            listener.surfaceCreated();

        } catch (Exception e) {
            // TODO: handle exception
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // empty. Take care of releasing the Camera preview in your activity.
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // If your preview can change or rotate, take care of those events here.
        // Make sure to stop the preview before resizing or reformatting it.

        Log.i(TAG, "Surface changed called");
        if (mHolder.getSurface() == null) {
            // preview surface does not exist
            return;
        }

        // stop preview before making changes
        try {
            mCamera.stopPreview();
        } catch (Exception e) {
            // ignore: tried to stop a non-existent preview
        }

        // set preview size and make any resize, rotate or
        // reformatting changes here
        mCamera.setDisplayOrientation(90);

        // start preview with new settings
        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();

        } catch (Exception e) {
            Log.d(TAG, "Error starting camera preview: " + e.getMessage());
        }
    }

}

//Layout file 
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <FrameLayout
        android:id="@+id/camera_preview"
        android:layout_width="300dp"
        android:layout_height="400dp"
        android:layout_centerHorizontal="true"
        android:paddingTop="10dp" >
    </FrameLayout>

</RelativeLayout>

这篇关于我怎样才能让一个SurfaceView大于屏幕?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆