我无法弄清楚为什么此代码不会在Android中显示图像

时间:2010-07-16 19:49:59

标签: android image bitmap

我非常关注TicTacToeLib资源中的示例代码,以及如何在名为Android Application Development的书中显示位图的示例。我正在做他们正在做的所有相同的事情,唯一的区别是我使用的是SurfaceView而不是视图。谁能告诉我我做错了什么?最终目标是手动显示相机的预览图像,并在其上方显示图像。

抱歉,我忘了包含问题所在。 onDraw方法永远不会被调用。而且我的印象是它应该由invalidate方法调用。其次,lockCanvas()方法返回一个NULL画布。即使我修改代码后不使用SurfaceHolder中的PUSH_BUFFER常量(我已编辑了此修正的代码)。

package com.test.combine;

import android.content.res.XmlResourceParser;
import android.app.Activity;
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import java.io.IOException;
import android.util.Log;
import java.util.List;

public class CombineTestActivity extends Activity
{
private Preview mPreview;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Hide the window title.
    requestWindowFeature(Window.FEATURE_NO_TITLE);

    // Create our Preview view and set it as the content of our activity.
    mPreview = new Preview(this);
    setContentView(mPreview);
}

 }

// ----------------------------------------------------------------------

class Preview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
private Paint mPaint;
private Canvas canvas;
private Bitmap currentprev;
private Picture mPicture;

private Camera.PreviewCallback mPrevCallback = new Camera.PreviewCallback() 
{
        public void onPreviewFrame( byte[] data, Camera Cam ) {
                Log.d("CombineTestActivity", "Preview registered");
                Log.d("CombineTestActivity", "Data length = " 
                        + data.length );
               // currentprev = BitmapFactory.decodeByteArray( data, 0, 
               //       data.length );

               currentprev = BitmapFactory.decodeResource( getResources(),
                   R.drawable.creature00 );
               if( currentprev == null )
                   Log.d("CombineTestActivity", "currentprev is null" );

                Log.d("CombineTestActivity", "Preview Finished" );
                invalidate();
        }
};

private OnTouchListener mCorkyListener = new OnTouchListener() {
        public boolean onTouch(View v, MotionEvent me) {
                Log.d("CombineTestActivity", "touch registered" );
                mCamera.takePicture( null, null, mPicCallback );
                return false;
        }
};

private Camera.PictureCallback mPicCallback = new Camera.PictureCallback() {
        public void onPictureTaken( byte[] data, Camera mCamera ) {

                Log.d("CombineTestActivity", "picture method run" );
        }
};

Preview(Context context) {
    super(context);

    // Install a SurfaceHolder.Callback so we get notified when the
    // underlying surface is created and destroyed.
mPicture = new Picture();
    mHolder = getHolder();
    mHolder.addCallback(this);
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_NORMAL);
    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    canvas = mHolder.lockCanvas();
    if(canvas==null)
        Log.d( "CombineTestActivity", "canvas is null in constructor");

this.setOnTouchListener( mCorkyListener );

invalidate();

}

@Override
protected void onDraw( Canvas mCanvas ) {

        if( mCanvas == null )
                Log.e("CombineTestActivity", "canvas is null" );
        if( currentprev == null ) {
                Log.e("CombineTestActivity", "currentprev is null" );
                return;
        }

        mCanvas.drawBitmap( currentprev, 0.0f, 0.0f, mPaint );

        Log.d("CombineTestActivity", "exiting onDraw" );

}


public void surfaceCreated(SurfaceHolder holder) {
    // The Surface has been created, acquire the camera and tell it where
    // to draw.

    mCamera = Camera.open();
    mCamera.setPreviewCallback( mPrevCallback );

    /*        
    try {
       mCamera.setPreviewDisplay(holder);
    } catch (IOException exception) {
        mCamera.release();
        mCamera = null;
        // TODO: add more exception handling logic here
    }
    */      

}

public void surfaceDestroyed(SurfaceHolder holder) {
    // Surface will be destroyed when we return, so stop the preview.
    // Because the CameraDevice object is not a shared resource, it's very
    // important to release it when the activity is paused.
    mCamera.stopPreview();
   mCamera.release();
    mCamera = null;
}

private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
    final double ASPECT_TOLERANCE = 0.05;
    double targetRatio = (double) w / h;
    if (sizes == null) return null;

    Size optimalSize = null;
    double minDiff = Double.MAX_VALUE;

    int targetHeight = h;

    // Try to find an size match aspect ratio and size
    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);
        }
    }

    // Cannot find the one match the aspect ratio, ignore the requirement
    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) {
    // Now that the size is known, set up the camera parameters and begin
    // the preview.
    Camera.Parameters parameters = mCamera.getParameters();

    List<Size> sizes = parameters.getSupportedPreviewSizes();
    if( sizes.isEmpty() )
        Log.d( "CameraTestActivity", "sizes null");
    else
        Log.d( "CameraTestActivity", "sizes not null"); 

    Size optimalSize = getOptimalPreviewSize(sizes, w, h);
    if( optimalSize == null )
        Log.d( "CameraTestActivity", "optimalSize null");
    else
        Log.d( "CameraTestActivity", "optimalSize not null");


    parameters.setPreviewSize(optimalSize.width, optimalSize.height);

if( parameters == null )
    Log.d( "CameraTestActivity", "parameters null" );
else
    Log.d( "CameraTestActivity", "parameters not null" );

    mCamera.setParameters(parameters);
    mCamera.startPreview();
}


}

1 个答案:

答案 0 :(得分:0)

我显然找到了解决方案。虽然SurfaceView继承自View,但它并不像View那样调用onDraw。至于为什么lockCanvas不工作,我仍然不知道。