2012-09-03 15 views
8

मैं वर्चुअल रियलिटी एप्लिकेशन बना रहा हूं जहां कैमरा चेहरों का पता लगाना चाहिए, उन्हें ढूंढें और कैमरे के पूर्वावलोकन पर अपना स्थान दिखाएं।कैमरा पूर्वावलोकन पर एंड्रॉइड ड्रॉ

मैं यह करने के 3 तरीके का पता है, मैं GLSurfaceView उपयोग करने के लिए जितनी जल्दी संभव (according to this post) होना चाहते हैं, लेकिन वर्तमान में मैं ही SurfaceView जहां कैमरे के लिए उपयोग कर रहा है पर आकर्षित करने के लिए कोशिश कर रहा हूँ इसका पूर्वावलोकन उस पर आकर्षित करने के लिए मेरे कॉलबैक तो जैसे onFaceDetection होगा:

public class MyActivity extends Activity implements SurfaceHolder.Callback, Camera.FaceDetectionListener { 
    Camera camera; 
    SurfaceView svPreview; 
    SurfaceHolder previewHolder; 
    TextView tvInfo; 
    Paint red; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     svPreview = (SurfaceView) findViewById(R.id.svPreview); 
     tvInfo = (TextView) findViewById(R.id.tvInfo); 

     red = new Paint(); 
     red.setStyle(Paint.Style.STROKE); 
     red.setStrokeWidth(3); 

     previewHolder = svPreview.getHolder(); 
     previewHolder.addCallback(this); 
     previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    } 

    public void surfaceCreated(SurfaceHolder arg0) { 
     camera = Camera.open(); 
     try { 
      camera.setDisplayOrientation(90); 
      camera.setFaceDetectionListener(this); 
      camera.setPreviewDisplay(previewHolder); 
     } 
     catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
     // . . . 
     camera.startPreview(); 
     camera.autoFocus(null); 
     camera.startFaceDetection(); 
    } 

    public void surfaceDestroyed(SurfaceHolder arg0) { 
     camera.stopFaceDetection(); 
     camera.cancelAutoFocus(); 
     camera.stopPreview(); 
     camera.release(); 
     camera = null; 
    } 

    public void onFaceDetection(Face[] faces, Camera camera) { 
     tvInfo.setText("Faces: " + String.valueOf(faces.length)); 

     Canvas canvas = previewHolder.lockCanvas(); 
     for(int i=0; i < faces.length; i++) { 
      Point leftEye = faces[i].leftEye; 
      Point rightEye = faces[i].rightEye; 
      // this is not working 
      canvas.drawPoint(leftEye.x, leftEye.y, red); 
     } 
     previewHolder.unlockCanvasAndPost(canvas); 
    } 
} 
इस कोड मैं इस त्रुटि प्राप्त हो रही के साथ

:

