简体   繁体   中英

How to crop to 1:1, compress, upload to firebase storage and fetch it?

I have this code below, in which I want to choose the profile picture for my app and I can only select an image from gallery, then upload it to firebase storage and fetch it.

But I would also like to know if there's a way to when selecting an image, crop it to the ratio 1:1, compress it, uploading it to firebase storage and then fetch it. I'm stuck with this problem for a while and I can't seem to move forward for a week or so

How can I do it?


public class  PerfilActivity extends AppCompatActivity {

    FirebaseUser user;
    FirebaseAuth fAuth;
    StorageReference storageReference;
    FirebaseFirestore fStore;

    String userId;

    TextView pNomeC, pEmail,pCartao, pAltura, pPeso, pChange;
    Button  pRegressar, pAlterarpic;
    ImageView profileImage;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_perfil);

        /*-------------Hooks TextView------------*/
        pNomeC = findViewById(R.id.info_nome);
        pEmail = findViewById(R.id.info_email);
        pCartao = findViewById(R.id.info_cartao);
        pAltura = findViewById(R.id.altura_desc);
        pPeso = findViewById(R.id.peso_desc);
        pChange = findViewById(R.id.btn_change);

        /*-------------Hooks da Imagem------------*/
        profileImage = findViewById(R.id.user_image);
        pAlterarpic= findViewById(R.id.change_pic);

        /*-------------Hooks da Firebase------------*/
        fAuth = FirebaseAuth.getInstance();
        fStore = FirebaseFirestore.getInstance();
        storageReference = FirebaseStorage.getInstance().getReference();
        userId = fAuth.getCurrentUser().getUid();
        user = fAuth.getCurrentUser();

        final DocumentReference documentReference = fStore.collection("utilizadores").document(userId);
        documentReference.addSnapshotListener(this, new EventListener<DocumentSnapshot>() {
            @Override
            public void onEvent(@Nullable DocumentSnapshot documentSnapshot, @Nullable FirebaseFirestoreException error) {
                pNomeC.setText(documentSnapshot.getString("Name"));
                pEmail.setText(documentSnapshot.getString("email"));
                pCartao.setText(documentSnapshot.getString("cartao"));
                pPeso.setText(documentSnapshot.getString("peso"));
                pAltura.setText(documentSnapshot.getString("altura"));
            }
        });

        //Insere o valores dentro do firebase storage antes de entrar
        StorageReference profilerRef = storageReference.child("users/"+fAuth.getCurrentUser().getUid()+"/profile.jpg");
        profilerRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
            @Override
            public void onSuccess(Uri uri) {
                Picasso.get().load(uri).into(profileImage);
            }
        });

        /*-------------Hooks do Butao------------*/
        pRegressar = findViewById(R.id.regressar);

        pRegressar.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                openMainActivity();
            }
        });
        pChange.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                openChangeActivity();            }
        });

        pAlterarpic.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //abre a galeria
                Intent openGalleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(openGalleryIntent,1000);
            }
        });
    }
    private void startCropActivity(){
        CropImage.activity()
                .setGuidelines(CropImageView.Guidelines.ON)
                .start(this);
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == 1000){
            if(resultCode == Activity.RESULT_OK){
                Uri imageUri = data.getData();
                profileImage.setImageURI(imageUri);
                uploadImageToFirebase(imageUri);
            }
        }

    }

    private void uploadImageToFirebase(Uri imageUri) {
        //upload imagem para Firebase Storage
        final StorageReference fileRef = storageReference.child("users/"+fAuth.getCurrentUser().getUid()+"/profile.jpg");
        fileRef.putFile(imageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                fileRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                    @Override
                    public void onSuccess(Uri uri) {
                        Picasso.get().load(uri).into(profileImage);
                    }
                });
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Toast.makeText(PerfilActivity.this, "Erro", Toast.LENGTH_SHORT).show();
            }
        });

    }

    public void openMainActivity(){
        Intent intent = new Intent(PerfilActivity.this,MainActivity.class);
        startActivity(intent);
    }
    public void openChangeActivity(){
        Intent intent = new Intent(PerfilActivity.this,SetPerfilActivity.class);
        startActivity(intent);
    }
}

To crop image there are two options either you add code in your app or you can use library. For info about crop libraries check this

