domenica 10 ottobre 2010

It Works (Android emulator camera preview e save)

In attesa di acquistare uno smartphone android sto continuando a guardare l'SDK inseguendo le idee che mi ronzano in testa. Visto che diverse delle mie idee dovrebbero appoggiarsi sulla camera (ed eventualmente sui sensori) dell'OS ho cercato il modo di "simulare" la Fotocamera dello smartphone utilizzando la webcam del pc.
Come per tutte le cose non sono partito da zero, ed ho prima googleato un po' trovando quest'ottimo sito di chi aveva già fatto una ricerca simile alla mia :
http://www.inter-fuser.com/2009/09/live-camera-preview-in-android-emulator.html
Da bravo developer dell'anno 2010 ho copiaincollato il tutto. ;)

In primis ho creato su eclipse un progetto web chiamato WebcamBroadcaster dove ho semplicemente reincollato il sorgente proposto nella pagina. Funziona tutto, una volta aggiunte le jmf al progetto. Ho visto che avviando l'applicazione accendeva la webcam e mi sono fidato.
Come secondo step, sul mio programmino di esempio ICapture che già apriva la camera normale di android, ho aggiunto la classe SocketCamera trovata sulla pagina linkata sopra. Nella mia activity principale ho eseguito poi le seguenti sostituzioni :

// Cambio SocketCamera
// private Camera camera;
SocketCamera camera;
...
// Cambio SocketCamera
// surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_NORMAL);
...
// Cambio SocketCamera
// camera = Camera.open();
camera = SocketCamera.open();

Come riportato nell'articolo trovato.
Ho dovuto anche commentare il salvataggio della foto perchè il metodo takePicture non era implementato in socketCamera

// if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
// camera.takePicture(mShutterCallback, mPictureCallbackRaw, iccb);
// return true;
// }

Fix import, ricompilato, avviato (con WebcamBroadcaster già avviato) e la magia era fatta, mi rivedevo in livePreview nella mia app android.
A questo punto ero già felice al 99% ma volevo anche decommentare quell'ultima takePicture, per cui, dopo un briciolo di ricerche per capire come ottenere un byte array da una bitmap, ho aggiunto il codice sottostante alla SocketCamera e riabilitato con successo (anche se mi è servito un po' di tempo per trovare le immagini) il salvataggio delle foto.

// Prova per takePicture
public final void takePicture(Camera.ShutterCallback shutter, Camera.PictureCallback raw, Camera.PictureCallback jpeg) {
takePicture(shutter, raw, null, jpeg);
}
public final void takePicture(Camera.ShutterCallback shutter,
Camera.PictureCallback raw, Camera.PictureCallback postview, Camera.PictureCallback jpeg) {
stopPreview();

try {
Socket socket = null;
try {
socket = new Socket();
socket.bind(null);
socket.setSoTimeout(SOCKET_TIMEOUT);
socket.connect(new InetSocketAddress(address, port), SOCKET_TIMEOUT);

if (shutter != null) shutter.onShutter();

// obtain the bitmap
InputStream in = socket.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(in);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); //bm is the bitmap object
byte[] b = baos.toByteArray();
// Chiama la callback
if (raw != null) raw.onPictureTaken(b, null);
if (postview != null) postview.onPictureTaken(b, null);
if (jpeg != null) jpeg.onPictureTaken(b, null);
} catch (RuntimeException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e)
/* ignore */
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}

Forse non sarà la soluzione migliore o più elegante, ma funziona e per ora mi basta.
A questo punto, in bocca al lupo a chiunque abbia voglia di cimentarsi con Android e la sua fotocamera.

4 commenti:

  1. Hi,
    I'm working on project that take picture with android emulator, but I have an question about the above code of taken picture, this code we must colled in class socketClass or in activity
    thanks in advance

    RispondiElimina
  2. Hello, can u please post the code in English and also let us know where to put this code and how this can be called in our Camera Preview Activity???

    RispondiElimina
  3. Hello sir,can i ask for the working source of the project..
    i tried myself and i just only got Hello World and my webcamBroadcaster is error..it show that no suitable player..
    can u please show me how its done and email me at
    matpyam@gmail.com
    thanks in advance

    RispondiElimina
  4. ciao anche io sto cercando di far funzionare l'emulatore ma proprio non va...mi potresti spiegare brevemente i passi da fare?
    grazie.

    RispondiElimina