0
votes

I usually don't work with images. I tried it. App will onBttnClick show gallery and user can choose picture and he has to crop it. It will save great but I want to save it and use cropped image until user change it.

So please can you tell me how can I save image for later use ?

Here is code in Activity

public void onImage(View view){
    //Přechod do třídy GalleryUtil
    Intent gallery_Intent = new Intent(getApplicationContext(), GalleryUtil.class);
    startActivityForResult(gallery_Intent, GALLERY_ACTIVITY_CODE);
}

//Vyhodnocení zadaných údajů
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == GALLERY_ACTIVITY_CODE) {
        if(resultCode == Activity.RESULT_OK){
            String picturePath = data.getStringExtra("picturePath");
            performCrop(picturePath);
        }
    }

    if (requestCode == RESULT_CROP ) {
        if(resultCode == Activity.RESULT_OK){

            Bundle extras = data.getExtras();
            Bitmap selectedBitmap = extras.getParcelable("data");
            ImageView imageView=(ImageView)findViewById(R.id.imageView);
            imageView.setImageBitmap(getCroppedBitmap(selectedBitmap));
            imageView.setScaleType(ImageView.ScaleType.FIT_XY);

            String path = Environment.getExternalStorageDirectory().getAbsolutePath() +"/images"; // save to SD Card in images folder. Make sure path is there !
            OutputStream fOut = null;

            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
            String currentDateandTime = sdf.format(new Date());
            File file = new File(path, "Cropped_Image_"+currentDateandTime+".jpg"); // the File to save to
            try {
                fOut = new FileOutputStream(file);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }

            Bitmap pictureBitmap = getCroppedBitmap(selectedBitmap); // Using the cropped bitmap.
            pictureBitmap.compress(Bitmap.CompressFormat.JPEG, 85, fOut); // saving the Bitmap to a file compressed as a JPEG with 85% compression rate
            try {
                fOut.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                fOut.close(); // do not forget to close the stream
            } catch (IOException e) {
                e.printStackTrace();
            }

            try {
                MediaStore.Images.Media.insertImage(getContentResolver(),file.getAbsolutePath(),file.getName(),file.getName());
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }

        }
    }
}

private void performCrop(String picUri) {
    try {


        Intent cropIntent = new Intent("com.android.camera.action.CROP");
        // indicate image type and Uri
        File f = new File(picUri);
        Uri contentUri = Uri.fromFile(f);

        cropIntent.setDataAndType(contentUri, "image/*");
        // set crop properties
        cropIntent.putExtra("crop", "true");
        // indicate aspect of desired crop
        cropIntent.putExtra("aspectX", 1);
        cropIntent.putExtra("aspectY", 1);
        // indicate output X and Y
        cropIntent.putExtra("outputX", 280);
        cropIntent.putExtra("outputY", 280);

        // retrieve data on return
        cropIntent.putExtra("return-data", true);
        // start the activity - we handle returning in onActivityResult
        startActivityForResult(cropIntent, RESULT_CROP);
    }
    // respond to users whose devices do not support the crop action
    catch (ActivityNotFoundException anfe) {
        // display an error message
        String errorMessage = "your device doesn't support the crop action!";
        Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
        toast.show();
    }
}

public Bitmap getCroppedBitmap(Bitmap bitmap) {
    Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
            bitmap.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(output);

    final int color = 0xff424242;
    final Paint paint = new Paint();
    final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());

    paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    paint.setColor(color);
    canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2,
            bitmap.getWidth() / 2, paint);
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    canvas.drawBitmap(bitmap, rect, rect, paint);


    return output;
}

}

And here is my GalleryUtil code