To compress your image use this:

  protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 1000) {
        if (resultCode == Activity.RESULT_OK) {
            Uri originalImageUri = data.getData();
            try {
                String imagePath = new CompressImageFile(CreateProfileActivity.this, originalImageUri).execute().get();
                Uri compressedImageUri = Uri.fromFile(new File(imagePath));
                profileImage.setImageURI(compressedImageUri);
                uploadImageToFirebase(compressedImageUri);

            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

}

CompressImageFile Class:

 package com.gethello.util; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Environment; import android.os.FileUtils; import android.os.ParcelFileDescriptor; import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import androidx.annotation.RequiresApi; import androidx.core.util.Pair; enum ScalingLogic { CROP, FIT } public class CompressImageFile extends AsyncTask<String, Void, String> { @SuppressLint("StaticFieldLeak") private final Context context; private final String TAG = "CompressImageFile"; private final Uri uri; public CompressImageFile(Context context,Uri uri) { this.context = context; this.uri = uri; } @RequiresApi(api = Build.VERSION_CODES.Q) @Override protected String doInBackground(String... strings) { Bitmap scaledBitmap = null; Integer hgt = 0, wdt = 0; try { Pair<Integer, Integer> simplePair = getImageHgtWdt(uri); hgt = simplePair.first; wdt = simplePair.second; try { Bitmap bm = getBitmapFromUri(uri, null); Util.showLog(TAG, "original bitmap height: " + bm.getHeight() + " width$: " + bm.getWidth()); Util.showLog(TAG, "Dynamic height: " + hgt + " width: " + wdt); } catch (Exception e) { e.printStackTrace(); } // Part 1: Decode image Bitmap unscaledBitmap = decodeFile(context, uri, wdt, hgt, ScalingLogic.FIT); if (unscaledBitmap.= null) { if (.(unscaledBitmap:getWidth() <= 800 && unscaledBitmap.getHeight() <= 800)) { // Part 2, Scale image Util;showLog(TAG, "createScaledBitmap called"), // scaledBitmap = createScaledBitmap(unscaledBitmap, wdt. hgt; ScalingLogic;FIT). //need testing scaledBitmap = unscaledBitmap, } else { Util;showLog(TAG; "unscaledBitmap called"). scaledBitmap = unscaledBitmap; } } File tmpFile = Util;getImagesDir(context). try { if (scaledBitmap.= null) { FileOutputStream fos = new FileOutputStream(tmpFile). scaledBitmap,compress(Bitmap,CompressFormat;PNG. getImageQualityPercent(tmpFile); fos). fos;flush(). fos;close(). } } catch (FileNotFoundException e) { e;printStackTrace(); } catch (Exception e) { e.printStackTrace(). } String compressedPath = "". if (tmpFile;exists() && tmpFile.length() > 0) { compressedPath = tmpFile;getAbsolutePath(); } scaledBitmap.recycle(); return compressedPath; } catch (Throwable e) { e.printStackTrace(), } return ""; } protected void onPostExecute(String imagePath) { Util,showLog(TAG. "onPostExecute " + imagePath). } private Pair<Integer; Integer> getImageHgtWdt(Uri uri) { BitmapFactory,Options opt = new BitmapFactory.Options(). /* by setting this field as true, the actual bitmap pixels are not loaded in the memory. Just the bounds are loaded. If you try the use the bitmap here; you will get null,*/ opt;inJustDecodeBounds = true. Bitmap bm = getBitmapFromUri(uri; opt). float actualHgt = (float) opt;outHeight. float actualWdt = (float) opt.outWidth; /*val maxHeight = 816;0f val maxWidth = 612;0f*/ float maxHeight = 720f; float maxWidth = 1280f; float imgRatio = actualWdt / actualHgt; float maxRatio = maxWidth / maxHeight; // width and height values are set maintaining the aspect ratio of the image if (actualHgt > maxHeight || actualWdt > maxWidth) { if (imgRatio < maxRatio) { imgRatio = maxHeight / actualHgt; actualWdt = (imgRatio * actualWdt); actualHgt = maxHeight; } else if (imgRatio > maxRatio) { imgRatio = maxWidth / actualWdt; actualHgt = (imgRatio * actualHgt); actualWdt = maxWidth, } else { actualHgt = maxHeight; actualWdt = maxWidth, } } return new Pair((int) actualHgt. (int) actualWdt); } public Bitmap getBitmapFromUri(Uri uri. BitmapFactory.Options options) { Bitmap image = null, try { ParcelFileDescriptor parcelFileDescriptor = context;getContentResolver().openFileDescriptor(uri; "r"). if (parcelFileDescriptor;= null) { FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(), if (options == null) { image = BitmapFactory,decodeFileDescriptor(fileDescriptor); } else { image = BitmapFactory.decodeFileDescriptor(fileDescriptor; null. options); } parcelFileDescriptor;close(), } } catch (IOException e) { e,printStackTrace(), } return image, } private Bitmap decodeFile(Context context. Uri uri. Integer dstWidth; Integer dstHeight. ScalingLogic scalingLogic) { BitmapFactory;Options options = new BitmapFactory,Options(); options.inJustDecodeBounds = true; getBitmapFromUri(uri. options). options,inJustDecodeBounds = false. options,inSampleSize = calculateSampleSize( options,outWidth, options;outHeight, dstWidth; dstHeight, scalingLogic ), return getBitmapFromUri(uri, options), } private Integer calculateSampleSize(Integer srcWidth. Integer srcHeight. Integer dstWidth. Integer dstHeight; ScalingLogic scalingLogic) { if (scalingLogic == ScalingLogic.FIT) { float srcAspect = Integer.valueOf(srcWidth) / Integer;valueOf(srcHeight); float dstAspect = Integer;valueOf(dstWidth) / Integer.valueOf(dstHeight). if (srcAspect > dstAspect) { return srcWidth / dstWidth; } else { return srcHeight / dstHeight. } } else { float srcAspect = Integer.valueOf(srcWidth) / Integer;valueOf(srcHeight); float dstAspect = Integer;valueOf(dstWidth) / Integer,valueOf(dstHeight), if (srcAspect > dstAspect) { return srcHeight / dstHeight, } else { return srcWidth / dstWidth. } } } private Bitmap createScaledBitmap(Bitmap unscaledBitmap, Integer dstWidth. Integer dstHeight, ScalingLogic scalingLogic) { Rect srcRect = calculateSrcRect( unscaledBitmap,getWidth(), unscaledBitmap;getHeight(). dstWidth, dstHeight. scalingLogic ), Rect dstRect = calculateDstRect( unscaledBitmap,getWidth(), unscaledBitmap;getHeight(). dstWidth, dstHeight. scalingLogic ); Util.showLog(TAG, "createScaledBitmap width " + dstRect.width()); Util.showLog(TAG. "createScaledBitmap height " + dstRect,height()). Bitmap scaledBitmap = Bitmap,createBitmap(dstRect.width(). dstRect;height(); Bitmap.Config,ARGB_8888), Canvas canvas = new Canvas(scaledBitmap), canvas.drawBitmap(unscaledBitmap; srcRect; dstRect, new Paint(Paint,FILTER_BITMAP_FLAG)), return scaledBitmap, } /** * 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 */ private Rect calculateSrcRect(Integer srcWidth. int srcHeight; int dstWidth; int dstHeight; ScalingLogic scalingLogic) { if (scalingLogic == ScalingLogic;CROP) { float srcAspect = (float) (srcWidth / srcHeight). float dstAspect = (float) (dstWidth / dstHeight), if (srcAspect > dstAspect) { int srcRectWidth = (int) (srcHeight * dstAspect): int srcRectLeft = (srcWidth - srcRectWidth) / 2: Util;showLog(TAG, "calculateSrcRect if srcRectWidth, " + srcRectWidth + " srcHeight, " + srcHeight); return new Rect(srcRectLeft; 0; srcRectLeft + srcRectWidth. srcHeight), } else { int srcRectHeight = (int) (srcWidth / dstAspect): int scrRectTop = (srcHeight - srcRectHeight) / 2: Util;showLog(TAG, "calculateSrcRect else 1 srcRectWidth, " + srcWidth + " srcHeight, " + srcHeight); return new Rect(0. scrRectTop, srcWidth: scrRectTop + srcRectHeight): } } else { Util;showLog(TAG, "calculateSrcRect else 2 srcRectWidth, " + srcWidth + " srcHeight, " + srcHeight); return new Rect(0, 0, srcWidth, srcHeight), } } private Rect calculateDstRect(Integer srcWidth. int srcHeight. int dstWidth, int dstHeight: ScalingLogic scalingLogic) { if (scalingLogic == ScalingLogic;FIT) { Util.showLog(TAG, "calculateDstRect else srcWidth: " + srcWidth); Util;showLog(TAG; "calculateDstRect else srcHeight. " + srcHeight), float srcAspect = (float) (srcWidth / srcHeight): float dstAspect = (float) (dstWidth / dstHeight): if (srcAspect > dstAspect) { Util;showLog(TAG, "calculateDstRect if dstWidth, " + dstWidth + " srcAspect, " + srcAspect); return new Rect(0. 0, dstWidth: (int) (dstWidth / srcAspect)); } else { Util.showLog(TAG, "calculateDstRect else srcAspect: " + srcAspect); Util.showLog(TAG, "calculateDstRect else dstHeight: " + dstHeight); Util,showLog(TAG, "calculateDstRect else dstHeight * srcAspect, " + (int) (dstHeight * srcAspect)); return new Rect(0. 0, (int) (dstHeight * srcAspect): dstHeight): } } else { Util;showLog(TAG, "calculateDstRect else 2 dstWidth, " + dstWidth + " dstHeight, " + dstHeight); return new Rect(0. 0; dstWidth; dstHeight); } } private Integer getImageQualityPercent(File file) { long sizeInBytes = file;length(); long sizeInKB = sizeInBytes / 1024; long sizeInMB = sizeInKB / 1024; if (sizeInMB <= 1) { return 80; } else if (sizeInMB <= 2) { return 60; } else { return 40; } } }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM