2013-01-19 26 views
13

カメラに問題があります。私はonPreviewFrameで画像を取得したいですが、決して呼び出されません。私はカメラを開いてプレビューを設定し、コールバックをプレビューしますが、何も表示しません。私はちょうど私が間違っていた場所を理解したい。Android onPreviewFrameが呼び出されていません

public class VideoCall extends Activity implements View.OnClickListener, Callback, PreviewCallback 
{ 

    TabHost thVideoChat; 
    Button btnVideoUp, btnVideoDown; 
    Handler uiHandler; 
    SurfaceView videoPrev; 
    SurfaceHolder surfaceHolder; 
    Camera camera; 

    Timer timer; 
    boolean getPic; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.a_video); 
     initialize(); 

     Log.d("RAYZ", "onCreate"); 
    } 

    private void initialize() 
    { 

     thVideoChat = (TabHost) findViewById(R.id.thVideoChat); 
     thVideoChat.setup(); 

     TabSpec specs = thVideoChat.newTabSpec("1"); 
     specs.setContent(R.id.tabVideo); 
     specs.setIndicator("Видео", getResources().getDrawable(R.drawable.mcam)); 
     thVideoChat.addTab(specs); 

     specs = thVideoChat.newTabSpec("2"); 
     specs.setContent(R.id.tabChat); 
     specs.setIndicator("Чат", getResources().getDrawable(R.drawable.mchat)); 
     thVideoChat.addTab(specs); 

     btnVideoUp = (Button) findViewById(R.id.btnVideoUp); 
     btnVideoDown = (Button) findViewById(R.id.btnVideoDown); 
     btnVideoUp.setOnClickListener(this); 
     btnVideoDown.setOnClickListener(this); 

     videoPrev = (SurfaceView) findViewById(R.id.videoPrev); 

     if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) 
     { 

      LayoutParams lp = videoPrev.getLayoutParams(); 
      lp.height = 320; 
      lp.width = 240; 
      videoPrev.setLayoutParams(lp); 

     } 
     else 
     { 
      LayoutParams lp = videoPrev.getLayoutParams(); 
      lp.height = 240; 
      lp.width = 320; 
      videoPrev.setLayoutParams(lp); 
     } 

     surfaceHolder = videoPrev.getHolder(); 
     surfaceHolder.addCallback(this); 
     surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 

     uiHandler = new Handler(); 
     getPic = false; 
    } 

    @Override 
    protected void onPause() 
    { 
     Log.d("RAYZ", "onPause"); 
     if (camera != null) 
     { 
      camera.setPreviewCallback(null); 
      camera.stopPreview(); 
      camera.release(); 
      camera = null; 
     } 
     if (timer != null) 
     { 
      timer.cancel(); 
     } 
     super.onPause(); 
    } 

    @Override 
    protected void onResume() 
    { 
     super.onResume(); 
     camera = Camera.open(); 
    } 

    @Override 
    public void onClick(View v) 
    { 
     switch (v.getId()) 
     { 
      case R.id.btnVideoUp: 
      { 
       btnVideoUp.setEnabled(false); 
       btnVideoDown.setEnabled(true); 

       timer = new Timer(); 

       Log.d("RAYZ", "G_BTN"); 

       timer.schedule(new TimerTask() 
       { 

        @Override 
        public void run() 
        { 
         uiHandler.post(new Runnable() 
         { 

          @Override 
          public void run() 
          { 
           getPic = true; 
          } 
         }); 
        } 
       }, 0L, 1L * 500L); 

       break; 
      } 
      case R.id.btnVideoDown: 
      { 
       btnVideoUp.setEnabled(true); 
       btnVideoDown.setEnabled(false); 
       Log.d("RAYZ", "R_BTN"); 
       timer.cancel(); 
       timer = null; 
       break; 
      } 
      default: 
       break; 
     } 

    } 

    @Override 
    public void onPreviewFrame(byte[] data, Camera camera) 
    { 
     Log.d("RAYZ", "getPic"); 
     // if (getPic) 
     // { 

     // } 

    } 

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

    } 

    @Override 
    public void surfaceCreated(SurfaceHolder holder) 
    { 

     try 
     { 

      camera.setPreviewDisplay(holder); 
      camera.setPreviewCallback(this); 
      camera.startPreview(); 
     } 
     catch (IOException e) 
     { 
      e.printStackTrace(); 
     } 

    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) 
    { 

    } 

} 

は2つの他のデバイス(携帯電話のHTSとソニーのXperia)でこのコードを試してみましたが、すべてがうまく働きました。しかし、私のタブレットでは動作しません。よくわかりません。

答えて

0

