Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Tomar la imagen de la cámara personalizada se estira cuando guardar en ImageView

Estoy utilizando este código para guardar la imagen en Imageview, pero la imagen se estira cuando dsave en imageview. Previsualización de la cámara es prefecto y haga clic en la imagen de la derecha, pero cuando se establece que la imagen en imageview la imagen es stetched.

public void onPicTaken(byte[] data) { if (data != null) { int screenWidth = getResources().getDisplayMetrics().widthPixels; int screenHeight = getResources().getDisplayMetrics().heightPixels; Bitmap bm = BitmapFactory.decodeByteArray(data, 0, (data != null) ? data.length : 0); if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { // Notice that width and height are reversed Bitmap scaled = Bitmap.createScaledBitmap(bm, screenHeight, screenWidth, true); int w = scaled.getWidth(); int h = scaled.getHeight(); // Setting post rotate to 90 Matrix mtx = new Matrix(); mtx.postRotate(90); // Rotating Bitmap bm = Bitmap.createBitmap(scaled, 0, 0, w, h, mtx, true); }else{// LANDSCAPE MODE //No need to reverse width and height Bitmap scaled = Bitmap.createScaledBitmap(bm, screenWidth,screenHeight , true); bm=scaled; } ivCaptureImagePreview.setImageBitmap(bm); ivCaptureImagePreview.setVisibility(View.VISIBLE); } } 

  • Configuración de JAVA_HOME en SDK de Android
  • Android - Aceleración hacia abajo (smash)
  • Android, ¿Cómo puedo convertir la cadena a la fecha?
  • Se inicia la actividad de detección para obtener resultados
  • Java.lang.Void vs void vs Null
  • Uses-permission vs permission para los permisos de android en el archivo manifest.xml
  • No es capaz de "findViewById" en Kotlin. Error de obtención "Inferencia de tipo no"
  • Problema al instalar el controlador USB de Android en Galaxy SII
  • Compilar el proyecto de Android desde la línea de comandos es lento
  • Cómo borrar fragmento backstack en android
  • Actividad que extiende ActionBarActivity y YouTubeBaseActivity
  • Instalación de ADT en Eclipse
  • 7 Solutions collect form web for “Tomar la imagen de la cámara personalizada se estira cuando guardar en ImageView”

    Utilice la siguiente clase para crear mapas de bits escalados

     public class ScalingUtilities { /** * Utility function for decoding an image resource. The decoded bitmap will * be optimized for further scaling to the requested destination dimensions * and scaling logic. * * @param res The resources object containing the image data * @param resId The resource id of the image data * @param dstWidth Width of destination area * @param dstHeight Height of destination area * @param scalingLogic Logic to use to avoid image stretching * @return Decoded bitmap */ public static Bitmap decodeResource(Resources res, int resId, int dstWidth, int dstHeight, ScalingLogic scalingLogic) { Options options = new Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(res, resId, options); options.inJustDecodeBounds = false; options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth, dstHeight, scalingLogic); Bitmap unscaledBitmap = BitmapFactory.decodeResource(res, resId, options); return unscaledBitmap; } /** * Utility function for creating a scaled version of an existing bitmap * * @param unscaledBitmap Bitmap to scale * @param dstWidth Wanted width of destination bitmap * @param dstHeight Wanted height of destination bitmap * @param scalingLogic Logic to use to avoid image stretching * @return New scaled bitmap object */ public static Bitmap createScaledBitmap(Bitmap unscaledBitmap, int dstWidth, int dstHeight, ScalingLogic scalingLogic) { Rect srcRect = calculateSrcRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(), dstWidth, dstHeight, scalingLogic); Rect dstRect = calculateDstRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(), dstWidth, dstHeight, scalingLogic); Bitmap scaledBitmap = Bitmap.createBitmap(dstRect.width(), dstRect.height(), Config.ARGB_8888); Canvas canvas = new Canvas(scaledBitmap); canvas.drawBitmap(unscaledBitmap, srcRect, dstRect, new Paint(Paint.FILTER_BITMAP_FLAG)); return scaledBitmap; } /** * ScalingLogic defines how scaling should be carried out if source and * destination image has different aspect ratio. * * CROP: Scales the image the minimum amount while making sure that at least * one of the two dimensions fit inside the requested destination area. * Parts of the source image will be cropped to realize this. * * FIT: Scales the image the minimum amount while making sure both * dimensions fit inside the requested destination area. The resulting * destination dimensions might be adjusted to a smaller size than * requested. */ public static enum ScalingLogic { CROP, FIT } /** * Calculate optimal down-sampling factor given the dimensions of a source * image, the dimensions of a destination area and a scaling logic. * * @param srcWidth Width of source image * @param srcHeight Height of source image * @param dstWidth Width of destination area * @param dstHeight Height of destination area * @param scalingLogic Logic to use to avoid image stretching * @return Optimal down scaling sample size for decoding */ public static int calculateSampleSize(int srcWidth, int srcHeight, int dstWidth, int dstHeight, ScalingLogic scalingLogic) { if (scalingLogic == ScalingLogic.FIT) { final float srcAspect = (float)srcWidth / (float)srcHeight; final float dstAspect = (float)dstWidth / (float)dstHeight; if (srcAspect > dstAspect) { return srcWidth / dstWidth; } else { return srcHeight / dstHeight; } } else { final float srcAspect = (float)srcWidth / (float)srcHeight; final float dstAspect = (float)dstWidth / (float)dstHeight; if (srcAspect > dstAspect) { return srcHeight / dstHeight; } else { return srcWidth / dstWidth; } } } /** * Calculates source rectangle for scaling bitmap * * @param srcWidth Width of source image * @param srcHeight Height of source image * @param dstWidth Width of destination area * @param dstHeight Height of destination area * @param scalingLogic Logic to use to avoid image stretching * @return Optimal source rectangle */ public static Rect calculateSrcRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight, ScalingLogic scalingLogic) { if (scalingLogic == ScalingLogic.CROP) { final float srcAspect = (float)srcWidth / (float)srcHeight; final float dstAspect = (float)dstWidth / (float)dstHeight; if (srcAspect > dstAspect) { final int srcRectWidth = (int)(srcHeight * dstAspect); final int srcRectLeft = (srcWidth - srcRectWidth) / 2; return new Rect(srcRectLeft, 0, srcRectLeft + srcRectWidth, srcHeight); } else { final int srcRectHeight = (int)(srcWidth / dstAspect); final int scrRectTop = (int)(srcHeight - srcRectHeight) / 2; return new Rect(0, scrRectTop, srcWidth, scrRectTop + srcRectHeight); } } else { return new Rect(0, 0, srcWidth, srcHeight); } } /** * Calculates destination rectangle for scaling bitmap * * @param srcWidth Width of source image * @param srcHeight Height of source image * @param dstWidth Width of destination area * @param dstHeight Height of destination area * @param scalingLogic Logic to use to avoid image stretching * @return Optimal destination rectangle */ public static Rect calculateDstRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight, ScalingLogic scalingLogic) { if (scalingLogic == ScalingLogic.FIT) { final float srcAspect = (float)srcWidth / (float)srcHeight; final float dstAspect = (float)dstWidth / (float)dstHeight; if (srcAspect > dstAspect) { return new Rect(0, 0, dstWidth, (int)(dstWidth / srcAspect)); } else { return new Rect(0, 0, (int)(dstHeight * srcAspect), dstHeight); } } else { return new Rect(0, 0, dstWidth, dstHeight); } } } 

    Y utilizar esta clase en su función como a continuación

     public void onPicTaken(byte[] data) { if (data != null) { int screenWidth = getResources().getDisplayMetrics().widthPixels; int screenHeight = getResources().getDisplayMetrics().heightPixels; Bitmap bm = BitmapFactory.decodeByteArray(data, 0, (data != null) ? data.length : 0); if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { // Notice that width and height are reversed Bitmap scaled = ScalingUtilities.createScaledBitmap(bm, screenHeight, screenWidth, ScalingLogic.FIT); int w = scaled.getWidth(); int h = scaled.getHeight(); // Setting post rotate to 90 Matrix mtx = new Matrix(); mtx.postRotate(90); // Rotating Bitmap bm = Bitmap.createBitmap(scaled, 0, 0, w, h, mtx, true); }else{// LANDSCAPE MODE //No need to reverse width and height Bitmap scaled = ScalingUtilities.createScaledBitmap(bm, screenHeight, screenWidth, ScalingLogic.FIT); bm=scaled; } ivCaptureImagePreview.setImageBitmap(bm); ivCaptureImagePreview.setVisibility(View.VISIBLE); } } 

    Configuración de UIImageView

     <ImageView android:id="@id/img" android:layout_width="match_parent" android:layout_height="wrap_content" android:adjustViewBounds="true" android:scaleType="fitCenter" /> 

    Mi aplicación de prueba para este problema

    Para obtener la imagen de la cámara, utilizo los siguientes métodos:

     private void pickImageIntent() { Intent pickPhoto = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); getCurrentActivity().startActivityForResult(pickPhoto, REQUEST_PICK_IMAGE); } private void takeImageIntent() { try { File outputDir = getCurrentActivity().getExternalCacheDir(); File outputFile = File.createTempFile("prefix", "extension", outputDir); selectedImageUri = Uri.fromFile(outputFile); Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); takePicture.putExtra(MediaStore.EXTRA_OUTPUT, selectedImageUri); getCurrentActivity().startActivityForResult(takePicture, REQUEST_TAKE_IMAGE); } catch (IOException e) { e.printStackTrace(); } } 

    Para obtener el resultado de la cámara o el selector de imágenes, y muéstrelo en la imagenVista. Aquí this.myInterfaceImage :

     public void onActivityResult(int requestCode, int resultCode, Intent data) { switch(requestCode) { case REQUEST_PICK_IMAGE: if(resultCode == Activity.RESULT_OK) { selectedImageUri = data.getData(); initImage(selectedImageUri); } break; case REQUEST_TAKE_IMAGE: if(resultCode == Activity.RESULT_OK) { initImage(selectedImageUri); } break; } } protected void initImage(Uri selectedImageUri_) { try { ParcelFileDescriptor parcelFileDescriptor = getContext().getContentResolver().openFileDescriptor(selectedImageUri_, "r"); FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(); Bitmap source = BitmapFactory.decodeFileDescriptor(fileDescriptor); float ratio = (float)source.getWidth() / (float)source.getHeight(); // here perhaps limit the size of the image int height = Math.min(getContext().getResources().getDisplayMetrics().heightPixels, source.getHeight()); int width = (int)(ratio*height); Bitmap result = Bitmap.createScaledBitmap(source, width, height, false); this.interfaceImage.setImageBitmap(result); if (result != source) { source.recycle(); } } catch (Exception ex) { System.out.println("File not found"); } } 

    Así es como lo utilicé en Mi aplicación de prueba y funciona. No tengo problemas de orientación. He probado en el modo vertical con retrato y paisaje, y en modo horizontal con retrato y paisaje. Y con ambos en donde cambié la orientación después de conseguir la imagen.

    Si está usando la cámara personalizada y la orientación es incorrecta con el código anterior, simplemente añada esto

    Hay dos cosas necesarias:

    1. La vista previa de la cámara necesita lo mismo que su rotación. Establecer esto por

      camera.setDisplayOrientation(result);

    2. Guarde la imagen capturada como previsualización de la cámara. Haga esto a través de Camera.Parameters.

      int mRotation = getCameraDisplayOrientation(); Camera.Parameters parameters = camera.getParameters(); parameters.setRotation(mRotation); //set rotation to save the picture camera.setDisplayOrientation(result); //set the rotation for preview camera camera.setParameters(parameters);

    A continuación, puede utilizar su función sin la orientación de cosas

     public void onPicTaken(byte[] data) { if (data != null) { Bitmap bm = BitmapFactory.decodeByteArray(data, 0, (data != null) ? data.length : 0); int screenWidth = getResources().getDisplayMetrics().widthPixels; float ratio = (float)bm.getWidth() / (float)bm.getHeight(); int screenHeight = (int)(ratio*screenWidth) Bitmap scaled = Bitmap.createScaledBitmap(bm, screenHeight, screenWidth, true); if (scaled != bm) { source.recycle(); } ivCaptureImagePreview.setImageBitmap(scaled); ivCaptureImagePreview.setVisibility(View.VISIBLE); } } 

    Espero que ayude.

    Utilice esto para evitar que la imagen se estire y mantenga la relación de aspecto de la imagen

     android:scaleType="fitXY" // or desired scale type android:adjustViewBounds="true" 

    Utilizo esta función en mi proyecto, por favor compruebe si es útil para usted.

     public static Bitmap Preview(String path) { //SCALE IMAGE int SCALE = 4; try { BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize = SCALE; Bitmap bitmap = BitmapFactory.decodeFile(path, o2); OutputStream os = new FileOutputStream(path); bitmap.compress(Bitmap.CompressFormat.PNG, 100, os); os.flush(); os.close(); File file = new File(path); while (file.length() > 800000) { SCALE += 2; o2.inSampleSize = SCALE; bitmap = BitmapFactory.decodeFile(path, o2); os = new FileOutputStream(path); bitmap.compress(Bitmap.CompressFormat.PNG, 100, os); os.flush(); os.close(); file = new File(path); } bitmap = BitmapFactory.decodeFile(path, o2); return bitmap; } catch (Exception e) { e.printStackTrace(); return null; } } 

    Puede establecer scaleType en xml

     <ImageView android:id="@+id/iv_imageview" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitCenter" /> 

    En código Java puede lograr lo mismo como este

     ImageView mImageView = (ImageView) findViewById(R.id.iv_imageview); mImageView.setScaleType(ImageView.ScaleType.FIT_CENTER); 

    Escala de su mapa de bits con Bitmap.createScaledBitmap(bm, screenHeight, screenWidth, true); No mantendrá la relación de aspecto porque esto se extenderá el ancho y la altura del mapa de bits para coincidir con el destino.

    Una opción sería calcular la altura objetivo manualmente para que no se produzca ningún cultivo:

     double aspectRatio = (double) source.getHeight() / (double) source.getWidth(); int targetHeight = (int) (screenWidth * aspectRatio); 

    Y luego use targetHeight lugar de screenHeight como argumento height en createScaledBitmap ().

    Además, asegúrese de que la vista de imagen en la que cargue su mapa de bits tenga el tipo de escala apropiado (por ejemplo, FIT_CENTER o CENTER_CROP).

    Utilizar este putExtra en su intención de llamar a la cámara

     intent.putExtra("outputX", 80); intent.putExtra("outputY", 80); intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); intent.putExtra("scale", true); intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, 20); intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); startActivityForResult(intent, Utility.REQUEST_FOR_CAMERA); 
    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.