无法在(相机)SurfaceView上更新ImageView

时间:2013-10-31 12:02:51

标签: android imageview android-camera surfaceview

在我的Android应用中,有一个Activity显示了一个Camera预览,使用此处的文档实现为SurfaceView:http://developer.android.com/guide/topics/media/camera.html#custom-camera

我想从一开始就在此SurfaceView上显示一个ImageView,但我还想在用户拍摄第一张照片时更新其布局(宽度,高度和源图像)。 我的问题是代码在第一步工作,当Activity启动时,图像显示在SurfaceView上,但是当我想要时它的布局不会改变。

这是XML:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/layout_capture"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".CaptureActivity" >

    <RelativeLayout
        android:id="@+id/camera_preview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
    >
            <!-- Here I will programmatically add the SurfaceView -->

        <ImageView
            android:id="@+id/image_picture"
            android:layout_width="100dp"
            android:layout_height="80dp"
            android:layout_centerInParent="true"
            android:contentDescription="picture preview"
            android:src="@drawable/image1" />

    </RelativeLayout>

    <Button
      android:id="@+id/button_capture"
      android:text="Capture"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_gravity="bottom|center"
    />


</FrameLayout>

使用此代码段添加SurfaceView:

mPreview = new CameraPreview(this, mCamera);
RelativeLayout preview = (RelativeLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview, 0); //

这是应该更新ImageView的代码(它在onPictureTaken()方法中)...但它不起作用:

LayoutInflater linf = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
FrameLayout frame = (FrameLayout) linf.inflate(R.layout.activity_capture, null);
ImageView imgw = (ImageView) frame.findViewById(R.id.image_left_picture); // get the ImageView

imgw.setImageResource(R.drawable.image2); // change its source image        
imgw.setLayoutParams(new RelativeLayout.LayoutParams(w, h)); //change its size

invalidate(); // also tried to add this method call... nothing changes.

2 个答案:

答案 0 :(得分:0)

试试这个...它对你有帮助......

public class CameraActivity extends Activity implements PictureCallback{

protected static final String EXTRA_IMAGE_PATH = "com.blundell.tut.cameraoverlay.ui.CameraActivity.EXTRA_IMAGE_PATH";
 ImageView img;
private Camera camera;
private CameraPreview cameraPreview;
int windowwidth;
int windowheight;

@SuppressWarnings("unused")
private LayoutParams layoutParams;

@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_camera);


     windowwidth = getWindowManager().getDefaultDisplay().getWidth();
     windowheight = getWindowManager().getDefaultDisplay().getHeight();
    img=(ImageView) findViewById(R.id.img);
    img.setImageResource(R.drawable.img1);


    setResult(RESULT_CANCELED);
    // Camera may be in use by another activity or the system or not available at all
    camera = getCameraInstance();
    if(cameraAvailable(camera)){
        initCameraPreview();
    } else {
        finish();
    }
}

// Show the camera view on the activity
private void initCameraPreview() {
    cameraPreview = (CameraPreview) findViewById(R.id.camera_preview);
    cameraPreview.init(camera);
    cameraPreview.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // TODO Auto-generated method stub
            LayoutParams layoutParams = (LayoutParams) img
                    .getLayoutParams();
      switch (event.getAction()) {
      case MotionEvent.ACTION_DOWN:
             break;
      case MotionEvent.ACTION_MOVE:
             int x_cord = (int) event.getRawX();
             int y_cord = (int) event.getRawY();

             if (x_cord > windowwidth) {
                    x_cord = windowwidth;
             }
             if (y_cord > windowheight) {
                    y_cord = windowheight;
             }

             layoutParams.leftMargin = x_cord - 25;
             layoutParams.topMargin = y_cord - 75;

             img.setLayoutParams(layoutParams);
             break;
      default:
             break;
      }
      return true;
        }
    });
}

@FromXML
public void onCaptureClick(View button){
    // Take a picture with a callback when the photo has been created
    // Here you can add callbacks if you want to give feedback when the picture is being taken
    camera.takePicture(null, null, this);
}

@Override
public void onPictureTaken(byte[] data, Camera camera) {
    Log.d("Picture taken");
    String path = savePictureToFileSystem(data);
    setResult(path);
    finish();
}

private static String savePictureToFileSystem(byte[] data) {
    File file = getOutputMediaFile();
    saveToFile(data, file);
    return file.getAbsolutePath();
}

private void setResult(String path) {
    Intent intent = new Intent();
    intent.putExtra(EXTRA_IMAGE_PATH, path);
    setResult(RESULT_OK, intent);
}

// ALWAYS remember to release the camera when you are finished
@Override
protected void onPause() {
    super.onPause();
    releaseCamera();
}

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

}

和Camera Preiew ...

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {

private Camera camera;

private SurfaceHolder holder;

public CameraPreview(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

public CameraPreview(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public CameraPreview(Context context) {
    super(context);
}

public void init(Camera camera) {
    this.camera = camera;
    initSurfaceHolder();
}

@SuppressWarnings("deprecation") // needed for < 3.0
private void initSurfaceHolder() {
    holder = getHolder();
    holder.addCallback(this);
    holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    initCamera(holder);

}

private void initCamera(SurfaceHolder holder) {
    try {
        camera.setPreviewDisplay(holder);
        camera.startPreview();
    } catch (Exception e) {
        Log.d("Error setting camera preview", e);
    }
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}

}

答案 1 :(得分:0)

我认为问题是:

FrameLayout frame = (FrameLayout) linf.inflate(R.layout.activity_capture, null);

您是否已将此布局添加到视图组?我没看到你的代码。你刚刚给它充气并在这个布局中设置了图像视图。