低消費電力デバイスのプレビュー解像度を低く設定する必要がある場合があります。サーフェイスビューのサイズを320x240に設定しても、カメラ自体のプレビュー解像度には影響しません。プレビュー解像度は明示的に設定する必要があります。あなたはこのような何かを試してみてください:

List<Camera.Size> resList = camera.getParameters().getSupportedPreviewSizes(); 
int w=0, h=0; 
final int desiredRes_W = 176; 
for (Camera.Size size : resList) { 
    // find a supported res nearest to desired_Res 
    if (w==0) { 
     w = size.width; 
     h = size.height; 
    } 
    else if (size.width >= desiredRes_W && size.width <= w ) { 
     w=size.width; 
     h = size.height; 
    } 
} // 176x144, 320x240 ... 
Parameters par = camera.getParameters(); 
par.setPreviewSize(w, h); 
// ALSO set width/height of the SurfaceView to the same aspect ratio. 
camera.setParameters(par); 
camera.setPreviewDisplay(holder); 
4

私はあなたのonCreate(初期化中())の間にプレビュー面のレイアウトをオーバーライドしている、特に以来、surfaceChangedにsurfaceCreatedにコードを移動お勧めします。

サーフェスにサイズ変更があるたびに呼び出されるため、通常はsurfaceChangedに応答する方が安全です。おそらく、すでにsurfaceChangedでプレビューが実行されているかどうかを確認する必要があります。

プレビューサーフェスのサイズは、プレビューコールバックで受け取るプレビューバッファのサイズを決定しません。それはsetPreviewSizeメソッドによって設定され、あなたはあなたがsurfaceCreatedだけでなく、surfaceChanged方法でsetPreviewCallbackを呼び出すために必要

Camera.Parameters.getSupportedPreviewSizes(). 
2

から取得サポートプレビューサイズのリストから値を使用する必要があります。これは私のメインのCameraActivity.javaです:

package com.example.cameraview; 

import java.util.Hashtable; 

import android.app.Activity; 
import android.hardware.Camera; 
import android.hardware.Camera.Size; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.widget.FrameLayout; 
import android.widget.ImageView; 

import com.google.zxing.BinaryBitmap; 
import com.google.zxing.DecodeHintType; 
import com.google.zxing.MultiFormatReader; 
import com.google.zxing.NotFoundException; 
import com.google.zxing.PlanarYUVLuminanceSource; 
import com.google.zxing.Result; 
import com.google.zxing.common.HybridBinarizer; 

public class CameraActivity extends Activity implements Camera.PreviewCallback { 

    private Camera mCamera; 
    private CameraPreview mPreview; 

    private Result result; 
    private MultiFormatReader reader; 

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

     reader = new MultiFormatReader(); 
     Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>(); 
     hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE); 
     reader.setHints(hints); 

    // Create an instance of Camera 
    mCamera = getCameraInstance(); 

    // Create our Preview view and set it as the content of our activity. 
    mPreview = new CameraPreview(this, mCamera); 
    FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview); 
    preview.addView(mPreview); 
    } 

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

     if (mCamera != null) { 
      mCamera.setPreviewCallback(null); 
      mPreview.getHolder().removeCallback(mPreview); 
      mCamera.release(); 
     } 
    } 

    /** A safe way to get an instance of the Camera object. */ 
    public static Camera getCameraInstance(){ 
    Camera c = null; 
    try { 
     c = Camera.open(); // attempt to get a Camera instance 
    } 
    catch (Exception e){ 
     // Camera is not available (in use or does not exist) 
    } 
    return c; // returns null if camera is unavailable 
    } 

    public void onPreviewFrame(byte[] data, Camera camera) { 
    Size size = mCamera.getParameters().getPreviewSize(); 
     PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(data, size.width, size.height, 0, 0, size.width, size.height, false); 
     HybridBinarizer hybBin = new HybridBinarizer(source); 
     BinaryBitmap bitmap = new BinaryBitmap(hybBin); 

    ImageView myImage = (ImageView) findViewById(R.id.foto); 

     try { 
      result = reader.decode(bitmap); 
     Log.d("Result", "Result found!: " + String.valueOf(result)); 

     myImage.setVisibility(View.VISIBLE); 

     if (String.valueOf(result).contentEquals("1")) 
      myImage.setImageResource(R.drawable.juan); 
     else if (String.valueOf(result).contentEquals("2")) 
      myImage.setImageResource(R.drawable.antonio); 

     } catch (NotFoundException e1) { 

      if (myImage != null) 
     myImage.setVisibility(View.INVISIBLE); 

     Log.d("NotFoundException", "NotFoundException"); 
     } finally { 
     reader.reset(); 
     } 
    } 

} 

そして、これが私のCameraPreview.javaです:

package com.example.cameraview; 

import java.io.IOException; 
import java.util.List; 

