web-dev-qa-db-fra.com

Android: superposition sur l'aperçu de l'appareil photo Android

J'utilise Camera API et j'appelle la caméra. 

Je souhaite afficher un en-tête (pour le marquage) en haut de l'aperçu de la caméra. L'en-tête est une image jpeg. 

C'est possible? Toute aide appréciée.

Merci d'avance.

Mon code va comme ci-dessous.

public class CameraActivity extends Activity {
    @Override
    protected void onPause() {

        super.onPause();
    }

    private static final int CAMERA_PIC_REQUEST = 2500;
    private Bitmap image2;
    private Bitmap bm;
    public static String imagepath;
    public static int x=1;
    private RdmsDbAdapter dbHelper;
    @Override



    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.header);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        //caling new incident
        if(IncidentFormActivity.incident_id == null || IncidentFormActivity.isDisable==true){
            //DBAdapter instance created and connection opened. 
            dbHelper = new RdmsDbAdapter(CameraActivity.this);
            dbHelper.open();

            //setting up flags
            NewIncidentHelper nih = new NewIncidentHelper();
            nih.setUpNewIncident();

            //setting up incident_id
            String Date= IncidentIdGenerator.getDate();
            String Time = IncidentIdGenerator.getTime();

            IncidentFormActivity.incident_id = IncidentIdGenerator.now("ddMMyyyyHHmmss");
            dbHelper.executeSQL("insert into incident values ('" + IncidentFormActivity.incident_id
                    + "', ' ', ' ', ' ', ' ', '"+Date+"', '0','0','0','0','0','0','0','0','0','"+Time+"')");
            dbHelper.close();
        }

        //calling camera
        Intent cameraIntent = new Intent(
                Android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);


    }
    public String getPath(Uri uri) {
        String[] projection = { MediaStore.Images.Media.DATA };
        Cursor cursor = managedQuery(uri, projection, null, null, null);
        int column_index = cursor
                .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }

    //back key on phone pressed
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        switch (keyCode) {
        case KeyEvent.KEYCODE_BACK:
            Intent i= new Intent(CameraActivity.this, IncidentFormActivity.class);
            startActivity(i);
            this.finish();

            break;

        default:
            break;
        }
        return super.onKeyDown(keyCode, event);
    }

    //handle response came from camera when the picture is taken.
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == CAMERA_PIC_REQUEST && resultCode == RESULT_OK) {
                final ImageView img = new ImageView(this);
                img.setLayoutParams(new LayoutParams(100, 100));
                image2 = (Bitmap) data.getExtras().get("data");
                img.setImageBitmap(image2);
                String incident_ID = IncidentFormActivity.incident_id;
                //l2.addView(img);
                    imagepath="/sdcard/RDMS/"+incident_ID+ x + ".png";
                File file = new File(imagepath);
                try {
                     bm = Bitmap.createScaledBitmap( image2,400, 300, true);
                    file.createNewFile();
                    FileOutputStream ostream = new FileOutputStream(file);
                    bm.compress(CompressFormat.PNG, 90, ostream);
                    ostream.close(); 
                    //Initialising db class and inserting values
                    dbHelper = new RdmsDbAdapter(CameraActivity.this);
                    dbHelper.open();
                    dbHelper.executeSQL("insert into files values ('"+imagepath+"', '"+IncidentFormActivity.incident_id+"')");
                    dbHelper.close();

                } catch (Exception e) {
                    e.printStackTrace();
                    Toast.makeText(getApplicationContext(),"yourfirst  error message is "
                                            + e.toString(), 1000).show();
                }
                x++;
                final AlertDialog.Builder alert = new AlertDialog.Builder(
                        CameraActivity.this);

                alert.setTitle(getString(R.string.anotherimage));
                alert.setCancelable(false);
                //alert.setMessage("Play or Delete the Video selected");
                //alert.setIcon(R.drawable.vid_red);
                alert.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        Intent sendingpage = new Intent(CameraActivity.this, CameraActivity.class);
                          startActivity(sendingpage);

                    }
                });
                alert.setNegativeButton(getString(R.string.no),
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                Intent callback = new Intent (CameraActivity.this, IncidentFormActivity.class);
                                startActivity(callback);
                            }
                        });

                alert.show();


            }
            if(resultCode==RESULT_CANCELED)
            {

                AlertDialog.Builder builder = new AlertDialog.Builder(CameraActivity.this);

                builder.setMessage(getString(R.string.areuexit)).setCancelable(
                        false).setPositiveButton(getString(R.string.yes),
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                Intent i= new Intent(CameraActivity.this, IncidentFormActivity.class);
                                startActivity(i);
                                CameraActivity.this.finish();
                            }
                        }).setNegativeButton(getString(R.string.no),
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                dialog.cancel();
                                Intent i= new Intent(CameraActivity.this, CameraActivity.class);                            startActivity(i);
                                CameraActivity.this.finish();
                            }
                        });

                builder.show();



            }
        }
    }
