如何使 SurfaceView 大于屏幕? [英] How can I make a SurfaceView larger than the screen?
问题描述
我想有效地为相机预览进行简单的数字缩放,所以我想我只需将 SurfaceView 的大小调整为大于屏幕.其他问题(例如 3813049) 似乎表明这很容易,所以我创建了下面的示例代码,我希望让我在水平方向上只看到一半的图像(因为 SurfaceView 是屏幕的两倍宽)并且图像只占一半屏幕水平.但是,运行它(在我的带有 Android 2.2.1 的 Thunderbolt 上针对 SDK 版本 4 时)导致能够在水平填充屏幕的同时水平查看整个图像.SurfaceView 在垂直方向上表现得像预期的那样(当我让它比屏幕小时),但 Android 不允许我让 SurfaceView 比屏幕大.
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.
如何实现数码变焦?(不,我不能使用 Camera.Parameters.setZoom;Android 1.6 不仅不支持,而且不同的相机支持和实现方式也不同)
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();
}
}
更新:根据@Pulkit Sethi 的回复,可以垂直拉伸/放大 SurfaceView,而不是水平.要垂直放大 SurfaceView,只需将 display.getHeight()/2 替换为上面的 display.getHeight()*2 即可.还要注意,无论是在我的代码中还是在 Pulkit 中,更改宽度都不会产生任何水平放大.
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屋!