在相机预览框中添加一个按钮

时间:2011-08-16 01:58:33

标签: java android

我正在尝试通过XML向相机的预览框添加一个按钮,虽然一切正常,但即使我从代码中添加按钮后按钮也不显示。谁能帮帮我吗?以下是我的代码的一部分:

主要课程:

public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    dummy = (Button)findViewById(R.id.dummy); //adding button

    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

    mContext = this;
    mPreview = new Preview(this);
    setContentView(mPreview);
    manager = new CameraConfigurationManager(this);
    display = ((WindowManager) this.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
    screenResolution = new Point(display.getWidth(), display.getHeight());
    rect = getFramingRect();       
    mDraw = new DrawOnTop(this, rect);

    addContentView(mDraw, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

}

我的main.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical">
<SurfaceView android:id="@+id/surface_camera"
    android:layout_width="fill_parent" android:layout_height="10dip"
    android:layout_weight="1">      
</SurfaceView>
    <Button android:id="@+id/dummy" 
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="a Button" />
</LinearLayout>

预览课程:

public class Preview extends ViewGroup implements SurfaceHolder.Callback {
private final String TAG = "Preview";

SurfaceView mSurfaceView;
SurfaceHolder mHolder;
Size mPreviewSize;
List<Size> mSupportedPreviewSizes;
Camera mCamera;

public Preview(Context context) {
    super(context);
     mSurfaceView = new SurfaceView(context);
     addView(mSurfaceView);

     mHolder = mSurfaceView.getHolder();
     mHolder.addCallback(this);
     mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

public Preview(Context context, AttributeSet attrs) {
     super(context);
     mSurfaceView = new SurfaceView(context);
     addView(mSurfaceView);

     mHolder = mSurfaceView.getHolder();
     mHolder.addCallback(this);
     mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

public void setCamera(Camera camera) {
    mCamera = camera;
    if(mCamera != null) {
        mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
        requestLayout();
    }
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
    final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
    setMeasuredDimension(width, height);

    if(mSupportedPreviewSizes != null) {
        mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
    }
}

protected void onLayout(boolean changed, int l, int t, int r, int b) {
    if (changed && getChildCount() > 0) {
        final View child = getChildAt(0);

        final int width = r - l;
        final int height = b - t;

        int previewWidth = width;
        int previewHeight = height;
        if(mPreviewSize != null) {
            previewWidth = mPreviewSize.width;
            previewHeight = mPreviewSize.height;
        }

        if(width*previewHeight > height * previewWidth) {
            final int scaledChildWidth = previewWidth * height / previewHeight;
            child.layout(((width) - scaledChildWidth) /2, 0, ((width) + scaledChildWidth) /2, height);
        }
        else {
            final int scaledChildHeight = previewHeight * width / previewWidth;
            child.layout(0, ((height)-scaledChildHeight) / 2, width, ((height) + scaledChildHeight) /2);
        }

    }

}

public void surfaceCreated(SurfaceHolder holder) {
    try {
        if(mCamera != null) {
            mCamera.setPreviewDisplay(holder);
        }
    }
    catch (IOException exception) {

    }
}

Camera.PreviewCallback mPreviewCallback = new Camera.PreviewCallback() {


                public void onPreviewFrame(byte[] data, Camera camera) {
                    //test1 = 8889898;
                    //throw new UnsupportedOperationException("Not supported yet.");
                    int ARRAY_LENGTH = mPreviewSize.width*mPreviewSize.height*3/2;
                    int argb8888[] = new int[ARRAY_LENGTH];

                    decodeYUV(argb8888, data, mPreviewSize.width, mPreviewSize.height);
                    Bitmap bitmap = Bitmap.createBitmap(argb8888, mPreviewSize.width, mPreviewSize.height, Config.ARGB_8888);

                    FileOutputStream fos;
                    try {
                        fos = new FileOutputStream(String.format("/sdcard/testImage/%d.jpg", System.currentTimeMillis()));


                    BufferedOutputStream bos = new BufferedOutputStream(fos);
                    bitmap.compress(CompressFormat.JPEG, 75, bos);
            try {
                bos.flush();
            } catch (IOException ex) {
                Logger.getLogger(Preview.class.getName()).log(Level.SEVERE, null, ex);
            }
                    bos.close();
                    fos.close();
                    } catch (FileNotFoundException ex) {
                        Logger.getLogger(Preview.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    catch (IOException ex) {
                            Logger.getLogger(Preview.class.getName()).log(Level.SEVERE, null, ex);
                        }

                }
            };

// decode Y, U, and V values on the YUV 420 buffer described as YCbCr_422_SP by Android 
// David Manpearl 081201 
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 surfaceDestroyed(SurfaceHolder holder) {
    if(mCamera != null) {
        mCamera.stopPreview();
    }  
}

private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
    final double ASPECT_TOLERANCE = 0.1;
    double targetRatio = (double)w/h;
    if(sizes==null) {
        return null;
    }
    Size optimalSize = null;
    double minDiff = Double.MAX_VALUE;

    int targetHeight = h;

    for(Size size : sizes) {
        double ratio = (double) size.width/size.height;
        if(Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
        if(Math.abs(size.height - targetHeight) < minDiff) {
            optimalSize = size;
            minDiff = Math.abs(size.height - targetHeight);
        }
    }

    if(optimalSize == null) {
        minDiff = Double.MAX_VALUE;
        for (Size size : sizes) {
            if(Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }

        }
    }
    return optimalSize;
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    Camera.Parameters parameters = mCamera.getParameters();
    parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
    //mCamera.setDisplayOrientation(90);
    requestLayout();
    //mCamera.setPreviewCallback(mPreviewCallback);
    mCamera.setParameters(parameters);
    mCamera.startPreview();
}
}

1 个答案:

答案 0 :(得分:0)

使用相对布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:orientation="horizontal"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:id="@+id/layout">

    <LinearLayout
        android:id="@+id/preview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="horizontal"
        android:visibility="visible"
        android:layout_alignParentTop="true">
    </LinearLayout>

    <Button android:text="Freeze" android:id="@+id/someButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
    </Button>           
</RelativeLayout>

然后在setContentView函数中使用addViewonCreate的组合。

public void onCreate(Bundle savedInstanceState) {
    Log.i(TAG, "onCreate");
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);


    setContentView(R.layout.main);                
    mPreview = new Preview(this);
    LinearLayout ll = (LinearLayout)findViewById(R.id.preview);
    if(ll != null)
    {
        ll.addView(mPreview);
    }

}