34
Jay Mayu

Vous pouvez utiliser SurfaceView et créer un CustomView qui ouvrira la caméra et vous pourrez ajuster sa taille dans le xml en conséquence. Vous trouverez ci-dessous un pseudo-code.

Créez une classe qui étend SurfaceView et ouvrez la caméra à l'intérieur de celle-ci

CapturePreview.Java  

public class CapturePreview extends SurfaceView implements SurfaceHolder.Callback{

    public static Bitmap mBitmap;
    SurfaceHolder holder;
    static Camera mCamera;

    public CapturePreview(Context context, AttributeSet attrs) {
        super(context, attrs);

        holder = getHolder();
        holder.addCallback(this);
        holder.setType(SurfaceHolder.SURFACE_TYPE_Push_BUFFERS);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {

        Camera.Parameters parameters = mCamera.getParameters();
        parameters.getSupportedPreviewSizes();
        mCamera.setParameters(parameters);
        mCamera.startPreview();
    }
    @Override
    public void surfaceCreated(SurfaceHolder holder) {

        try {
            mCamera = Camera.open();
            mCamera.setPreviewDisplay(holder);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mCamera.stopPreview();
        mCamera.release();
    }
    /***
     * 
     *  Take a picture and and convert it from bytes[] to Bitmap.
     *  
     */
    public static void takeAPicture(){  

        Camera.PictureCallback mPictureCallback = new PictureCallback() {
            @Override
            public void onPictureTaken(byte[] data, Camera camera) {

                BitmapFactory.Options options = new BitmapFactory.Options();
                mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
            }
        };
        mCamera.takePicture(null, null, mPictureCallback);
    }
}

Vous devez maintenant inclure la vue que vous avez créée avec SurfaceView dans votre fichier xml comme ceci

main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
  xmlns:Android="http://schemas.Android.com/apk/res/Android"
  Android:orientation="vertical"
  Android:layout_width="fill_parent"
  Android:layout_height="fill_parent">

  <FrameLayout 
  Android:id="@+id/mySurfaceView"
  Android:layout_width="wrap_content"
  Android:layout_height="wrap_content">

  <com.cam.CapturePreview 
  Android:layout_width="fill_parent"
  Android:layout_height="wrap_content">
  </com.cam.CapturePreview>

  </FrameLayout>

  <LinearLayout 
  Android:layout_below="@id/mySurfaceView" 
  Android:layout_width="fill_parent"
  Android:layout_height="wrap_content"
  Android:layout_centerInParent="true"
  Android:gravity="center">

  <ImageView Android:id="@+id/myImageView" 
  Android:layout_width="wrap_content"
  Android:layout_height="wrap_content"
  Android:src="@drawable/icon"/>
  </LinearLayout>  

</RelativeLayout>

Maintenant, vous pouvez utiliser ce fichier main.xml dans toute Acitivty qui ouvrira une caméra avec un ImageView. Merci ....

21
Lalit Poptani

Vous devrez gérer l'aperçu complet de la caméra et prendre des photos vous-même. Jetez un coup d'œil aux échantillons au samples/ApiDemos/src/com/example/Android/apis/graphics/CameraPreview. Vous pouvez avoir votre propre mise en page sur la zone d'aperçu et y ajouter votre graphique.

Exemple de lien:

http://developer.Android.com/resources/samples/ApiDemos/src/com/example/Android/apis/graphics/CameraPreview.html

20
Ronnie

Vous pouvez le faire avec l’aide de FrameLayout comme ceci:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
  xmlns:Android="http://schemas.Android.com/apk/res/Android"
  Android:layout_width="fill_parent"
  Android:layout_height="fill_parent" >

  <Android.view.SurfaceView
  Android:id="@+id/surface"
  Android:layout_width="fill_parent"
  Android:layout_height="fill_parent" />

<ImageView
    Android:id = "@+id/header"
    Android:layout_width = "wrap_content"
    Android:layout_height = "wrap_content" />

</FrameLayout>

Ce projet camera vous aidera.

3
Vineet Shukla

J'ai bien peur que vous deviez implémenter vous-même l'écran de prévisualisation de la caméra. En théorie, une superposition peut être ajoutée à une autre application en modifiant sa disposition ou en créant une fenêtre de superposition. Le premier moyen est impossible à implémenter et le second peut être implémenté je pense mais c'est un peu un hack et une méthode sujette aux erreurs.

Mettre en œuvre votre propre activité de caméra n'est pas une tâche très difficile, mais plutôt difficile. Je vous recommande de jeter un coup d'œil à l'application Caméra par défaut. Voici son code source: https://github.com/Android/platform_packages_apps_camera .

1
Michael

regardez votre XML serait comme ça:

 <?xml version="1.0" encoding="utf-8"?>
<FrameLayout
 xmlns:Android="http://schemas.Android.com/apk/res/Android"
 Android:layout_width="fill_parent"
 Android:layout_height="fill_parent" >

<Android.view.SurfaceView
 Android:id="@+id/surface"
 Android:layout_width="fill_parent"
 Android:layout_height="fill_parent" />

<ImageView
Android:id = "@+id/header"
Android:layout_width = "wrap_content"
Android:layout_height = "wrap_content" />

</FrameLayout>

et pour le code Java, vous devez étendre SurfaceHolder.Callback à votre activité, puis attachez la caméra à la vue de la surface de la manière suivante.

 public class MainActivity extends Activity implements SurfaceHolder.Callback 
{
  private Camera camera = null;
  private SurfaceView cameraSurfaceView = null;
  private SurfaceHolder cameraSurfaceHolder = null;
  private boolean previewing = false;
  RelativeLayout relativeLayout;





  private Button btnCapture = null;
  private Button btnsave = null;
  private Button btnshare = null;
  private boolean isSaved=false;
  private boolean isCaptured=false;

  @Override
  protected void onCreate(Bundle savedInstanceState) 
  {
    super.onCreate(savedInstanceState);

    getWindow().setFormat(PixelFormat.TRANSLUCENT);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(
                         WindowManager.LayoutParams.FLAG_FULLSCREEN,
                         WindowManager.LayoutParams.FLAG_FULLSCREEN);

    setContentView(R.layout.activity_main);

    relativeLayout=(RelativeLayout) findViewById(R.id.containerImg);
    relativeLayout.setDrawingCacheEnabled(true);
    cameraSurfaceView = (SurfaceView)
                                       findViewById(R.id.surfaceView1);
  //  cameraSurfaceView.setLayoutParams(new FrameLayout.LayoutParams(640, 480));
    cameraSurfaceHolder = cameraSurfaceView.getHolder();
    cameraSurfaceHolder.addCallback(this);
//    cameraSurfaceHolder.setType(SurfaceHolder.
  //                                               SURFACE_TYPE_Push_BUFFERS);




    btnCapture = (Button)findViewById(R.id.capturebtn);
    btnCapture.setOnClickListener(new OnClickListener() 
    {   
      @Override
      public void onClick(View v) 
      {
         camera.takePicture(cameraShutterCallback, 
                                       cameraPictureCallbackRaw,
                                       cameraPictureCallbackJpeg);
         isCaptured=true;
      }
    });
    btnsave = (Button)findViewById(R.id.savebtn);
    btnsave.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
             FrameLayout frm = (FrameLayout)findViewById(R.id.frameLayout1);
                frm.setDrawingCacheEnabled(true);
                frm.buildDrawingCache();
                Bitmap bitmap = frm.getDrawingCache();
                try {
                    File rootFile=new File(Environment.getExternalStorageDirectory().toString()+"/MYCAMERAOVERLAY");
                    rootFile.mkdirs();
                    Random generator = new Random();
                    int n = 10000;
                    n = generator.nextInt(n);
                    String fname = "Image-"+ n +".png";

                    File resultingfile = new File(rootFile, fname);

                    if (resultingfile.exists ()) resultingfile.delete (); 
                    try {
                           FileOutputStream Fout = new FileOutputStream(resultingfile);
                           bitmap.compress(CompressFormat.PNG, 100, Fout);
                           Fout.flush();
                           Fout.close();

                    } catch (FileNotFoundException e) {
                        Log.d("In Saving File", e + "");
                }
                } catch(IOException e){
                    Log.d("In Saving File", e + "");
                }
                isSaved=true;
            }
        });
    btnshare = (Button)findViewById(R.id.sharebtn);
    btnshare.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            if((isSaved)&&(isCaptured)){
                // TODO sharing what ever we saved 
                // take the path


            }

        }
    });
   } 


  ShutterCallback cameraShutterCallback = new ShutterCallback() 
  {  
    @Override
    public void onShutter() 
    {
      // TODO Auto-generated method stub   
    }
  };

  PictureCallback cameraPictureCallbackRaw = new PictureCallback() 
  {  
    @Override
    public void onPictureTaken(byte[] data, Camera camera) 
    {
      // TODO Auto-generated method stub   
    }
  };

  PictureCallback cameraPictureCallbackJpeg = new PictureCallback() 
  {  
    @Override
    public void onPictureTaken(byte[] data, Camera camera) 
    {
      // TODO Auto-generated method stub   
      Bitmap cameraBitmap = BitmapFactory.decodeByteArray
                                                                  (data, 0, data.length);

   int   wid = cameraBitmap.getWidth();
     int  hgt = cameraBitmap.getHeight();

    //  Toast.makeText(getApplicationContext(), wid+""+hgt, Toast.LENGTH_SHORT).show();
      Bitmap newImage = Bitmap.createBitmap
                                        (wid, hgt, Bitmap.Config.ARGB_8888);

      Canvas canvas = new Canvas(newImage);

      canvas.drawBitmap(cameraBitmap, 0f, 0f, null);

      camera.startPreview();

      newImage.recycle();
      newImage = null;

      Intent intent = new Intent();
      intent.setAction(Intent.ACTION_VIEW);

      startActivity(intent);

    }
  };

  @Override
  public void surfaceChanged(SurfaceHolder holder, 
                                       int format, int width, int height) 
  {
    // TODO Auto-generated method stub

    if(previewing)
    {
      camera.stopPreview();
      previewing = false;
    }
    try 
    {
      Camera.Parameters parameters = camera.getParameters();
      parameters.setPreviewSize(640, 480);
      parameters.setPictureSize(640, 480);
      if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
          camera.setDisplayOrientation(-90);

      }

     // parameters.setRotation(90);
      camera.setParameters(parameters);

      camera.setPreviewDisplay(cameraSurfaceHolder);
      camera.startPreview();
      previewing = true;
    } 
    catch (IOException e) 
    {
      // TODO Auto-generated catch block
      e.printStackTrace();  
    }
  }

  @Override
  public void surfaceCreated(SurfaceHolder holder) 
  {
    // TODO Auto-generated method stub
    try
    {
      camera = Camera.open();
    }
    catch(RuntimeException e)
    {
      Toast.makeText(getApplicationContext(), "Device camera  is not working properly, please try after sometime.", Toast.LENGTH_LONG).show();
    }
  }

  @Override
  public void surfaceDestroyed(SurfaceHolder holder) 
  {
    // TODO Auto-generated method stub
      try{


    camera.stopPreview();
    camera.release();
    camera = null;
    previewing = false;
      }catch(Exception e){
          e.printStackTrace();
      }
  }

}

