Colocar una vista de imagen como imagen de superposición en la vista previa de la cámara

Hola Estoy codificando una aplicación de cámara con Android Camera API!

Tiene las siguientes funciones:

  • La aplicación tiene una vista de imagen sobre la vista previa de la cámara
  • El usuario puede arrastrar y soltar esa vista de imagen en la vista previa de la cámara
  • El evento de caída captura la posición de la vista de imagen donde se cayó
  • El usuario captura una imagen y la vista de imagen se agrega a la foto en la ubicación deseada de arrastrar y soltar del usuario

Aquí está el código que se utiliza para la vista de la imagen arrastrar y soltar:

@Override public boolean onTouch(View view, MotionEvent event) { final int X = (int) event.getRawX(); final int Y = (int) event.getRawY(); switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) view.getLayoutParams(); _xDelta = X - lParams.leftMargin; _yDelta = Y - lParams.topMargin; break; case MotionEvent.ACTION_UP: xloc=X; yloc=Y; Toast.makeText(getContext(), "Location==="+Integer.toString(xloc)+"==="+Integer.toString(yloc), Toast.LENGTH_SHORT).show(); break; case MotionEvent.ACTION_POINTER_DOWN: break; case MotionEvent.ACTION_POINTER_UP: break; case MotionEvent.ACTION_MOVE: RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view .getLayoutParams(); layoutParams.leftMargin = X - _xDelta; layoutParams.topMargin = Y - _yDelta; layoutParams.rightMargin = -250; layoutParams.bottomMargin = -250; view.setLayoutParams(layoutParams); break; } mRrootLayout.invalidate(); return true; } 

¡El xloc y el yloc contienen la posición donde el usuario dejará caer esa visión de la imagen!


Este es el código que estoy usando para determinar la orientación del dispositivo. Está siendo realizado por el sensor, ya que la actividad está configurada como retrato en manifest.xml por defecto

  @Override public void onSensorChanged(SensorEvent event) { float x = event.values[0]; float y = event.values[1]; if (x < 5 && x > -5 && y > 5){ //portrait UP ↑↑↑ cam_orientation = 0; image_watermark.setRotation(0); //rotating the water mark with screen orientation } else if (x<-5 && y<5 && y>-5) { //landscape RIGHT →→→ cam_orientation = 3; image_watermark.setRotation(270); } else if (x<5 && x>-5 && y<-5) { //Portrait DOWN ↓↓↓ cam_orientation = 4; image_watermark.setRotation(0); } else if (x>5 && y<5 && y>-5){ //Landscape LEFT ←←← cam_orientation = 1; image_watermark.setRotation(90); } } 

Aquí está el código para capturar la imagen

  private Camera.PictureCallback mPicture = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { File pictureFile = getOutputMediaFile(1); if (pictureFile == null){ Log.i("#LOGTAG pic","Exception"); return; } try { //rotate the image view as expected BitmapFactory.Options options = new BitmapFactory.Options(); Bitmap mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options); if(cam_orientation==0){ //portrait UP ↑↑↑ if(cam_id==1){ //this is front camera id=1 mBitmap= rotate(mBitmap, 270); mBitmap=flip(mBitmap); } if(cam_id==0){ mBitmap= rotate(mBitmap, 90); } } if(cam_orientation==1){ //Landscape LEFT ←←← if(cam_id==1){ //this is front camera id=1 mBitmap= rotate(mBitmap, 0); mBitmap=flip(mBitmap); } if(cam_id==0){ //this is back camera id=0 mBitmap= rotate(mBitmap, 0); } } if(cam_orientation==3){ //landscape RIGHT →→→ if(cam_id==1){ //this is front camera id=1 mBitmap= rotate(mBitmap, 180); mBitmap=flip(mBitmap); } if(cam_id==0){ //this is back camera id=0 mBitmap= rotate(mBitmap, 180); } } if(cam_orientation==4){ //Portrait DOWN ↓↓↓ if(cam_id==1){ //this is front camera id=1 mBitmap= rotate(mBitmap, 90); mBitmap=flip(mBitmap); } if(cam_id==0){ //this is back camera id=0 mBitmap= rotate(mBitmap, 270); } } //add the water mark to the camera photo bitmap here Bitmap mutableBitmap = mBitmap.copy(Bitmap.Config.ARGB_8888, true); image_watermark.buildDrawingCache(); Bitmap bmap = image_watermark.getDrawingCache(); Bitmap final_image=Bitmap.createScaledBitmap(bmap,(image_watermark.getMeasuredWidth())*2,(image_watermark.getMeasuredWidth())*2,false); Canvas canvas = new Canvas(mutableBitmap); if(cam_id==1){ canvas.drawBitmap(icon,(int)(xloc*1.5),(int)(yloc*1.5), null); //setting the location of the water mark image view on front camera/photo } if(cam_id==0){ canvas.drawBitmap(icon,xloc*2,yloc*2, null); //setting the location of the water mark image view on back camera/photo } FileOutputStream fos = new FileOutputStream(pictureFile); mutableBitmap.compress(Bitmap.CompressFormat.JPEG,100,fos); fos.close(); } 

¡Tengo un problema de fijar la localización de la opinión de la imagen de la marca de agua en la foto capturada de la cámara! Sólo quiero establecer la ubicación de la imagen de marca de agua para establecer la vista donde el usuario arrastró y dejó caer esa marca de agua vista de la imagen.

Aunque el código funciona bien, pero hay una falta de precisión y precisión en la configuración de la imagen de marca de agua vista ubicación en la foto capturada para diferentes dispositivos.

He estado intentando en diversos dispositivos, pero cada dispositivo distorsiona la posición exacta.

¿Puede alguien darme alguna idea o un mejor enfoque para agregar una imagen de marca de agua en la foto de la cámara capturada!

Tenga en cuenta que los ids para la cámara son:

  cam_id=1 for the from camera cam_id=0 for the back camera 

Necesito un acercamiento, de modo que podría capaz de colocar mi marca de agua marca en todos los modos de orientación del dispositivo y por lo menos algunos dispositivos múltiples.

Introduzca aquí la descripción de la imagen Gracias

Supongamos que si arrasto mi vista de imagen en este botón azul cuando la pantalla está en posición vertical, la imagen debe ser guardada en la foto de la cámara capturada en la misma ubicación que está en el botón azul! Introduzca aquí la descripción de la imagen

Del mismo modo, si lo puse en esa caja de la cámara capturada foto debe posicionar esta imagen ver lo mismo en ese cuadro en modo de paisaje!

Aquí está el XML usado a continuación

  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=""> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:background="@color/colorAccent"> <ToggleButton android:id="@+id/flipper" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="" android:background="@drawable/my_btn_toggle" android:textOff="" android:textOn=""/> </LinearLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="10" android:id="@+id/root"> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/camera_preview"> </FrameLayout> <ImageView android:layout_width="0dp" android:layout_height="0dp" android:id="@+id/watermark" /> </RelativeLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:background="#000" android:layout_alignParentBottom="true" android:gravity="center" android:id="@+id/capture_layout"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/capture" android:text="Capture" android:layout_alignParentBottom="true" android:layout_alignParentRight="true"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/neg" android:text="Cancel Para" android:layout_alignParentBottom="true" android:layout_alignParentRight="true"/> </LinearLayout> </LinearLayout> </RelativeLayout> 

Puede convertir View Containing Camera View y su marca de agua en mapa de bits y guárdelo en la memoria del teléfono sin capturar la imagen directamente desde la cámara. Funcionará como una captura de pantalla. Y su marca de agua se colocará en la misma ubicación de su aparición.

Asegúrese de que la vista de cámara y la vista de imagen de marca de agua estén en la misma vista principal y convierta su vista principal en mapa de bits.

Este enlace puede ayudarle.

Trata eso :

Extienda su SurfaceView y reemplace el método onDraw (). Allí puede insertar su imagen en la vista previa. Y puedes añadirlo en el Jpeqcall después de eso

Simplemente reemplace su Camera.PictureCallback con esta:

 private Camera.PictureCallback mPicture = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { File pictureFile = getOutputMediaFile(1); if (pictureFile == null){ Log.i("#LOGTAG pic","Exception"); return; } //rotate the image view as expected Bitmap mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length); if(cam_orientation==0){ //portrait UP ↑↑↑ if(cam_id==1){ //this is front camera id=1 mBitmap= rotate(mBitmap, 270); mBitmap=flip(mBitmap); } if(cam_id==0){ mBitmap= rotate(mBitmap, 90); } } if(cam_orientation==1){ //Landscape LEFT ←←← if(cam_id==1){ //this is front camera id=1 mBitmap= rotate(mBitmap, 0); mBitmap=flip(mBitmap); } if(cam_id==0){ //this is back camera id=0 mBitmap= rotate(mBitmap, 0); } } if(cam_orientation==3){ //landscape RIGHT →→→ if(cam_id==1){ //this is front camera id=1 mBitmap= rotate(mBitmap, 180); mBitmap=flip(mBitmap); } if(cam_id==0){ //this is back camera id=0 mBitmap= rotate(mBitmap, 180); } } if(cam_orientation==4){ //Portrait DOWN ↓↓↓ if(cam_id==1){ //this is front camera id=1 mBitmap= rotate(mBitmap, 90); mBitmap=flip(mBitmap); } if(cam_id==0){ //this is back camera id=0 mBitmap= rotate(mBitmap, 270); } } Bitmap newImage = Bitmap.createBitmap( mBitmap.getWidth(), mBitmap.getHeight(), Bitmap.Config.ARGB_8888 ); Canvas canvas = new Canvas(newImage); canvas.drawBitmap(mBitmap, 0f, 0f, null); image_watermark.buildDrawingCache(); Drawable drawable = new BitmapDrawable(getResources(), image_watermark.getDrawingCache()); drawable.setBounds( xloc, yloc, image_watermark.getMeasuredWidth() + xloc, image_watermark.getMeasuredHeight() + yloc ); drawable.draw(canvas); try { FileOutputStream out = new FileOutputStream(pictureFile); newImage.compress(Bitmap.CompressFormat.JPEG, 100, out); out.flush(); out.close(); } catch (Exception e) { Log.d("In Saving File", e.getMessage(), e); } Log.d("Image", "Pic taken!"); // Camera preview should be started again after taking a picture camera.startPreview(); // Release image newImage.recycle(); newImage = null; } } 

Esto debería solucionar tu problema.

Puede utilizar esta biblioteca , se trata de una biblioteca de marcas de agua simples para Android, la conversión de XML (VIEW) a mapa de bits

 private Bitmap generateWaterMark(Bitmap src) { //src is your original image, like camera preview WaterMark waterMark = new WaterMark(this); View view = getLayoutInflater().inflate(R.layout.register_email_layout, null, false); //Manipulate your view like you prefer, then invoke the method getImageWaterMarkFromView return waterMark.getImageWaterMarkFromView(src, view); } 
  • Android: trazado de dibujo como superposición en MapView
  • Entender boundCenterBottom ()
  • Android cómo dibujar la pintura en mano libre en MapView con superposición?
  • No lleve el botón al primer plano al hacer clic
  • Primera vista arriba / superpuesta en LinearLayout
  • Cómo obtener el largo y lat valor de cuatro esquinas en el mapa en android?
  • Cómo dibujar polígono mano libre en Google mapa V2 en Android?
  • Especifique Layout Margen superior para la barra de acción de superposición
  • ICS teclado de vuelta, los botones de inicio no tomar contacto cuando se abre en la superposición
  • Disposición de Android: coloca una vista entre dos vistas
  • RelativaLayout TextView superposición
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.