import android.content.Context; 
import android.hardware.Camera; 
import android.hardware.Camera.PreviewCallback; 
import android.hardware.Camera.Size; 
import android.hardware.Camera.Parameters; 
import android.util.Log; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 


/** A basic Camera preview class */ 
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { 
    private SurfaceHolder mHolder; 
    private Camera mCamera; 
    private String TAG = "CameraPreview"; 
    private Context context; 

    @SuppressWarnings("deprecation") 
    public CameraPreview(Context context, Camera camera) { 
    super(context); 
    mCamera = camera; 
    this.context = context; 

    // Install a SurfaceHolder.Callback so we get notified when the 
    // underlying surface is created and destroyed. 
    mHolder = getHolder(); 
    // deprecated setting, but required on Android versions prior to 3.0 
    mHolder.addCallback(this); 
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    } 

    public void surfaceCreated(SurfaceHolder holder) { 
    // The Surface has been created, now tell the camera where to draw the preview. 
    try { 
     mCamera.setPreviewDisplay(holder); 
     mCamera.startPreview(); 

    } catch (NullPointerException e) { 
     Log.d(TAG, "Error setting camera preview - nullpointerexception: " + e.getMessage()); 
    } catch (IOException e) { 
     Log.d(TAG, "Error setting camera preview: " + e.getMessage()); 
    } 
    } 

    public void surfaceDestroyed(SurfaceHolder holder) { 
    // empty. Take care of releasing the Camera preview in your activity. 
    } 

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
    // If your preview can change or rotate, take care of those events here. 
    // Make sure to stop the preview before resizing or reformatting it. 

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

    // stop preview before making changes 
    try { 
     mCamera.stopPreview(); 
    } catch (Exception e){ 
     // ignore: tried to stop a non-existent preview 
    } 

    // set preview size and make any resize, rotate or 
    // reformatting changes here 

    // start preview with new settings 
    try { 
     Parameters parameters = mCamera.getParameters(); 

     List<Size> sizes = parameters.getSupportedPreviewSizes(); 
     Size optimalSize = getOptimalPreviewSize(sizes, w, h); 
     parameters.setPreviewSize(optimalSize.width, optimalSize.height); 

     if (context.getPackageManager().hasSystemFeature("android.hardware.camera.autofocus")) 
      parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); 

     mCamera.setParameters(parameters); 

     mCamera.setPreviewCallback((PreviewCallback) context); 
     mCamera.setPreviewDisplay(mHolder); 
     mCamera.startPreview(); 

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

    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; 
    } 
} 

がリーダーとzxing事を無視し、それはQR検出オーバーショーのレイアウトのためのコンセプトの証明ではですZXingライブラリ。

これは、StackOverflowで自分のコードエラーを検索している間に見つかった混在した解決策です。

+0

私のプレビューは作成以来変更されていません。 – Rayz

+1

surfaceChangedに移動するための推奨事項について@Eddyの回答を参照してください。すべての作業コードを表示した回答を編集します。 – Neonigma

+0

@Neonigmaは、複数のフレームレートでライブプレビューを表示する方法を教えてくれます....私は2番目のフレームレイアウトでライブカメラのプレビューを表示できませんでした – Erum

14

私はいつかのために、この問題で苦労されていると私のためのソリューションは、ちょうどSurfaceView.surfaceChangedでCamera.setPreviewDisplay後Camera.setPreviewCallbackを呼び出すことだった:

私はsetPreviewCallbackが失敗する可能性が実現し、多くの記事を読んで
public void onCreate(Bundle state) { log("onCreate"); 
    try { 
     super.onCreate(state); 
     setContentView(R.layout.main); 
     text = (TextView) findViewById(R.id.text); 
     surface = (SurfaceView) findViewById(R.id.surface); 
     int type = SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS; 
     surface.getHolder().setType(type);//REQUIRED:API10 
     surface.getHolder().addCallback(this); 
     camera = Camera.open(); 
     camera.setDisplayOrientation(90); // portrait mode only 
    } catch (Exception e) { 
     showException(e); 
    } 
} 


public void surfaceChanged(SurfaceHolder sh, int format, int w, int h) { log("surfaceChanged"); 
    try { 
     camera.stopPreview(); 
     Size s = camera.getParameters().getPreviewSize(); 
     LayoutParams params = surface.getLayoutParams(); 
     params.height = w*s.width/s.height; // portrait mode only 
     surface.setLayoutParams(params); 
     camera.setPreviewDisplay(sh); 
     camera.setPreviewCallback(this); 
     camera.startPreview(); 
    } catch (Exception ex) { 
     showException(ex); 
    } 
} 

カメラが完全に初期化されたSurfaceHolderを持たない場合。

私はこれが役立つことを願っています...

+0

Sup'b Works Fine.Thanks –

関連する問題