public class GalleryUtil extends Activity{

private final static int RESULT_SELECT_IMAGE = 100;
public static final int MEDIA_TYPE_IMAGE = 1;
private static final String TAG = "GalleryUtil";

String mCurrentPhotoPath;
File photoFile = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    try{
        //Pick Image From Gallery
        Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(i, RESULT_SELECT_IMAGE);
    }catch(Exception e){
        e.printStackTrace();
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    switch(requestCode){
        case RESULT_SELECT_IMAGE:

            if (resultCode == Activity.RESULT_OK && data != null && data.getData() != null) {
                try{
                    Uri selectedImage = data.getData();
                    String[] filePathColumn = {MediaStore.Images.Media.DATA };
                    Cursor cursor = getContentResolver().query(selectedImage,
                            filePathColumn, null, null, null);
                    cursor.moveToFirst();
                    int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                    String picturePath = cursor.getString(columnIndex);


                    //return Image Path to the Main Activity
                    Intent returnFromGalleryIntent = new Intent();
                    returnFromGalleryIntent.putExtra("picturePath",picturePath);
                    setResult(RESULT_OK,returnFromGalleryIntent);
                    finish();
                }catch(Exception e){
                    e.printStackTrace();
                    Intent returnFromGalleryIntent = new Intent();
                    setResult(RESULT_CANCELED, returnFromGalleryIntent);
                    finish();
                }
            }else{
                Log.i(TAG,"RESULT_CANCELED");
                Intent returnFromGalleryIntent = new Intent();
                setResult(RESULT_CANCELED, returnFromGalleryIntent);
                finish();
            }
            break;
    }
}

}

Error:

12-04 23:00:25.521 1728-1728/com.tomiktuts.tom.mygirlfriendapp E/AndroidRuntime: FATAL EXCEPTION: main Process: com.tomiktuts.tom.mygirlfriendapp, PID: 1728 java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=400, result=-1, data=Intent { (has extras) }} to activity {com.tomiktuts.tom.mygirlfriendapp/com.tomiktuts.tom.mygirlfriendapp.DashBoardActivity}: java.lang.NullPointerException at android.app.ActivityThread.deliverResults(ActivityThread.java:4067) at android.app.ActivityThread.handleSendResult(ActivityThread.java:4110) at android.app.ActivityThread.access$1400(ActivityThread.java:177) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1498) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:145) at android.app.ActivityThread.main(ActivityThread.java:5951) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195) Caused by: java.lang.NullPointerException at android.graphics.Bitmap.compress(Bitmap.java:1143) at com.tomiktuts.tom.mygirlfriendapp.DashBoardActivity.onActivityResult(DashBoardActivity.java:161) at android.app.Activity.dispatchActivityResult(Activity.java:6549) at android.app.ActivityThread.deliverResults(ActivityThread.java:4063) at android.app.ActivityThread.handleSendResult(ActivityThread.java:4110)  at android.app.ActivityThread.access$1400(ActivityThread.java:177)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1498)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:145)  at android.app.ActivityThread.main(ActivityThread.java:5951)  at java.lang.reflect.Method.invoke(Native Method)  at java.lang.reflect.Method.invoke(Method.java:372)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195) 

Thank you for help. Have a nice day.

1

1 Answers

1
votes

You should use the Bitmap.compress() method to save a Bitmap as a file. It will compress your picture and push it into an OutputStream.

I think the best thing would be to add below logic just when imageview is set using getCroppedBitmap(Bitmap bitmap) (which is called after performCrop(String picUri) is performed).

String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();

OutputStream fOut = null;

// Lets save using date
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
String currentDateandTime = sdf.format(new Date());
String fileName = "Cropped_Image_" + currentDateandTime + ".png";

// Not sure if the / is on the path or not
File file = new File(baseDir + File.separator + fileName); // the File to save to
fOut = new FileOutputStream(file);

Bitmap pictureBitmap = getCroppedBitmap(selectedBitmap); // Using the cropped bitmap.
pictureBitmap.compress(Bitmap.CompressFormat.JPEG, 85, fOut); // saving the Bitmap to a file compressed as a JPEG with 85% compression rate
fOut.flush();
fOut.close(); // do not forget to close the stream

MediaStore.Images.Media.insertImage(getContentResolver(),file.getAbsolutePath(),file.getName(),file.getName());

Hope this helps !

Remember to add below to manifest, if you have not :

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Complete Working Code :

GalleryUtil.java

    package com.example.user.myapplication;

    import android.app.Activity;
    import android.content.Intent;
    import android.database.Cursor;
    import android.net.Uri;
    import android.provider.MediaStore;
    import android.os.Bundle;
    import android.util.Log;

    import java.io.File;

    public class GalleryUtil extends Activity {

        private final static int RESULT_SELECT_IMAGE = 100;
        public static final int MEDIA_TYPE_IMAGE = 1;
        private static final String TAG = "GalleryUtil";

        String mCurrentPhotoPath;
        File photoFile = null;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            try{
                //Pick Image From Gallery
                Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(i, RESULT_SELECT_IMAGE);
            }catch(Exception e){
                e.printStackTrace();
            }
        }

        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);

            switch(requestCode){
                case RESULT_SELECT_IMAGE:

                    if (resultCode == Activity.RESULT_OK && data != null && data.getData() != null) {
                        try{
                            Uri selectedImage = data.getData();
                            String[] filePathColumn = {MediaStore.Images.Media.DATA };
                            Cursor cursor = getContentResolver().query(selectedImage,
                                    filePathColumn, null, null, null);
                            cursor.moveToFirst();
                            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                            String picturePath = cursor.getString(columnIndex);


                            //return Image Path to the Main Activity
                            Intent returnFromGalleryIntent = new Intent();
                            returnFromGalleryIntent.putExtra("picturePath",picturePath);
                            setResult(RESULT_OK,returnFromGalleryIntent);
                            finish();
                        }catch(Exception e){
                            e.printStackTrace();
                            Intent returnFromGalleryIntent = new Intent();
                            setResult(RESULT_CANCELED, returnFromGalleryIntent);
                            finish();
                        }
                    }else{
                        Log.i(TAG, "RESULT_CANCELED");
                        Intent returnFromGalleryIntent = new Intent();
                        setResult(RESULT_CANCELED, returnFromGalleryIntent);
                        finish();
                    }
                    break;
            }
        }
    }

MainActivity :

            package com.example.user.myapplication;

            import android.app.Activity;
            import android.content.ActivityNotFoundException;
            import android.content.Intent;
            import android.graphics.Bitmap;
            import android.graphics.Canvas;
            import android.graphics.Paint;
            import android.graphics.PorterDuff;
            import android.graphics.PorterDuffXfermode;
            import android.graphics.Rect;
            import android.net.Uri;
            import android.os.Bundle;
            import android.os.Environment;
            import android.provider.MediaStore;
            import android.view.Menu;
            import android.view.MenuItem;
            import android.view.View;
            import android.widget.ImageView;
            import android.widget.Toast;

            import java.io.File;
            import java.io.FileOutputStream;
            import java.text.SimpleDateFormat;
            import java.util.Date;

            public class MainActivity extends Activity {

                private final static int GALLERY_ACTIVITY_CODE = 100;
                public static final int RESULT_CROP = 1;

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

                    // onImage can be called with anything doesn't matter :
                    onImage(null);
                }

                @Override
                public boolean onCreateOptionsMenu(Menu menu) {
                    // Inflate the menu; this adds items to the action bar if it is present.
                    getMenuInflater().inflate(R.menu.menu_main, menu);
                    return true;
                }

                @Override
                public boolean onOptionsItemSelected(MenuItem item) {
                    // Handle action bar item clicks here. The action bar will
                    // automatically handle clicks on the Home/Up button, so long
                    // as you specify a parent activity in AndroidManifest.xml.
                    int id = item.getItemId();

                    //noinspection SimplifiableIfStatement
                    if (id == R.id.action_settings) {
                        return true;
                    }

                    return super.onOptionsItemSelected(item);
                }

                public void onImage(View view){
                    //Přechod do třídy GalleryUtil
                    Intent gallery_Intent = new Intent(getApplicationContext(), GalleryUtil.class);
                    startActivityForResult(gallery_Intent, GALLERY_ACTIVITY_CODE);
                }

                //Vyhodnocení zadaných údajů
                @Override
                public void onActivityResult(int requestCode, int resultCode, Intent data) {
                    super.onActivityResult(requestCode, resultCode, data);
                    if (requestCode == GALLERY_ACTIVITY_CODE) {
                        if(resultCode == Activity.RESULT_OK){
                            String picturePath = data.getStringExtra("picturePath");
                            performCrop(picturePath);
                        }
                    }

                    if (requestCode == RESULT_CROP ) {
                        if(resultCode == Activity.RESULT_OK){

                            Bundle extras = data.getExtras();
                            Bitmap selectedBitmap = extras.getParcelable("data");
                            Bitmap croppedBitmap = getCroppedBitmap(selectedBitmap);

                            ImageView imageView=(ImageView)findViewById(R.id.imageView);
                            imageView.setImageBitmap(croppedBitmap);
                            imageView.setScaleType(ImageView.ScaleType.FIT_XY);

                            String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();
                            FileOutputStream fOut = null;
                            String fileName = "Cropped_Image.jpg";

                            try {
                                // Not sure if the / is on the path or not
                                File file = new File(baseDir + File.separator + fileName); // the File to save to
                                fOut = new FileOutputStream(file);

                                Bitmap pictureBitmap = getCroppedBitmap(selectedBitmap); // Using the cropped bitmap.
                                pictureBitmap.compress(Bitmap.CompressFormat.JPEG, 85, fOut); // saving the Bitmap to a file compressed as a JPEG with 85% compression rate

                                fOut.flush();
                                fOut.close(); // do not forget to close the stream
                                MediaStore.Images.Media.insertImage(getContentResolver(), file.getAbsolutePath(), file.getName(), file.getName());
                            } catch (Exception e) {
                                e.printStackTrace();
                            }

                        }
                    }
                }

                private void performCrop(String picUri) {
                    try {


                        Intent cropIntent = new Intent("com.android.camera.action.CROP");
                        // indicate image type and Uri
                        File f = new File(picUri);
                        Uri contentUri = Uri.fromFile(f);

                        cropIntent.setDataAndType(contentUri, "image/*");
                        // set crop properties
                        cropIntent.putExtra("crop", "true");
                        // indicate aspect of desired crop
                        cropIntent.putExtra("aspectX", 1);
                        cropIntent.putExtra("aspectY", 1);
                        // indicate output X and Y
                        cropIntent.putExtra("outputX", 280);
                        cropIntent.putExtra("outputY", 280);

                        // retrieve data on return
                        cropIntent.putExtra("return-data", true);
                        // start the activity - we handle returning in onActivityResult
                        startActivityForResult(cropIntent, RESULT_CROP);
                    }
                    // respond to users whose devices do not support the crop action
                    catch (ActivityNotFoundException anfe) {
                        // display an error message
                        String errorMessage = "your device doesn't support the crop action!";
                        Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
                        toast.show();
                    }
                }

                public Bitmap getCroppedBitmap(Bitmap bitmap) {
                    Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
                            bitmap.getHeight(), Bitmap.Config.ARGB_8888);
                    Canvas canvas = new Canvas(output);

                    final int color = 0xff424242;
                    final Paint paint = new Paint();
                    final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());

                    paint.setAntiAlias(true);
                    canvas.drawARGB(0, 0, 0, 0);
                    paint.setColor(color);
                    canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2,
                            bitmap.getWidth() / 2, paint);
                    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
                    canvas.drawBitmap(bitmap, rect, rect, paint);


                    return output;
                }
            }

AndroidManifest.xml

            <?xml version="1.0" encoding="utf-8"?>
            <manifest xmlns:android="http://schemas.android.com/apk/res/android"
                package="com.example.user.myapplication">

                <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

                <application
                    android:allowBackup="true"
                    android:icon="@mipmap/ic_launcher"
                    android:label="@string/app_name"
                    android:supportsRtl="true"
                    android:theme="@style/AppTheme">
                    <activity
                        android:name=".MainActivity"
                        android:label="@string/app_name"
                        android:theme="@style/AppTheme.NoActionBar">
                        <intent-filter>
                            <action android:name="android.intent.action.MAIN" />

                            <category android:name="android.intent.category.LAUNCHER" />
                        </intent-filter>
                    </activity>
                    <activity android:name=".GalleryUtil"></activity>
                </application>

            </manifest>

activity_main.xml

            <?xml version="1.0" encoding="utf-8"?>
            <RelativeLayout
                xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:app="http://schemas.android.com/apk/res-auto"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true"
                tools:context="com.example.user.myapplication.MainActivity">

                <ImageView
                    android:id="@+id/imageView"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content" />
            </RelativeLayout>

The above code is working absolutely fine. I am able to get pics cropped and saved in my sd card. Compare and check where you are doing wrong.

To read every time app opens, we need to add following to main activity :

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

        // Adding code for reading if file is already saved :
    loadImageFromStorage(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "Cropped_Image.jpg")

        // onImage can be called with anything doesn't matter :
        onImage(null);
}

private void loadImageFromStorage(String path)
{

    try {
        File f=new File(path);
        Bitmap b = BitmapFactory.decodeStream(new FileInputStream(f));
        ImageView img=(ImageView)findViewById(R.id.imageView);
        img.setImageBitmap(b);
    } 
    catch (FileNotFoundException e) 
    {
        e.printStackTrace();
    }

}

...