Comment ajouter des filtres à une application camera en temps rl

dlife123 Messages postés 44 Statut Membre -  
dlife123 Messages postés 44 Statut Membre -
Bonjour,
je voudrais créer une application android qui prendra des photos.j'aimerais integrer à mon application la possibilité d'appliquer des filtres en temps réel c'est à dire avant que l'utilisateur prenne la photo qu'il puisse par exemple ajouter la luminosité,flouter la photo,la rendre plus claire,la changer en noir et blanc...
je n'ai pas vraiment trouvé des tutos qui expliquent comment faire.
est-ce que quelqu'un peut me donner une piste?
merci d'avance pour votre aide

3 réponses

  1. Twinuts Messages postés 27 Date d'inscription   Statut Membre Dernière intervention   2
     
    Salut,

    As-tu regardé ce sujet ICI, voir ce github

    0
  2. dlife123 Messages postés 44 Statut Membre 35
     
    merci beaucoup pour ta réponse.
    j'ai téléchargé l'apk de "Camera Filter" pour voir comment ça marche mais quand j'ai installé l'app je n'ai vu aucun bouton qui me permetrait d'appliquer les filtres comme sur les captures d'écran qu'ils ont affichées à part le bouton qui permet de capturer l'image.
    y a-t-il des modifications à apporter au code source pour pouvoir appliquer les filtres?
    merci d'avance pour ta réponse
    0
  3. Twinuts Messages postés 27 Date d'inscription   Statut Membre Dernière intervention   2
     
    Salut,

    Ok, ok, pour faire au plus simple, si tu souhaites utiliser des effets de base ce n'est pas compliqué en soit il te suffit d'utiliser la fonction setColorEffect des paramètres de la caméra , sinon si tu veux faire tes propres effets, c'est un peu plus long.

    Ici j'utilise la version deprecated de la camera donc, si ton téléphone est sous Android 6 et que l'application crash sur le Camera.open(), il suffit de passer le targetSdkVersion à 22.
    Note: Le code est fait sous AndroidStudio


    Solution 1, utilisation des paramètres:
    Cet exemple initialise un spinner (en haut) avec les effets dispo pour la caméra du téléphone puis applique l'effet en fonction de ce qui est sélectionné par le spinner.

    AndroidManifest.xml
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
    


    res/layout/activity_main.xml
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/relativeLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:keepScreenOn="true"
        android:orientation="vertical">
    
        <Spinner
            android:id="@+id/effects"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"/>
    
        <org.camdemo.CamView
            android:id="@+id/camera"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"/>
    </LinearLayout>
    


    src/org/camdemo/MainActivity.java
    package org.camdemo;
    
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.AdapterView;
    import android.widget.ArrayAdapter;
    import android.widget.Spinner;
    
    
    public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
    
      private CamView m_cv = null;
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        m_cv = (CamView)findViewById(R.id.camera);
        /* init du spinner pour les effets */
        Spinner spinner = (Spinner) findViewById(R.id.effects);
    
        ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
          android.R.layout.simple_spinner_item, m_cv.supportedEffects());
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(adapter);
        spinner.setOnItemSelectedListener(this);
      }
    
      @Override
      public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
        /* application du filtre en fonction de celui choisi */
        m_cv.setEffect(adapterView.getItemAtPosition(i).toString());
      }
    
      @Override
      public void onNothingSelected(AdapterView<?> adapterView) {
    
      }
    }
    


    src/org/camdemo/CamView.java
    package org.camdemo;
    
    import android.content.Context;
    import android.content.res.Configuration;
    import android.hardware.Camera;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    
    import java.util.List;
    
    
    public class CamView extends SurfaceView implements SurfaceHolder.Callback {
      private SurfaceHolder m_holder = null;
      private Camera m_cam = null;
      private boolean m_running = false;
    
      public CamView(final Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
      }
      public CamView(final Context context) {
        super(context);
        init();
      }
      public CamView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
      }
    
      public List<String> supportedEffects() {
        Camera.Parameters parameters = m_cam.getParameters();
        return parameters.getSupportedColorEffects();
      }
    
      @SuppressWarnings("deprecation")
      private void init() {
        /* Installation du callback pour être notif lorsque la surface est créée/détruite. */
        m_holder = getHolder();
        m_holder.addCallback(this);
        m_holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        /* récupération d'une instance sur la camera */
        m_cam = Camera.open();
      }
    
      public void setEffect(final String s) {
        if(s.isEmpty()) return;
        Log.i(getClass().getSimpleName(), "Apply new effect: " + s);
        /* Reload de la surface avec le nouveau filtre */
        Camera.Parameters parameters = m_cam.getParameters();
        parameters.setColorEffect(s);
        m_cam.setParameters(parameters);
        m_cam.startPreview();
        try {
          m_cam.setPreviewDisplay(m_holder);
        } catch (final Throwable e) {
          Log.e(getClass().getName(), "Exception : " + e.getMessage(), e);
        }
      }
    
      @Override
      public void surfaceCreated(final SurfaceHolder holder) {
        try {
          m_cam.setPreviewDisplay(holder);
        } catch (final Throwable e) {
          Log.e(getClass().getName(), "Exception : " + e.getMessage(), e);
        }
      }
    
      @Override
      public void surfaceDestroyed(final SurfaceHolder holder) {
        if (m_running) {
          m_cam.stopPreview();
          m_cam.setPreviewCallback(null);
          m_cam.release();
          m_running = false;
        }
      }
    
      @Override
      public void surfaceChanged(final SurfaceHolder holder, final int format,
                                 final int w, final int h) {
    
        if (m_running) m_cam.stopPreview();
    
        // Prise en compte de la rotation de l’écran
        if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE)
          m_cam.setDisplayOrientation(90);
        else
          m_cam.setDisplayOrientation(0);
    
        try {
          m_cam.setPreviewDisplay(holder);
          m_cam.startPreview();
        } catch (final Exception e) {
          Log.e(getClass().getName(), "Exception : " + e.getMessage(), e);
        }
        m_running = true;
      }
    }
    


    Solution 2, utilisation d'un filtre maison:
    Je ne vais pas mettre d'exemple pour cette solution, qui, est assez longue à mettre en place, mais globalement, cette solution nécessite:
    - l'utilisation du PreviewCallback
    - l’intégration d'openGL (obligatoire sinon ton application va lag à mort)

    0
    1. dlife123 Messages postés 44 Statut Membre 35
       
      Bonjour et merci beaucoup pour ta réponse.
      j'ai essayé ta première solution, elle a bien marché et je t'en remercie.
      cependant j'ai voulu appliqué les filtres à la camera frontale,j'ai donc modifié une partie de ton code comme ceci:

      //Dans la classe CamView

      //recherche de la camera frontale
      int cameraId = -1;
      int numberOfCameras = Camera.getNumberOfCameras();
      for (int i = 0; i < numberOfCameras; i++) {
      Camera.CameraInfo info = new Camera.CameraInfo();
      Camera.getCameraInfo(i, info);
      if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
      cameraId = i;
      m_cam=Camera.open(cameraId);
      break;
      }
      }

      ///Dans la MainActivity

      //spinner.setAdapter(adapter);

      bouton.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
      for (int i=0;i <=m_cv.supportedEffects().size();i++){
      m_cv.setEffect(m_cv.supportedEffects().get(i).toString());
      }

      Avec ces modifications j'ai pu demarré la camera frontale mais les filtres ne s'appliquent
      pas.
      est-ce parce que ces filtres là ne sont supportés que par la camera arrière?

      pour la deuxième solution que tu m'as proposée ,est-ce que c'est ce que fait CameraFilter,le lien vers lequel tu m'as dirigé l'autre fois?
      ne connais-tu pas un bon tutoriel qui pourait m'aider?
      0