Home > Mobile >  How to convert a Fragment layout to a bitmap and send it by email without saving any file (Kotlin 20
How to convert a Fragment layout to a bitmap and send it by email without saving any file (Kotlin 20

Time:01-25

I am developing an Android app using Kotlin. I need to convert a layout (that is actually a report of the user's input data, some views converted to bitmap in imageviews and extra text) and send it by email as .pdf when the user clicks on a button inside the fragment (that is the previsualisation of the future PDF) without saving it.

I've read and watched hours of tutorials but none is helping (deprecated, old java or saving the file)

I guess I need a function that converts the desired view to a bitmap image, scales it to A4 size format, sets that scaled image to pdf file and returns it so I can then put it as an attachment to mail Intent,not forgetting I am inside a fragment.

I will be updating the post. Thank you

EDIT : I already know how to convert a layout to bitmap and put it inside an image view (I can share if someone needs). So I only need a function that takes the bitmap as an argument and returns .pdf (or .jpg) and an other one that intents as attachment that returned pdf to send email

CodePudding user response:

What I gather, you need to create a screenshot of sorts of your view. This is something I did a while back so I have some java code, not yet converted to Kotlin, but AS can take care of that.

You can utilise a class PixelCopy, unfortunately it is Android O .

This is a simplified version of what you can do:

int[] viewLocationInWindow = new int[2];
view.getLocationInWindow(viewLocationInWindow);

int x = viewLocationInWindow[0];
int y = viewLocationInWindow[1];

int width = view.getWidth();
int height = view.getHeight();

Rect rectScope = new Rect(x, y, x   width, y   height);

Bitmap screenshotBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Handler handler = new Handler();
        
PixelCopy.request(getWindow(), rectScope, screenshotBitmap, copyResult -> {
            if (copyResult == PixelCopy.SUCCESS) {
                listener.onScreenshotSuccess(screenshotBitmap);
            } else {
                listener.onScreenshotError();
            }
            handler.removeCallbacksAndMessages(null);
        }, handler);

The view that is being referenced here should be your containing view. In my case, I had to take a screenshot of the entire view(the entire screen), so instead I did:

int width = Resources.getSystem().getDisplayMetrics().widthPixels;
int height = Resources.getSystem().getDisplayMetrics().heightPixels;

Then just implement the listener

public interface OnScreenshotTakenListener {
        void onScreenshotSuccess(Bitmap bitmap);
        
        void onScreenshotError();
    }

Inside onScreenshotSuccess you could modify the bitmap and do all of your other requirements.

CodePudding user response:

fun getDetailImage(){

    val image=getBitmapFromView(llParent)
    ivShareImage.setImageBitmap(image)
}

private fun getBitmapFromView(view: View): Bitmap? {

    //Define a bitmap with the same size as the view
    val returnedBitmap=Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
    //Bind a canvas to it
    val canvas=Canvas(returnedBitmap)
    //Get the view's background
    val bgDrawable=view.background
    if (bgDrawable != null) {
        //has background drawable, then draw it on the canvas
        bgDrawable.draw(canvas)
    } else {
        //does not have background drawable, then draw white background on the canvas
        canvas.drawColor(Color.WHITE)
    }
    // draw the view on the canvas
    view.draw(canvas)
    //return the bitmap
    return returnedBitmap
}

fun getShareImage(){
    getDetailImage()
    val mDrawable: Drawable=ivShareImage.getDrawable()
    val mBitmap=(mDrawable as BitmapDrawable).bitmap

    val path=MediaStore.Images.Media.insertImage(
        appCompatActivity.getContentResolver(),
        mBitmap,
        "image-name",
        null
    )
    val uri: Uri=Uri.parse(path)
    val shareIntent=Intent()
    shareIntent.action=Intent.ACTION_SEND
    shareIntent.putExtra(Intent.EXTRA_STREAM, uri)
    shareIntent.type="image/*"
    appCompatActivity.startActivity(Intent.createChooser(shareIntent, "Share Image"))
}
  •  Tags:  
  • Related