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:
- Android ViewPager: fragmentos superpuestos cuando el ancho de página se establece en 90%
- ¿Hay alguna forma de que los elementos de la interfaz de usuario se superpongan ligeramente (uno encima del otro) sin usar diseños absolutos?
- Barra de navegación translúcida (Android 4.4) - Mostrar contenido debajo
- Alternativa de Android a MetroGridHelper
- Lista de clics dentro de OverlayItem (MapView para Android)
- 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.
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!
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>
- ¿Cómo mostrar una ruta entre dos geocoords en google maps?
- ¿Por qué mi sistema se superpone capturando todos los toques (no es posible interacción con la vista subyacente)
- Android: ItemizedOverlay onTouchEvent y onTap se superponen
- Aplicación de Android: mostrar elementos de superposición en AsyncTask
- Almacenamiento en caché de superposiciones al redondear rectángulos de coordenadas - ¿cómo?
- ¿Cómo puedo poner una vista encima de un glSurfaceView con un fondo transparente?
- ¿Se puede ampliar el tamaño de la superposición con el mapa de google en android?
- ¿Cómo crear una superposición que bloquea los eventos de toque a la interfaz de usuario debajo de él?
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); }
- La realización de una exploración UPNP no devuelve el puente Philips Hue
- Intervalo de números seguro para mi propio ID en diseño dinámico?