et je pense maintenant que je devrais vous donner la partie XML complète aussi. alors le voici:

  <?xml version="1.0" encoding="utf-8"?>
 <RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
 xmlns:Android1="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/containerImg"
Android:layout_width="fill_parent"
Android:layout_height="match_parent"
Android1:layout_gravity="bottom"
Android:orientation="vertical"
Android1:gravity="bottom" >

    <FrameLayout
    Android:id="@+id/frameLayout1"
    Android1:layout_width="wrap_content"
    Android1:layout_height="wrap_content"
    Android:gravity="center|top"
     >

 <SurfaceView
     Android1:id="@+id/surfaceView1"
     Android1:layout_width="100dip"
     Android1:layout_height="150dip"
     Android1:layout_gravity="center_horizontal" />

<ImageView
Android1:id="@+id/imageView1"
Android1:layout_width="fill_parent"
Android1:layout_height="fill_parent"
Android:contentDescription="@string/app_dress_desc"
Android:gravity="center|bottom"
Android1:scaleType="center"
Android1:src="@drawable/dress" />

</FrameLayout>


<GridLayout
    Android1:id="@+id/gridLayout1"
    Android1:layout_width="match_parent"
    Android1:layout_height="wrap_content"
    Android1:layout_alignParentBottom="true"
    Android1:layout_alignParentLeft="true"
    Android1:columnCount="1"
    Android1:gravity="center|bottom"
    Android1:orientation="vertical" >

    <ImageButton
        Android1:id="@+id/capturebtn"
        Android1:layout_width="60dp"
        Android1:layout_height="wrap_content"
        Android1:layout_gravity="left"
        Android1:src="@drawable/camera"
        Android:contentDescription="@string/app_icon_camera_desc" />

    <ImageButton
        Android1:id="@+id/savebtn"
        Android1:layout_width="60dp"
        Android1:layout_height="wrap_content"
        Android1:layout_column="0"
        Android1:layout_gravity="center_horizontal|top"
        Android1:layout_row="0"
        Android1:src="@drawable/save"
        Android:contentDescription="@string/app_icon_save_desc" />

    <ImageButton
        Android1:id="@+id/sharebtn"
        Android1:layout_width="60dp"
        Android1:layout_height="wrap_content"
        Android1:layout_column="0"
        Android1:layout_gravity="right|top"
        Android1:layout_row="0"
        Android1:src="@drawable/share"
        Android:contentDescription="@string/app_icon_share_desc" />
