Comment ajouter des filtres à une application camera en temps rl

Fermé
dlife123 Messages postés 36 Date d'inscription jeudi 9 juillet 2015 Statut Membre Dernière intervention 30 octobre 2016 - 18 août 2016 à 08:29
dlife123 Messages postés 36 Date d'inscription jeudi 9 juillet 2015 Statut Membre Dernière intervention 30 octobre 2016 - 30 oct. 2016 à 19:27
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

Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 2
6 oct. 2016 à 12:57
Salut,

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



0
dlife123 Messages postés 36 Date d'inscription jeudi 9 juillet 2015 Statut Membre Dernière intervention 30 octobre 2016 35
21 oct. 2016 à 17:28
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
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 2
24 oct. 2016 à 17:05
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
dlife123 Messages postés 36 Date d'inscription jeudi 9 juillet 2015 Statut Membre Dernière intervention 30 octobre 2016 35
30 oct. 2016 à 19:27
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