mardi, 22 décembre 2009

Créer un Avatar à partir de sa photo


Je ne suis pas encore allé voir le film Avatar dont tout le monde parle mais j'ai trouvé cette vidéo tout simplement bluffante ! Créer à partir de sa photo et de Photoshop le visage d'un Avatar réalise, moi je dis chapeau :)

Source : Le Plubigeekaire

lundi, 17 août 2009

Développement : prendre une photo avec Android

Dernièrement j'ai eu besoin pour une de mes applications Android (Fontaines) d'utiliser la caméra de mon HTC Magic. J'ai donc cherché comment utiliser simplement la caméra sous Android pour prendre une photo qui serait ensuite utilisé dans mon application.

J'ai trouvé de nombreuses sources, chacune avec ses petits défauts. J'ai donc compilé plusieurs codes et je vous présente aujourd'hui une application simple qui tient en une classe et qui permet de prendre une photo (grâce au trackball du HTC Magic, au menu ou via le bouton de l'interface). Libre à vous d'adapter ce code pour vos besoins personnels.

Comme je suis généreux et que le code est un peu long je vous donne directement le projet Eclipse Android et l'APK si vous voulez tester par vous même l'application ;)

EDIT 19/06/2011 : il semblerait que la classe initiale ne fonctionne plus très bien sous Android 2.x, un lecteur m'a donc fourni un nouveau code qui est fonctionnel sur son Galaxy S :

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;

import android.app.Activity;
import android.content.ContentValues;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore.Images;
import android.provider.MediaStore.Images.Media;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Button;

public class AppareilPhotoActivity extends Activity implements SurfaceHolder.Callback, PictureCallback, ShutterCallback {

    
    private Camera camera;
    private SurfaceView surfaceView;
    private SurfaceHolder surfaceHolder;
    
    
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        

        // Cache la barre de titre
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        
        setContentView(R.layout.main);
        
        surfaceView = (SurfaceView)this.findViewById(R.id.surface_view);
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        
        