</GridLayout>

Le bouton de partage ne fonctionne pas à ce stade, mais il enregistre l'ensemble de la disposition du cadre sur la capture cliquée . espérons que cela vous sera utile. 

0
pouya

Une solution de rechange consiste à superposer le fichier XML d'activité avec un autre fichier XML contenant l'image d'en-tête. Faire cela:

  1. Créez un nouveau fichier de mise en page dans le dossier de mise en page. Par exemple: overlay.xml
  2. Insérez une ImageView à l'intérieur, quelque chose comme:

    <RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    xmlns:app="http://schemas.Android.com/apk/res-auto">
    
    <ImageView
        Android:id="@+id/imageView1"
        Android:layout_centerInParent="true"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:src="@drawable/Android" />
    
    
    </RelativeLayout>
    
  3. Ensuite, dans le fichier Activity Java, c'est-à-dire MotionDetector.Java, créez une nouvelle méthode addView():

       private void addView()
       {
           controlInflater = LayoutInflater.from(getBaseContext());
           View viewControl = controlInflater.inflate(R.layout.overlay, null);
           LayoutParams layoutParamsControl = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
           this.addContentView(viewControl, layoutParamsControl);
    
       }
    
  4. Enfin, appelez la méthode addView() à partir de onCreate() pour ajouter l'image:

    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.header);
    addView();
    

Le résultat final serait alors une superposition d'image au-dessus de SurfaceView. Sous réserve de la qualité de l'image d'en-tête, la qualité de rendu de l'en-tête doit sembler originale. J'espère que ça aide.

0
OBX