09-03 19:35:42.743: E/SurfaceHolder(19394): Exception locking surface 
09-03 19:35:42.743: E/SurfaceHolder(19394): java.lang.IllegalArgumentException 
09-03 19:35:42.743: E/SurfaceHolder(19394):  at android.view.Surface.lockCanvasNative(Native Method) 
09-03 19:35:42.743: E/SurfaceHolder(19394):  at android.view.Surface.lockCanvas(Surface.java:76) 
09-03 19:35:42.743: E/SurfaceHolder(19394):  at android.view.SurfaceView$4.internalLockCanvas(SurfaceView.java:744) 
09-03 19:35:42.743: E/SurfaceHolder(19394):  at android.view.SurfaceView$4.lockCanvas(SurfaceView.java:720) 
09-03 19:35:42.743: E/SurfaceHolder(19394):  at com.bluetooth.activities.MyActivity.onFaceDetection(MyActivity.java:90) 
09-03 19:35:42.743: E/SurfaceHolder(19394):  at android.hardware.Camera$EventHandler.handleMessage(Camera.java:729) 
09-03 19:35:42.743: E/SurfaceHolder(19394):  at android.os.Handler.dispatchMessage(Handler.java:99) 
09-03 19:35:42.743: E/SurfaceHolder(19394):  at android.os.Looper.loop(Looper.java:137) 
09-03 19:35:42.743: E/SurfaceHolder(19394):  at android.app.ActivityThread.main(ActivityThread.java:4424) 
09-03 19:35:42.743: E/SurfaceHolder(19394):  at java.lang.reflect.Method.invokeNative(Native Method) 
09-03 19:35:42.743: E/SurfaceHolder(19394):  at java.lang.reflect.Method.invoke(Method.java:511) 
09-03 19:35:42.743: E/SurfaceHolder(19394):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 
09-03 19:35:42.743: E/SurfaceHolder(19394):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 
09-03 19:35:42.743: E/SurfaceHolder(19394):  at dalvik.system.NativeStart.main(Native Method) 
09-03 19:35:42.743: W/dalvikvm(19394): threadid=1: thread exiting with uncaught exception (group=0x40a561f8) 
09-03 19:35:42.766: E/AndroidRuntime(19394): FATAL EXCEPTION: main 
09-03 19:35:42.766: E/AndroidRuntime(19394): java.lang.IllegalArgumentException 
09-03 19:35:42.766: E/AndroidRuntime(19394): at android.view.Surface.unlockCanvasAndPost(Native Method) 
09-03 19:35:42.766: E/AndroidRuntime(19394): at android.view.SurfaceView$4.unlockCanvasAndPost(SurfaceView.java:775) 
09-03 19:35:42.766: E/AndroidRuntime(19394): at com.bluetooth.activities.MyActivity.onFaceDetection(MyActivity.java:99) 
09-03 19:35:42.766: E/AndroidRuntime(19394): at android.hardware.Camera$EventHandler.handleMessage(Camera.java:729) 
09-03 19:35:42.766: E/AndroidRuntime(19394): at android.os.Handler.dispatchMessage(Handler.java:99) 
09-03 19:35:42.766: E/AndroidRuntime(19394): at android.os.Looper.loop(Looper.java:137) 
09-03 19:35:42.766: E/AndroidRuntime(19394): at android.app.ActivityThread.main(ActivityThread.java:4424) 
09-03 19:35:42.766: E/AndroidRuntime(19394): at java.lang.reflect.Method.invokeNative(Native Method) 
09-03 19:35:42.766: E/AndroidRuntime(19394): at java.lang.reflect.Method.invoke(Method.java:511) 
09-03 19:35:42.766: E/AndroidRuntime(19394): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 
09-03 19:35:42.766: E/AndroidRuntime(19394): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 
09-03 19:35:42.766: E/AndroidRuntime(19394): at dalvik.system.NativeStart.main(Native Method) 

वहाँ कैमरा एक ही पर इसके पूर्वावलोकन आकर्षित करने के लिए कोशिश कर रहा है के साथ एक समस्या है सतह चेहरा पहचान कॉलबैक देखें? SurfaceViews को बिना रखे मैं इसे कैसे कर सकता हूं?

+0

मैंने इस पर एक बाउंटी जोड़ा क्योंकि एंड्रॉइड स्रोत में खुदाई से ऐसा लगता है कि पूर्वावलोकन बाकी ऐप की तुलना में एक अलग थ्रेड पर चलता है, जिसका मेरा मानना ​​है कि आपका ऐप कैनवास ऑब्जेक्ट नहीं ले सकता है, या लॉक सतह, क्योंकि वे अलग धागे हैं। उस ने कहा, मैं उम्मीद कर रहा हूं कि जिसने इसका सामना किया है, वह –

+0

पारदर्शी पृष्ठभूमि के साथ इन सभी विचारों के शीर्ष पर फ़्रेमलेआउट का उपयोग करने के बारे में बताएगा! – Shafi

उत्तर

6

आप एक SurfaceView पर lock और ड्रॉ नहीं कर सकते हैं जिसमें Type.PUSH_BUFFERS है, (जिसे आप फ्रेम प्रदर्शित कर रहे हैं)। आपको ज़ेड दिशा में अपने मूल के ऊपर एक और दृश्य बनाना होगा और उस दृश्य में SurfaceView पर आकर्षित करना होगा।

तो आपके main.xml में फ़्रेमलेआउट में आपके मूल दृश्य के नीचे एक कस्टम दृश्य बनाएं।

अपनी गतिविधि दृश्य में SurfaceView बनाएं और प्रबंधित करें। इस दृश्य को कैमरा पूर्वावलोकन डिस्प्ले में जोड़ें। SurfaceHolder को पारित करने के अपने कस्टम दृश्य को शुरू करें। इस दृश्य में कैनवास पर लॉक और ड्रॉ कर सकते हैं।

-1

मैंने कहा सकता है,

यह एक थ्रेड के बारे में नहीं है।

यह इस लाइन की वजह से त्रुटि उत्पन्न करता है।

canvas.drawPoint(leftEye.x, leftEye.y, red); 

यह क्योंकि कैनवास अभी भी उपयोग कर रहा है और यह

को लॉक नहीं कर सकते हैं कि आप ध्यान से जांच की, तो आप इस कैनवास आपको मिल देखेंगे == बातिल

canvas = canvasHolder.lockCanvas(); 
    if (canvas == null) Log.i("Error", "Canvas == null!"); 

आप हो सकता है है प्रश्न तो यह पहले से ही कहां उपयोग कर रहा है?

यह पहले से ही यह दिखाने के लिए उपयोग करता है कि आप क्या चल रहे हैं! यही कारण है कि

camera.setPreviewDisplay(previewHolder); 

है तो, मेरा सुझाव है, तो आप अपने आंखों पर प्वाइंट आकर्षित करने के लिए चाहते हैं, तो आप पूर्वावलोकन कैमरे के लिए अधिक आप SurfaceView एक और SurfaceView/SurfaceHolder की आवश्यकता हो सकती है:]

5

के रूप में जेम्स बाहर आप इशारा किया जो SurfaceView फैली कस्टम सतह बनाने की जरूरत (मैं आमतौर पर भी SurfaceHolder.Callback लागू):

public class CameraSurfacePreview extends SurfaceView implements SurfaceHolder.Callback

कुछ

निर्माता हो जाएगा की तरह:

public CameraSurfacePreview(Context context) { 
    super(context); 
    ... 
    mHolder = getHolder(); 
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    ... 

कैमरे के खुले कॉल के बाद आपको अपनी सतह के साथ कैमरा बांधना होगा (यदि आप सरफेसहोल्डर लागू करते हैं।

mCamera = Camera.open(); 
mCamera.setPreviewDisplay(mHolder); 

अंत में आप गतिविधि सामग्री ध्यान में रखते हुए अपने कस्टम सतह somehere के कहने जोड़ने की जरूरत: कॉलबैक अधिरोहित surfaceCreated अंदर इस कहीं) डाल

CameraSurfacePreview cameraSurfacePreview = new CameraSurfacePreview(this); 
//camera surface preview is first child! 
((ViewGroup)findViewById(R.id.cameraLayout)).addView(cameraSurfacePreview, 0); 

गतिविधि के लिए मेरी उदाहरण लेआउट में (मैं तरह दिखता है

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
       android:layout_width="fill_parent"   
         android:layout_height="fill_parent" 
       android:layout_gravity="top|left" 
       android:id="@+id/cameraLayout"> 
0

lockcanvas/unlockcanvasandpost दृष्टिकोण जब ope के रूप में OpenGL का उपयोग उचित नहीं है: मुख्य फ्रेम लेआउट में कैमरा पूर्वावलोकन) दिखा रहा एनजीएल कोड सतह को नियंत्रित और लॉक कर रहा है। यदि आप मानक 2 डी एपीआई का उपयोग करना चाहते हैं, तो OpenGL का उपयोग न करें।

संबंधित मुद्दे