webentwicklung-frage-antwort-db.com.de

Android: Überlagerung in der Android-Kameravorschau

Ich verwende Camera API und rufe die Kamera auf. 

Ich möchte eine Kopfzeile (für das Branding) oben in der Kameravorschau anzeigen. Der Header ist ein JPEG-Bild. 

Ist es möglich? Jede Hilfe geschätzt.

Danke im Voraus.

Mein Code geht wie folgt.

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

Sie können SurfaceView verwenden und ein CustomView erstellen, das die Kamera öffnet, und Sie können die Größe in der XML-Datei entsprechend anpassen. Unten ist ein Pseudo-Code.

Erstellen Sie eine Klasse, die SurfaceView erweitert, und öffnen Sie die Kamera darin

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);
    }
}

Jetzt musst du die Ansicht, die du mit SurfaceView erstellt hast, wie folgt in deine XML einfügen

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>

Jetzt können Sie diese main.xml in jeder Acitivty verwenden, die eine Kamera mit einer ImageView..__ öffnet. Danke ....

21
Lalit Poptani

Sie müssen die gesamte Kameravorschau selbst übernehmen und fotografieren. Schauen Sie sich die Samples unter samples/ApiDemos/src/com/example/Android/apis/graphics/CameraPreview an. Sie können Ihr eigenes Layout über dem Vorschaubereich erstellen und Ihre Grafik hinzufügen.

Beispiellink:

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

20
Ronnie

Sie können das mit Hilfe von FrameLayout so machen:

<?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>

Dieses Kameraprojekt wird Ihnen helfen.

3
Vineet Shukla

Ich fürchte, Sie müssen den Kameravorschaubildschirm selbst implementieren. Theoretisch kann eine Überlagerung zu einer anderen Anwendung hinzugefügt werden, indem das Layout geändert oder ein Überlagerungsfenster erstellt wird. Der erste Weg ist unmöglich zu implementieren und der zweite Weg kann implementiert werden, denke ich, aber es ist eine Art Hack und eine fehleranfällige Methode.

Die Implementierung Ihrer eigenen Kameraaktivität ist keine sehr schwierige Aufgabe, aber eher anspruchsvoll. Ich würde Ihnen empfehlen, einen Blick auf die Standard-Kamera-Anwendung zu werfen. Hier ist der Quellcode: https://github.com/Android/platform_packages_apps_camera .

1
Michael

schau dir dein XML so an:

 <?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>

und für den Java-Code sollten Sie SurfaceHolder.Callback in Ihrer Aktivität erweitern und dann die Kamera wie folgt an die Oberflächenansicht anhängen. Es ist mein vollständiger Code. Bitte seien Sie vorsichtig mit Bitmaps und Canvas.

 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();
      }
  }

}

und ich denke, jetzt sollte ich Ihnen auch den vollständigen XML-Teil geben. hier ist es also:

  <?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>

Die Share-Schaltfläche funktioniert an dieser Stelle nicht, speichert jedoch das gesamte Frame-Layout beim Klicken auf Capture . Ich hoffe, es wird hilfreich sein. 

0
pouya

Als Alternative können Sie die Activity XML-Datei mit einer anderen XML-Datei überlagern, die das Header-Bild enthält. Um dies zu tun:

  1. Erstellen Sie eine neue Layoutdatei im Layoutordner. Zum Beispiel: overlay.xml
  2. Fügen Sie eine ImageView darin ein, etwa:

    <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. Erstellen Sie dann in der Activity-Java-Datei, dh MotionDetector.Java-Datei, eine neue Methode 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. Rufen Sie schließlich die addView()-Methode von onCreate() auf, um das Bild hinzuzufügen:

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

Das Endergebnis wäre dann eine Bildüberlagerung über der SurfaceView. Abhängig von der Qualität des Kopfbildes wirkt die gerenderte Qualität des Kopfbildes original. Ich hoffe es hilft.

0
OBX