2014-09-01 6 views
6

अब तक मेरे पास एक पूर्ण कामकाजी कोड है जो कैमरे में सामने वाले कैमरे के पूर्वावलोकन को देखने के लिए प्लग करता है।एक टुकड़े में एंड्रॉइड कैमरा पूर्वावलोकन

मैं अब क्या करने की कोशिश कर रहा हूं वह कैमरा Fragment के अंदर काम कर रहा है।

पूर्ण कोड:

MainActivity.java

public class MainActivity extends Activity { 

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

    setContentView(R.layout.fragment_main); 

    getFragmentManager().beginTransaction().add(R.id.mainLayout, new CameraExtractionFragment()).commit(); 
} 
} 

CameraExtractionFragment.java

public class CameraExtractionFragment extends Fragment { 

private CameraExtraction mCameraExtraction; 
Camera mCamera; 
int mNumberOfCameras; 
int cameraId; 
int rotation; 

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

    mCameraExtraction = new CameraExtraction(
      this.getActivity().getBaseContext(), 
      this.getActivity().getWindowManager().getDefaultDisplay().getRotation() 
      ); 

    // Find the total number of cameras available 
    mNumberOfCameras = Camera.getNumberOfCameras(); 

    // Find the ID of the rear-facing ("default") camera 
    CameraInfo cameraInfo = new CameraInfo(); 
    for (int i = 0; i < mNumberOfCameras; i++) { 
     Camera.getCameraInfo(i, cameraInfo); 
     if (cameraInfo.facing == CameraInfo.CAMERA_FACING_FRONT) { 
      cameraId = i; 
     } 
    } 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)    { 
    return mCameraExtraction; 
} 

@Override 
public void onResume() { 
    super.onResume(); 

    // Use mCurrentCamera to select the camera desired to safely restore 
    // the fragment after the camera has been changed 
    mCamera = Camera.open(cameraId); 
    mCameraExtraction.setCamera(mCamera); 
} 

@Override 
public void onPause() { 
    super.onPause(); 

    if (mCamera != null) 
    { 
     mCamera.release(); 
    } 
} 


// Modo en el que se pinta la cámara: encajada por dentro o saliendo los bordes por fuera. 
public enum CameraViewMode { 

    /** 
    * Inner mode 
    */ 
    Inner, 
    /** 
    * Outer mode 
    */ 
    Outer 
} 
} 

CameraExtraction.java

public class CameraExtraction extends ViewGroup implements SurfaceHolder.Callback { 

private final String TAG = "CameraExtraction"; 

Camera mCamera; 
SurfaceHolder mHolder; 
SurfaceView mSurfaceView; 
int mNumberOfCameras; 
int cameraId; 
Rect desiredSize; 
CameraViewMode cameraViewMode; 
boolean mSurfaceCreated = false; 
List<Size> mSupportedPreviewSizes; 
int rotation; 
Size mPreviewSize; 

public CameraExtraction(Context context, int rotation) { 
    super(context); 

    this.rotation = rotation; 

    mSurfaceView = new SurfaceView(context); 

    addView(mSurfaceView); 

    // Install a SurfaceHolder.Callback so we get notified when the 
    mHolder = mSurfaceView.getHolder(); 
    mHolder.addCallback(this); 
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 

    cameraViewMode = CameraViewMode.Inner; 
} 

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

public void switchCamera(Camera camera) { 
    setCamera(camera); 
    try { 
     camera.setPreviewDisplay(mHolder); 
    } catch (IOException exception) { 
     Log.e(TAG, "IOException caused by setPreviewDisplay()", exception); 
    } 
} 

@SuppressLint("DrawAllocation") 
@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    if (mSurfaceView == null ||mSurfaceView.getHolder() == null) return; 

    if (mSurfaceView.getHolder().getSurface() == null) { 
     // preview surface does not exist 
     return; 
    } 

    final int width = resolveSize(getSuggestedMinimumWidth(), 
      widthMeasureSpec); 
    final int height = resolveSize(getSuggestedMinimumHeight(), 
      heightMeasureSpec); 
    setMeasuredDimension(width, height); 