        Button prendrePhoto = (Button)this.findViewById(R.id.btn_prendrePhoto);
        prendrePhoto.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                camera.takePicture(AppareilPhotoActivity.this, null, AppareilPhotoActivity.this);
            }
        });
        
    }
    

    /*
     * Méthode appelée après un changement de taille ou de format de la surface.
     * */
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        // TODO Auto-generated method stub
        if(camera != null){
            camera.stopPreview();
            Camera.Parameters p = this.camera.getParameters();
            p.setPreviewSize(width, height);
            this.camera.setParameters(p);
            
            try {
                this.camera.setPreviewDisplay(holder);
                this.camera.startPreview();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    /*
     * Méthode appelée immédiatement après la création de la surface
     * */
    public void surfaceCreated(SurfaceHolder holder) {
        // TODO Auto-generated method stub
        camera = Camera.open();
    }

    /*
     * Méthode appelée immédiatement avant la destruction de la surface
     * */
    public void surfaceDestroyed(SurfaceHolder holder) {
        // TODO Auto-generated method stub
        if(camera != null){
            camera.stopPreview();
            camera.release();
        }
    }


    @Override
    public void onPictureTaken(byte[] data, Camera arg1) {
        // TODO Auto-generated method stub
        ContentValues values = new ContentValues();
        values.put(Media.TITLE, "Mon image");
        values.put(Media.DESCRIPTION, "Image prise par le téléphone");
        Uri uri = getContentResolver().insert(Images.Media.EXTERNAL_CONTENT_URI, values);
        
        OutputStream os;
        try {
            os = getContentResolver().openOutputStream(uri);
            os.write(data);
            os.flush();
            os.close();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        camera.startPreview();
    }


    @Override
    public void onShutter() {
        // TODO Auto-generated method stub
        Log.d(getClass().getSimpleName(), "Clic Clac !");
    }  
}

Et ci dessous le code complet de la classe qui gère tout ça (ancienne version pour Android 1.6).

public class TakePicture extends Activity implements SurfaceHolder.Callback
{
    private Camera camera;
    private boolean isPreviewRunning = false;
    private SimpleDateFormat timeStampFormat = new SimpleDateFormat("yyyy-MM-dd-HH.mm.ss");
    private int REQUEST_CODE_IMAGE_GALLERY = 1;
   
    private SurfaceView surfaceView;
    private SurfaceHolder surfaceHolder;
    private Handler mAutoFocusHandler;
    private int mAutoFocusMessage;
   
    private Uri taken;
    private String name;
    private OutputStream filoutputStream;

    public void onCreate(Bundle icicle)
    {
        super.onCreate(icicle);
        Log.e(getClass().getSimpleName(), "onCreate");
        getWindow().setFormat(PixelFormat.TRANSLUCENT);
        setContentView(R.layout.camera);
        surfaceView = (SurfaceView)findViewById(R.id.surface);
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
       
        ImageButton close = (ImageButton) findViewById(R.id.takepicture);
        close.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                takeThePicture();
            }
        });
    }
   
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState)
    {
        super.onRestoreInstanceState(savedInstanceState);
    }

    Camera.PictureCallback mPictureCallbackRaw = new Camera.PictureCallback() {
        public void onPictureTaken(byte[] data, Camera c) {
            Log.e(getClass().getSimpleName(), "PICTURE CALLBACK RAW: " + data);
            camera.startPreview();
        }
    };
   
    Camera.PictureCallback mPictureCallbackJpeg = new Camera.PictureCallback() {
        public void onPictureTaken(byte[] data, Camera c) {
            try {
                Log.v(getClass().getSimpleName(), "onPictureTaken=" + data + " length = " + data.length);
                filoutputStream.write(data);
                filoutputStream.flush();
                filoutputStream.close();
               
            } catch(Exception ex) {
            }
        }
    };
   
    Camera.ShutterCallback mShutterCallback = new Camera.ShutterCallback() {
        public void onShutter() {
            Log.e(getClass().getSimpleName(), "SHUTTER CALLBACK");
        }
    };
   
    private void takeThePicture ()
    {
        try {
            String filename = "takePicture" + timeStampFormat.format(new Date());
            String fl = filename + ".jpg";
            ContentValues values = new ContentValues();
            values.put(Media.TITLE, fl);
            values.put(Media.DISPLAY_NAME, fl);
            values.put(Media.DESCRIPTION, "Image capture by camera for TakePicture");
            long dt = new Date().getTime();
            values.put(Media.DATE_TAKEN, dt);
            values.put(Media.MIME_TYPE, "image/jpeg");
           
            name = "/sdcard/DCIM/Camera/" + String.valueOf(dt) + ".jpg";
           
            taken = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values);
           
            filoutputStream = getContentResolver().openOutputStream(taken);
            camera.takePicture(mShutterCallback, mPictureCallbackRaw, mPictureCallbackJpeg);
        } catch(Exception ex ){
            ex.printStackTrace();
            Log.e(getClass().getSimpleName(), ex.getMessage(), ex);
        }
    }

    public boolean onKeyDown(int keyCode, KeyEvent event)
    {
        if(keyCode == KeyEvent.KEYCODE_DPAD_CENTER)
        {
            takeThePicture ();
            return true;
        }
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            return super.onKeyDown(keyCode, event);
        }
        return false;
    }
   
    public boolean onCreateOptionsMenu(Menu menu)
    {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.camera, menu);
        return true;
    }
   

    public boolean onOptionsItemSelected(MenuItem item)
    {
        switch (item.getItemId())
        {
            case R.id.take:
                takeThePicture ();
                return true;
            case R.id.pictures:
                Intent activityIntent = new Intent();
                activityIntent.setAction("android.intent.action.GET_CONTENT");
                activityIntent.setType("image/*");
                startActivityForResult(activityIntent, REQUEST_CODE_IMAGE_GALLERY);
                return true;
        }
        return true;
    }

    protected void onResume()
    {
        Log.e(getClass().getSimpleName(), "onResume");
        super.onResume();
    }

    protected void onSaveInstanceState(Bundle outState)
    {
        super.onSaveInstanceState(outState);
    }

    protected void onStop()
    {
        Log.e(getClass().getSimpleName(), "onStop");
        super.onStop();
    }
   
    public void requestAutoFocus(Handler handler, int message)
    {
        if (camera != null)
        {
            mAutoFocusHandler = handler;
            mAutoFocusMessage = message;
            camera.autoFocus(autoFocusCallback);
        }
    }

    public void surfaceCreated(SurfaceHolder holder)
    {
        Log.e(getClass().getSimpleName(), "surfaceCreated");
        camera = Camera.open();
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)
    {
        Log.e(getClass().getSimpleName(), "surfaceChanged");
        if (isPreviewRunning) {
            camera.stopPreview();
        }
        Camera.Parameters p = camera.getParameters();
        p.setPreviewSize(w, h);
        camera.setParameters(p);
        try {
            camera.setPreviewDisplay(holder);
        } catch (IOException e) {
        }
        camera.startPreview();
        isPreviewRunning = true;
    }

    public void surfaceDestroyed(SurfaceHolder holder)
    {
        Log.e(getClass().getSimpleName(), "surfaceDestroyed");
        camera.stopPreview();
        isPreviewRunning = false;
        camera.release();
    }
   
    private final Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback() {
        public void onAutoFocus(boolean success, Camera camera) {
          if (mAutoFocusHandler != null) {
            Message message = mAutoFocusHandler.obtainMessage(mAutoFocusMessage, success);
            mAutoFocusHandler.sendMessageDelayed(message, 1500);
            mAutoFocusHandler = null;
          }
        }
      };
}


mercredi, 29 avril 2009

Terminate yourself

En vue de la sortie de Terminator 4 (Terminatr Salvation) prochainement (le 3 juin 2009) un service sur Internet propose de vous transformer en une terrible machine créée pour détruire l'humanité, le terminator.

Ce site s'appelle Terminate Yourself, il suffit d'uploader une photo de moins de 500 ko, d'ajuster la photo, de choisir le niveau de dommage de votre peau et ça y est on est transformer en machine de mort :D

Et voici ce que ça donne sur moi :

ça fait peur hein ? :D

mardi, 16 septembre 2008

Coucher de soleil

Un petit billet pour vous présenter une photo que j'ai pris samedi dernier, un joli couché de soleil dans les rues de Tremblay en France :)
Dommage que ce fichu câble électrique vienne un peu tout gâcher mais je suis pas assez fort en retouche photo pour le virer ...

C'est sympa de voir un ciel rose et non pas gris comme on a l'habitude par ici ;)

lundi, 15 octobre 2007

Ma vie parisienne

Bien ... Histoire de montrer à tout le monde que je ne suis pas mort et que ce blog ne vas pas sombrer dans l'oubli je profite du temps "libre" que j'ai pour poster un petit billet :) (je suis certain que ça vous fait super plaisir ...)

Tout ça pour dire que je bosse beaucoup nuit et jour (plus la nuit que le jour parfois ...) et que finalement ma vie "parisienne" dans mon appart se résumé très simplement :
metro, boulot, un peu dodo
Je n'ai pour le moment pas eu le temps de voir ce qu'il y avait autour de l'immeuble à plus de 50m (distance qui sépare la porte de l'immeuble de la station de métro), peut être un jour si j'ai du temps (donc jamais ?)

Et puis en cadeau, la super vue que j'ai depuis ma chambre (je suis sûr que vous m'enviez hein :p )