2011-06-13 25 views
7

Test uygulamamda bir kamera önizleme ile başlamak için SurfaceView ile SurfaceHolder kullanıyorum.Yüzey tutucusu üzerindeki kam resmi, çiz: Yüzey türü nedeniyle istisna

CameraPreview'ı kullanmak istiyorum (SDK sürüm 7 için SDK Örnekleriyle birlikte gelir). UI'ye bir tıklama bir fotoğraf çeker.

public class Preview extends SurfaceView implements OnClickListener, SurfaceHolder.Callback { 

SurfaceHolder holder; 
Camera cam; 

final static String TAG = "TextLocator:Preview"; 

Preview(Context context) { 
    super(context); 

    holder = getHolder(); 
    holder.addCallback(this); 
    this.setOnClickListener(this); 
    // seems to be required (although the docs state, this enum is deprecated, as the type will be chosen automatically... 
    holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
} 

public void surfaceCreated(SurfaceHolder holder) { 
    cam = Camera.open(); 
    try { 
     Camera.Parameters params = cam.getParameters(); 
     params.set("orientation", "landscape"); 
     Camera.Size bestSize = getBestPreviewSize(480, 320); 
     params.setPreviewSize(bestSize.width, bestSize.height); 
     cam.setParameters(params); 
     // where to draw: 
     cam.setPreviewDisplay(holder); 
    } catch (IOException exception) { 
     cam.release(); 
     cam = null; 
     // TODO: add more exception handling logic here 
    } 
} 

private Camera.Size getBestPreviewSize(int width, int height) 
{ 
    // checks for supported sizes close to the demanded values - implemented. 
} 


public void surfaceDestroyed(SurfaceHolder holder) { 
    cam.stopPreview(); 
    cam.release(); 
    cam = null; 
} 

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
    Camera.Parameters parameters = cam.getParameters(); 
    parameters.setPreviewSize(w, h); 

    cam.setParameters(parameters); 
    cam.startPreview(); 
} 

Camera.PictureCallback picCallback = new Camera.PictureCallback() { 

    public void onPictureTaken(byte[] bytes, Camera arg1) { 
     synchronized(holder) { 
       Canvas c = null;  

       try { 
        c = holder.lockCanvas();     

        Paint paint = new Paint(); 
        paint.setAntiAlias(false); 
        paint.setARGB(200, 120, 180, 0); 

        c.drawLine(10, 10, c.getWidth() - 10, c.getHeight() - 10, paint); 
       } 
       catch (Exception e) { 
        Log.d(TAG, "Exception: " + e.getMessage()); 
        // IllegalArguementException Surface Type is SURFACE_TYPE_PUSH_BUFFERS 
       } 
       finally {  
        holder.unlockCanvasAndPost(c); 
       } 
      } 
    } 
}; 

public void onClick(View v) 
{ 
    cam.takePicture(null, null, picCallback);  
} 

}

Sonraki Ben SurfaceHolder karşılık gelen Canvas için bazı ek resim yapmaya çalışıyorum: Burada Preview sınıfı. Bu yüzden ben canvas = holder.lockCanvas()'u arıyorum. Bu İleti ile IllegalArgumentException sonuçlanacaktır:

Surface type is SURFACE_TYPE_PUSH_BUFFERS 

Şimdi bu Yüzey Tipleri kullanımdan kaldırılmıştır docs devlet olduğunu, değer kümesi

dikkate alınmayacaktır. Ancak, kameranın önizlemesi sadece bu özel değere tip koyarsam çalışır.

SurfaceView'un Canvas numaralı çiziminde nasıl çizilir? Ya da farklı bir katman/görünüm üzerine konmalı mı?

+1

Kapanış sorumu ile ilgili olarak, fazladan bir görünüm kullanmanın ve bunun üzerine çizmenin bir yaklaşımı var. "SurfaceView" öğesinin z sırasını korumak için "RealtiveLayout" veya "FrameLayout" öğelerini kullanıyor ve bu yer paylaşma: http://stackoverflow.com/questions/2933882/how-to-draw-an-overlay-on-a- yüzey görüntülemeli kameralı kamera android – rdoubleui

+0

FYI: Yukarıdaki bağlantıdaki çözüm yardımcı oldu ve bu yaklaşımı kamera önizlemesinin üzerinde ek bir görüntü kullanarak bitirdim. – rdoubleui

cevap

5

Her ikisi de kamera önizlemesini görüntüleyemez ve bir Tuval ile çizemezsiniz. Birini ya da diğerini yapmalısın.

+0

Bu kesinlikle doğru olsa da, bu konuyla ilgili bazı belgelerin nerede bulunabileceğine dair bir ayrıntı mı bulabilirdiniz? Çünkü ben Android'e takıldığım için önizlemenin tamponunu sadece görünümüne yüklerdim ve üzerine çizebilmem gerekirdi. – rdoubleui

+2

SurfaceView kullanıldığında, ilgili Yüzey yalnızca bir tür işleme için kullanılabilir: video, GPU veya yazılım. Bir tür oluşturma seçildiğinde, başka bir tür için kullanılamaz. Her şey bellekteki arabelleklerin biçimi ve belleğin depolandığı yerdir. –

İlgili konular