2010-07-16 81 views
0

我非常关注TicTacToeLib资源中的示例代码,以及如何在标题为Android应用程序的书中显示位图的示例发展。我正在做同样的事情,唯一的区别是我使用SurfaceView而不是视图。谁能告诉我我做错了什么?最终目标是手动显示相机的预览图像,并在其上显示图像。我不明白为什么这段代码不会在Android中显示图片

对不起,我忘了包括什么问题。 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(); 
} 


} 
+0

运行此代码时会发生什么?只是一个任意猜测,也许你不应该使用SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS。 – 2010-07-16 19:59:40

+0

实际上发生了一些事情(抱歉,我忘了提及它们)。对于一个onDraw永远不会被调用。作为第二个surfaceholder.lockCanvas()返回null。我研究了你推荐的内容,并尝试将该行改为空,而canvas仍然为空。然后我尝试使用SURFACE_TYPE_NORMAL,它仍然是空的。 – RyoxSinfar 2010-07-19 15:29:18

回答

0

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

相关问题