我正在尝试进行相机预览并在 onPreviewFrame() 中对其进行更改并将其显示给用户。我已经实现了所需的功能,但问题在于相机预览的大小。它总是占用屏幕的较小部分,我想让它全屏,即想要拍摄应该填满设备整个屏幕的相机预览。我有阅读并尝试了网上可用的任何解决方案,但在我的情况下它们都不起作用。这是 Surface View 类:
public class MySurfaceView extends SurfaceView implements Callback, Camera.PreviewCallback, android.view.SurfaceHolder.Callback {
private static final String TAG = "MySurfaceView";
private int width;
private int height;
public SurfaceHolder mHolder;
private Camera mCamera;
private int[] rgbints;
private int mMultiplyColor;
public MySurfaceView(Context context, AttributeSet attrs , Camera camera ,
int width , int height)
{
super(context, attrs);
mCamera = camera;
this.width = width;
this.height = height;
mHolder = getHolder();
mHolder.addCallback(this);
mMultiplyColor = getResources().getColor(R.color.honeydew);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
synchronized (this) {
this.setWillNotDraw(false); // This allows us to make our own draw calls to this canvas
rgbints = new int[width * height];
// try { mCamera.setPreviewDisplay(holder); } catch (IOException e)
// { Log.e("Camera", "mCamera.setPreviewDisplay(holder);"); }
mCamera.startPreview();
mCamera.setPreviewCallback(this);
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
synchronized (this) {
try
{
CameraActivity cameraActivity = new CameraActivity();
cameraActivity.releaseCamera();
cameraActivity = null;
} catch (Exception e) {
Log.e("Camera", e.getMessage());
}
}
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
Canvas canvas = null;
if (mHolder == null)
{
return;
}
try {
synchronized (mHolder)
{
canvas = mHolder.lockCanvas(null);
int canvasWidth = canvas.getWidth();
int canvasHeight = canvas.getHeight();
decodeYUV(rgbints, data, width, height);
// draw the decoded image, centered on canvas
canvas.drawBitmap(rgbints, 0, width, canvasWidth-((width+canvasWidth)>>1), canvasHeight-((height+canvasHeight)>>1), width, height, false, null);
// use some color filter
canvas.drawColor(mMultiplyColor, Mode.MULTIPLY);
}
} catch (Exception e){
e.printStackTrace();
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (canvas != null)
{
mHolder.unlockCanvasAndPost(canvas);
canvas = null;
}
}
}
public void decodeYUV(int[] out, byte[] fg, int width, int height) throws NullPointerException, IllegalArgumentException {
int sz = width * height;
if (out == null)
throw new NullPointerException("buffer out is null");
if (out.length < sz)
throw new IllegalArgumentException("buffer out size " + out.length + " < minimum " + sz);
if (fg == null)
throw new NullPointerException("buffer 'fg' is null");
if (fg.length < sz)
throw new IllegalArgumentException("buffer fg size " + fg.length + " < minimum " + sz * 3 / 2);
int i, j;
int Y, Cr = 0, Cb = 0;
for (j = 0; j < height; j++) {
int pixPtr = j * width;
final int jDiv2 = j >> 1;
for (i = 0; i < width; i++) {
Y = fg[pixPtr];
if (Y < 0)
Y += 255;
if ((i & 0x1) != 1) {
final int cOff = sz + jDiv2 * width + (i >> 1) * 2;
Cb = fg[cOff];
if (Cb < 0)
Cb += 127;
else
Cb -= 128;
Cr = fg[cOff + 1];
if (Cr < 0)
Cr += 127;
else
Cr -= 128;
}
int R = Y + Cr + (Cr >> 2) + (Cr >> 3) + (Cr >> 5);
if (R < 0)
R = 0;
else if (R > 255)
R = 255;
int G = Y - (Cb >> 2) + (Cb >> 4) + (Cb >> 5) - (Cr >> 1) + (Cr >> 3) + (Cr >> 4) + (Cr >> 5);
if (G < 0)
G = 0;
else if (G > 255)
G = 255;
int B = Y + Cb + (Cb >> 1) + (Cb >> 2) + (Cb >> 6);
if (B < 0)
B = 0;
else if (B > 255)
B = 255;
out[pixPtr++] = 0xff000000 + (B << 16) + (G << 8) + R;
}
}
}
public void showSupportedCameraFormats(Parameters p) {
List<Integer> supportedPictureFormats = p.getSupportedPreviewFormats();
Log.d(TAG, "preview format:" + cameraFormatIntToString(p.getPreviewFormat()));
for (Integer x : supportedPictureFormats) {
Log.d(TAG, "suppoterd format: " + cameraFormatIntToString(x.intValue()));
}
}
@SuppressWarnings("deprecation")
private String cameraFormatIntToString(int format) {
switch (format) {
case PixelFormat.JPEG:
return "JPEG";
case PixelFormat.YCbCr_420_SP:
return "NV21";
case PixelFormat.YCbCr_422_I:
return "YUY2";
case PixelFormat.YCbCr_422_SP:
return "NV16";
case PixelFormat.RGB_565:
return "RGB_565";
default:
return "Unknown:" + format;
}
}
}
这是调用者类:
public class CameraActivity extends Activity {
private Camera mCamera;
private MySurfaceView surfaceView;
private RelativeLayout relativeLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
releaseCamera();
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
releaseCamera();
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
mCamera = Camera.open();
Camera.Parameters p = mCamera.getParameters();
Size size = p.getPreviewSize();
int width = size.width;
int height = size.height;
p.setPreviewFormat(ImageFormat.JPEG);
mCamera.setParameters(p);
surfaceView = new MySurfaceView(this, null , mCamera ,width , height);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
surfaceView.setLayoutParams(layoutParams);
relativeLayout = (RelativeLayout)findViewById(R.id.relativeLayout);
relativeLayout.addView(surfaceView);
surfaceView.showSupportedCameraFormats(p);
}
public void releaseCamera()
{
if (mCamera != null)
{
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
surfaceView.getHolder().removeCallback(surfaceView);
mCamera.release(); // release the camera for other applications
mCamera = null;
surfaceView.mHolder.removeCallback(surfaceView);
surfaceView.mHolder = null;
surfaceView = null;
relativeLayout.removeAllViews();
relativeLayout.removeAllViewsInLayout();
relativeLayout = null;
}
}
}
请帮助我。在此先感谢。
编辑:
xml是:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:id="@+id/relativeLayout"
android:layout_height="match_parent" >
</RelativeLayout>