Nov 19, 2014

surfaceview screenshot (camera screenshot)

Surface view often use for Camera preview.

Because Camera preview need many load. 

So, if you capture your phone, camera does'n capture.

May be just black image!!

I tried below image.


But I get just overlay and black display.

So I use camera preview callback!!

First, sufaceview

  1. public class SurfacePreview extends SurfaceView implements SurfaceHolder.Callback{
  2.    
  3.     SurfaceHolder holder;   
  4.     Camera cam=null;       //camera
  5.    
  6.     public SurfacePreview(Context context, AttributeSet attrs) {
  7.         super(context, attrs);
  8.         init(context);
  9.     }
  10.     public SurfacePreview(Context context) {
  11.         super(context);
  12.         init(context);
  13.     }
  14.     public void init(Context context){
  15.        
  16.         holder=getHolder();
  17.         holder.addCallback(this);
  18.         if(Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB)
  19.             getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
  20.        
  21.        
  22.     }
  23.     @Override
  24.     public void surfaceChanged(SurfaceHolder holder, int format, int width,
  25.             int height) {
  26.         cam.setDisplayOrientation(90);      //portrait
  27.         cam.startPreview();                 //preview start
  28.        
  29.     }
  30.     @Override
  31.     public void surfaceCreated(SurfaceHolder holder) {
  32.         cam=Camera.open();                  //open camera object(need camera permission)
  33.         try{
  34.             cam.setPreviewDisplay(holder);  
  35.         }catch(Exception e){
  36.             e.printStackTrace();
  37.         }
  38.     }
  39.     @Override
  40.     public void surfaceDestroyed(SurfaceHolder holder) {
  41.         cam.stopPreview();
  42.         cam.release();                      
  43.         cam=null;
  44.        
  45.     }  
  46. }

This is my old code.

I add implement Camera.PreviewCallback!!

  1. public class SurfacePreview extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback

Add onPreviewFrame method.

  1.     @Override
  2.     public void onPreviewFrame(byte[] data, Camera camera) {
  3.        
  4.         Camera.Parameters params = camera.getParameters();
  5.         int w = params.getPreviewSize().width;
  6.             int h = params.getPreviewSize().height;
  7.             int format = params.getPreviewFormat();
  8.             YuvImage image = new YuvImage(data, format, w, h, null);
  9.             ByteArrayOutputStream out = new ByteArrayOutputStream();
  10.             Rect area = new Rect(00, w, h);
  11.             image.compressToJpeg(area, 100, out);
  12.             Bitmap bm = BitmapFactory.decodeByteArray(out.toByteArray()0, out.size());
  13.            
  14.             Matrix matrix = new Matrix();
  15.         matrix.postRotate(90);
  16.         Bitmap rotatedBitmap = Bitmap.createBitmap(bm, 00,w, h, matrix, true);
  17.             camWeather.shareBitmap=rotatedBitmap;
  18.     }

onPreviewFrame auto callback!!

Line 4~13: camera preview transform to bitmap.

Line 15~17: bitmap rotate because I captured potrait(see surfaceview line 26)

Line 18 : need for combine to overlay.

Add to surfaceCreated for start preview callback

  1. cam.setPreviewCallback(this);

Add to surfaceDestroyed for anti method called after release() exception.

  1. cam.setPreviewCallback(null);

This code is combine to overlay.

  1.     public void capture(){
  2.         Bitmap overlay=Bitmap.createBitmap(shareBitmap.getWidth(),shareBitmap.getHeight(),shareBitmap.getConfig());
  3.         Canvas canvas=new Canvas(overlay);
  4.         canvas.drawBitmap(shareBitmap, 0,0null);
  5.         shareLayout.buildDrawingCache();
  6.         Bitmap bm=shareLayout.getDrawingCache();
  7.         canvas.drawBitmap(bm,0,0,null);
  8.         FileOutputStream out;
  9.        
  10.         String filename=System.currentTimeMillis()+".jpg";
  11.         String temp="/"+filename;
  12.        
  13.         try{
  14.             out=new FileOutputStream(Environment.getExternalStorageDirectory().toString()+temp);
  15.             overlay.compress(Bitmap.CompressFormat.JPEG,100, out);
  16.             Toast.makeText(getApplicationContext(),temp, Toast.LENGTH_SHORT).show();
  17.         }catch(Exception e){
  18.             Log.d("screenshot",String.valueOf(e));
  19.             e.printStackTrace();
  20.            
  21.         }
  22.        
  23.     }

Line 2,4 shareBitmap: camera bitmap from camera preview callback 

Line 2~3 : Setting new bitmap feature then draw canvas.

Line 4 : draw camerapreview to new bitmap.

Line 5~6 : capture overlay layout 

Line 7 : draw overlay to new bitmap.

Line 8~ : save to jpg file.

 This is run this code.!!



1 comment: