2013-01-19 12 views
13

Fotoğraf makinenizle ilgili bir sorunum var. OnPreviewFrame'de resim çekmek istiyorum ama asla denemez. Bir kamera açtım, önizleme Ekranı ayarla ve Geri arama önizleme ama hiçbir şey. Sadece yanlış olduğumu anlamak istiyorum. 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 diğer cihazlar (telefonlar HTS ve Sony Xperia) Bu kodu çalıştı ve her şey iyi çalıştı. Ama tabletimde çalışmıyor. Kafam karıştı.

cevap

0

Düşük güçlü aygıtlar için daha düşük önizleme çözünürlüğü ayarlamanız gerekebilir. Yüzey görünümü boyutunuzu 320x240 değerine ayarlamak kameranın kendisinin önizleme çözünürlüğünü etkilemez, Önizleme çözünürlüğü açıkça ayarlanmalıdır. Böyle bir şey deneyebilirsiniz:

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

Ben surfaceChanged içine surfaceCreated kodu hareketli öneriyoruz, sen onCreate sırasında önizleme Yüzeyin düzenini geçersiz konum özellikle de (initialize içinde()).

Genel olarak, yüzeye bir boyut değişikliği olduğunda her zaman çağrılacağından, genellikle SurfaceChanged'e yanıt vermek daha güvenlidir. Muhtemelen SurfaceChanged'de önizleme çalıştırıp çalıştırmadığınızı kontrol etmelisiniz.

Diğerlerinin dediği gibi, önizleme yüzeyinin boyutu, önizleme geri çağrımında aldığınız önizleme tamponlarının boyutunu belirlemez; O setPreviewSize yöntemiyle belirlenen ve siz sadece surfaceCreated içinde, surfaceChanged yönteminde setPreviewCallback aramaya

Camera.Parameters.getSupportedPreviewSizes(). 
2

Sen gerekir aldığım desteklenen önizleme boyutları listesinden bir değer kullanmak zorunda bulunuyor. Bu benim ana CameraActivity.java geçerli:

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

} 

Ve bu benim CameraPreview.java geçerli:

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

okuyucu ve ZXing şeyleri görmezden, bu qr tespiti üzerine gösteri düzenleri için kavramı bir kanıt öyle ZXing kütüphanesi.

Bu, StackOverflow'taki kod hatalarını ararken karışık bir çözüm bulundu. Ben bazen bu soruna ve benim için çözümü ile mücadele edilmiştir

+0

Önizleme oluşturulduğundan bu yana hiçbir zaman değişmedi. – Rayz

+1

SurfaceChanged'e geçmek için tavsiye hakkında @Eddy cevabına bakın. Tüm çalışma kodumu gösteren cevabımı düzenlerim. – Neonigma

+0

@Neonigma u bana yardım edebilirsiniz nasıl birden fazla framelayouts canlı önizleme gösterebilir .... i ikinci framelayouts benim canlı kamera önizleme göstermek başarısız oldu – Erum

14

SurfaceView.surfaceChanged sadece Camera.setPreviewDisplay sonra Camera.setPreviewCallback aramak oldu:

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

Ben setPreviewCallback başarısız olabilir fark sayısız makalenin okunması kameranın tamamen başlatılmış bir SurfaceHolder yoksa.

Umarız bu yardımcı olur ...

+0

Sup'b Works Fine.Thanks –