0

I am newbie when it comes to programming android. I am transferring images between the activity using both the ways i.e by using intent or by creating a file but it takes about 3 or 4 seconds to transfer image and show in imageview of second activity. Is there any way I can transfer faster then this because many application such as whatsapp are transferring at more faster rate. My code is given below. any help would be appreciated.

Code In first activity:

Camera.PictureCallback mPicture = new Camera.PictureCallback() {
                    @Override
                    public void onPictureTaken(byte[] data, Camera camera) {
                        mCamera.stopPreview();
                        Intent myintent = new Intent(CameraSetter.this,CameraPhotoViewer.class);
                        Bitmap bitmap_image = BitmapFactory.decodeByteArray(data, 0, data.length);
                        String fileName = "myImage";//no .png or .jpg needed
                        try {
                            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
                            bitmap_image.compress(Bitmap.CompressFormat.JPEG, 50, bytes);
                            FileOutputStream fo = openFileOutput(fileName, Context.MODE_PRIVATE);
                            fo.write(bytes.toByteArray());
                            // remember close file output
                            fo.close();
                            startActivity(myintent);
                        } catch (Exception e) {
                            e.printStackTrace();
                            fileName = null;
                        }

                    }
                };

and in second:

 Bitmap bitmap_image = BitmapFactory.decodeStream(getApplicationContext().openFileInput("myImage"));
imageview.setImageBitmap(bitmap_image);

It is working but I want more faster way any ideas?

Also tried with saving the image to internal storage but it also taking too much time.

code is:

In first activity:

Camera.PictureCallback mPicture = new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            mCamera.stopPreview();
            Intent myintent = new Intent(CameraSetter.this, CameraPhotoViewer.class);
            Bitmap bitmap_image = BitmapFactory.decodeByteArray(data, 0, data.length);
            ContextWrapper cw = new ContextWrapper(getApplicationContext());
            // path to /data/data/yourapp/app_data/imageDir
            File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
            // Create imageDir
            File mypath = new File(directory, "profile.jpg");

            FileOutputStream fos = null;

            try {
                fos = new FileOutputStream(mypath);
                // Use the compress method on the BitMap object to write image to the OutputStream
                bitmap_image.compress(Bitmap.CompressFormat.JPEG, 100, fos);

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    fos.close();
                    startActivity(myintent);
                    System.out.print(directory.getAbsolutePath());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
    };

and in Second Activity:

 imageview = (ImageView) findViewById(R.id.imview_camera_setter);
        framelayout = (FrameLayout) findViewById(R.id.frame_layout_viewer);
        try {


            File f=new File(internalpath, "profile.jpg");
            Bitmap b = BitmapFactory.decodeStream(new FileInputStream(f));

            imageview.setImageBitmap(Bitmap.createScaledBitmap(b, 300, 300, false));

        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        }

Still takes too much time

  • 1
    You should save the image in a file, create a low res version to use as a preview in the second activity until you finish to load the full version and then swap them. Btw the images you are showing shouldn't be too big to prevent UI unresponsiveness or OOM. – MatPag May 26 '17 at 13:16
  • Should I save this file within application? @MatPag – exceptionnotgood May 26 '17 at 13:17
  • Yes, you can use your app internal storage folder to store the original file and maybe use a cache to store the previews – MatPag May 26 '17 at 13:19
  • @MatPag I have implemented but it also taking so much time. If you want I can show the code – exceptionnotgood May 26 '17 at 13:46
  • Yes, add the code to the question – MatPag May 26 '17 at 13:49
  • @MatPag added that code in the bottom section – exceptionnotgood May 26 '17 at 13:55
  • Have you tried to low the resolution of the image captured? Try [this](https://stackoverflow.com/a/34716211/2910520) or you need to use `BitmapFactory.Options` to lower down it before decoding – MatPag May 26 '17 at 13:58
  • @MatPag I have already done it. – exceptionnotgood May 26 '17 at 14:00
  • `compress` method doesn't work with PNG. Try using Bitmap.CompressFormat.JPEG and a value of 70 – MatPag May 26 '17 at 14:02
  • @MatPag yes I solved the problem as you said I had a mistake in getting resoloution low thanks. – exceptionnotgood May 26 '17 at 14:03
  • Sorry that was wrong... `onPictureTaken(byte[] data,... ` The data byte array contains a jpg image. So you can directly save the bytes from the byte array to file. No need to construct a bitmap first which you then compress to a png file. Well if you need a png then bitmap has to be used indeed. – greenapps May 26 '17 at 14:35
  • @greenapps I made a mistake I dont need png edited – exceptionnotgood May 26 '17 at 14:39
  • If you keep using a bitmap - wich is wrong in my opinion- then do away with the ByteArrayOutputStream and compress the bitmap to the FileOutputStream right away. – greenapps May 26 '17 at 14:42
  • If you are going to use a Singleton class then copy the data byte array to it. Faster and less memory intence as constructing a bitmap. – greenapps May 26 '17 at 14:44
  • @greenapps yes I am doing by using singleton – exceptionnotgood May 26 '17 at 14:58

2 Answers2

0

You can use a singleton class to store your bitmap instead of do a write/read disk (this is slow). Only, take care to clear the bitmap after use it.

From activity A -> BitmapSingleton.getInstance().setBitmap(bitmap);

From activity B -> BitmapSingleton.getInstance().getBitmap(bitmap);

After you use it, you should do BitmapSingleton.getInstance().setBitmap(null); in activity B.

public class BitmapSingleton {

    private Bitmap image = null;

    private static final BitmapSingleton ourInstance = new BitmapSingleton();

    public static BitmapSingleton getInstance() {
        return ourInstance;
    }

    private BitmapSingleton() {
    }

    public Bitmap getBitmap() {
        return image;
    }

    public void setBitmap(Bitmap image) {
        this.image = image;
    } }
0

What you can do is take a static variable which stores the path of the file. Then you can access it anywhere in the app.

Sarthak Gandhi
  • 2,130
  • 1
  • 16
  • 23