    if (mSupportedPreviewSizes != null) { 

     mPreviewSize = getNearestPreviewSize(mCamera.new Size(widthMeasureSpec,heightMeasureSpec)); 
    } 

    if (mCamera != null) { 
     Camera.Parameters parameters = mCamera.getParameters(); 
     parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height); 

     mCamera.setParameters(parameters); 
    } 
} 

@Override 
protected void onLayout(boolean changed, int l, int t, int r, int b) { 
    if (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; 
     } 

     // Center the child SurfaceView within the parent. 
     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); 
     } 
    }  
} 

@Override 
public void surfaceCreated(SurfaceHolder holder) { 
    mCamera = Camera.open(cameraId);   
} 

@Override 
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) { 
    if (mSurfaceView == null || mSurfaceView.getHolder() == null) return; 

      if (mSurfaceView.getHolder().getSurface() == null) { 
       // preview surface does not exist 
       return; 
      } 

      // set preview size and make any resize, rotate or 
      // reformatting changes here 
      Camera.Parameters param = mCamera.getParameters(); 
      Point previewSize = new Point(640,480); 

      Camera.Size size = getNearestPreviewSize(mCamera.new Size(previewSize.x,previewSize.y)); 
      param.setPreviewSize(size.width, size.height); 
      mCamera.setParameters(param); 
      rotation = setCameraDisplayOrientation(cameraId, mCamera); 

      // start preview with new settings 
      try { 
       mCamera.setPreviewCallback(new Camera.PreviewCallback() { 

        @Override 
        public void onPreviewFrame(byte[] data, Camera camera) { 
         // TODO Auto-generated method stub 

        } 
       }); 
       mCamera.setPreviewDisplay(mSurfaceView.getHolder()); 
       mCamera.startPreview(); 

      } catch (Exception e) { 
       Log.d("AndroidControlSurfaceView", 
         "Error starting camera preview: " + e.getMessage()); 
      }  
} 

@Override 
public void surfaceDestroyed(SurfaceHolder holder) { 
    if (mCamera != null) 
    { 
     mCamera.stopPreview(); 
     mCamera.release(); 
    } 
} 


protected Rect getCameraViewSizeCompensated(Camera.Size cameraPreviewSize, Point hostViewSize) { 
    Rect toReturn=null; 

    float ratioWidth = hostViewSize.x/(float)cameraPreviewSize.width; 
    float ratioHeight = hostViewSize.y/(float)cameraPreviewSize.height; 

    switch (cameraViewMode){ 
    case Inner: 
     if (ratioWidth < ratioHeight) { 
      int newHeight = (int)(cameraPreviewSize.height*ratioWidth); 
      int y = (hostViewSize.y - newHeight)/2; 
      toReturn = new Rect(0, y, hostViewSize.x, y+newHeight); 
     } else { 
      int newWidth = (int)(cameraPreviewSize.width*ratioHeight); 
      int x = (hostViewSize.x - newWidth)/2; 
      toReturn = new Rect(x, 0, x+newWidth,hostViewSize.y); 
     } 
     break; 
    case Outer: 
     if (ratioWidth < ratioHeight) { 
      int newWidth = (int)(cameraPreviewSize.width*ratioHeight); 
      int x = (hostViewSize.x - newWidth)/2; 
      toReturn = new Rect(x, 0, x+newWidth,hostViewSize.y); 
     } else { 
      int newHeight = (int)(cameraPreviewSize.height*ratioWidth); 
      int y = (hostViewSize.y - newHeight)/2; 
      toReturn = new Rect(0, y, hostViewSize.x, y+newHeight); 
     } 
     break; 
    } 
    return toReturn; 
} 

private Camera.Size getNearestPreviewSize(Camera.Size size) { 
    List<Camera.Size> availableSizes = mCamera.getParameters().getSupportedPreviewSizes(); 
    if (availableSizes == null || availableSizes.size() <= 0) return null; 

    Camera.Size toReturn = availableSizes.get(0); 
    int distance = Math.abs(size.width*size.height - toReturn.width*toReturn.height); 
    for (int a=1; a<availableSizes.size(); a++) { 
     int temp = Math.abs(size.width*size.height - availableSizes.get(a).width*availableSizes.get(a).height); 
     if (temp < distance) { 
      distance = temp; 
      toReturn = availableSizes.get(a); 
     } 
    } 
    return toReturn; 
} 


public int setCameraDisplayOrientation(int cameraId, android.hardware.Camera camera) { 

    CameraInfo info = new Camera.CameraInfo(); 
    Camera.getCameraInfo(cameraId, info); 
    int degrees = 0; 

    switch (rotation) { 
     case Surface.ROTATION_0: degrees = 0; break; 
     case Surface.ROTATION_90: degrees = 90; break; 
     case Surface.ROTATION_180: degrees = 180; break; 
     case Surface.ROTATION_270: degrees = 270; break; 
    } 

    int result; 
    if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 
     result = (info.orientation + degrees) % 360; 
     result = (360 - result) % 360; // compensate the mirror 
    } else { // back-facing 
     result = (info.orientation - degrees + 360) % 360; 
    } 
    camera.setDisplayOrientation(result); 
    return result/90; 
} 

} 

लेकिन जब आप एप्लिकेशन चलाते हैं, तो मेरे डिवाइस में कोई छवि नहीं दिखाई जा रही है। केवल एक सफेद स्क्रीन। ध्यान दें, जैसा कि मैंने का उल्लेख किया है, कैमरा एक गतिविधि में काम कर रहा है जिसमें टुकड़े नहीं हैं।

तो, मुख्य गतिविधि को एक सफेद स्क्रीन के साथ क्यों दिखाया जाता है?

पीएस: Here आप मेरा कोड डाउनलोड कर सकते हैं और इसका परीक्षण कर सकते हैं।

+0

क्या आप अपना कोड यहां पोस्ट कर सकते हैं? आपका लिंक मर चुका है और काम नहीं कर रहा है। – chinmish

उत्तर

4

पहले - अपने कैमरे के पूर्वावलोकन के लिए FrameLayout का उपयोग करें।

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

दूसरा - कैमरा दो बार खोलने की आवश्यकता नहीं है। आपकी surfaceCreated विधि।

@Override 
public void surfaceCreated(SurfaceHolder holder) { 
    try { 
     if (mCamera != null) { 
      mCamera.setPreviewDisplay(holder); 
      mCamera.setPreviewCallback(new Camera.PreviewCallback() { 
       @Override 
       public void onPreviewFrame(byte[] data, Camera camera) { 
       } 
      }); 
     } 
    } catch (IOException exception) { 
     Log.e(TAG, "IOException caused by setPreviewDisplay()", exception); 
    } 
} 

तीसरा - कैमरा दो बार रिलीज़ करने की आवश्यकता नहीं है। आपने इसे फ्रैगमेंट में किया है, इसे surfaceDestroyed से हटा दें।

@Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
     if (mCamera != null) 
     { 
//   mCamera.stopPreview(); 
//   mCamera.release(); 
     } 
    } 

और आपके टुकड़े में।

@Override 
public void onPause() { 
    super.onPause(); 

    if (mCamera != null) 
    { 
     mCamera.stopPreview(); 
     mCamera.release(); 
    } 
} 

और आप अपने कैमरे के पूर्वावलोकन को एक टुकड़े में देखेंगे जो मैं देखता हूं। सौभाग्य!

+0

वास्तव में मदद की! – Sonhja

0

ऐसा लगता है आप CameraExtractionFragment और CameraExtraction में cameraId विशेषता है, लेकिन यह केवल CameraExtractionFragment में एक मूल्य असाइन किया गया है।

आपको CameraExtraction.cameraId को हटा देना चाहिए और इसके बजाय CameraExtractionFragment.cameraId का उपयोग करना चाहिए।

+0

अभी भी सफेद .... – Sonhja

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