Pages

Showing posts with label Gallery. Show all posts
Showing posts with label Gallery. Show all posts

Friday, October 31, 2014

Image Cropping in android : While capture image or select from gallery

Hello everyone, I write example code for capture & select image from gallery and cropping image in android. see below example code.

1. Create XML file in layout folder "res/layout/activity_main.xml".


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn_select_image"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:layout_marginTop="10dp"
        android:text="Select Image" />

    <ImageView
        android:id="@+id/img_photo"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_marginTop="10dp"
        android:scaleType="fitXY" />

</LinearLayout>
2. Create XML file in layout folder "res/layout/croping_selector.xml".


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:padding="10dp" >

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

    <TextView
        android:id="@+id/txt_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:text=""
        android:textColor="@android:color/black"
        android:textSize="16sp" />

</LinearLayout>

3. Create an activity Java file "MainActivity.java".


package com.limbani.imagecropping;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private final static int REQUEST_PERMISSION_REQ_CODE = 34;
        private static final int CAMERA_CODE = 101, GALLERY_CODE = 201, CROPING_CODE = 301;

        private Button btn_select_image;
        private ImageView imageView;
        private Uri mImageCaptureUri;
        private File outPutFile = null;

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

            outPutFile = new File(android.os.Environment.getExternalStorageDirectory(), "temp.jpg");

            btn_select_image = (Button) findViewById(R.id.btn_select_image);
            imageView = (ImageView) findViewById(R.id.img_photo);

            btn_select_image.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    selectImageOption();
                }
            });
        }

        private void selectImageOption() {
            final CharSequence[] items = { "Capture Photo", "Choose from Gallery", "Cancel" };

            AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
            builder.setTitle("Add Photo!");
            builder.setItems(items, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int item) {

                    if (items[item].equals("Capture Photo")) {

                        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                        File f = new File(android.os.Environment.getExternalStorageDirectory(), "temp1.jpg");
                        mImageCaptureUri = Uri.fromFile(f);
                        intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
                        startActivityForResult(intent, CAMERA_CODE);

                    } else if (items[item].equals("Choose from Gallery")) {

                        Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                        startActivityForResult(i, GALLERY_CODE);

                    } else if (items[item].equals("Cancel")) {
                        dialog.dismiss();
                    }
                }
            });
            builder.show();
        }

    @Override
    protected void onResume() {
        super.onResume();
        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSION_REQ_CODE);
            return;
        }
    }

    @Override
    public void onRequestPermissionsResult(final int requestCode, final @NonNull String[] permissions, final @NonNull int[] grantResults) {
        switch (requestCode) {
            case REQUEST_PERMISSION_REQ_CODE: {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(this, "Permission granted.", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(this, "Permission denied.", Toast.LENGTH_SHORT).show();
                }
                break;
            }
        }
    }

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

            super.onActivityResult(requestCode, resultCode, data);

            if (requestCode == GALLERY_CODE && resultCode == RESULT_OK && null != data) {

                mImageCaptureUri = data.getData();
                System.out.println("Gallery Image URI : "+mImageCaptureUri);
                CropingIMG();

            } else if (requestCode == CAMERA_CODE && resultCode == Activity.RESULT_OK) {

                System.out.println("Camera Image URI : "+mImageCaptureUri);
                CropingIMG();
            } else if (requestCode == CROPING_CODE) {

                try {
                    if(outPutFile.exists()){
                        Bitmap photo = decodeFile(outPutFile);
                        imageView.setImageBitmap(photo);
                    }
                    else {
                        Toast.makeText(getApplicationContext(), "Error while save image", Toast.LENGTH_SHORT).show();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        private void CropingIMG() {

            final ArrayList<cropingoption> cropOptions = new ArrayList<cropingoption>();

            Intent intent = new Intent("com.android.camera.action.CROP");
            intent.setType("image/*");

            List<resolveinfo> list = getPackageManager().queryIntentActivities( intent, 0 );
            int size = list.size();
            if (size == 0) {
                Toast.makeText(this, "Cann't find image croping app", Toast.LENGTH_SHORT).show();
                return;
            } else {
                intent.setData(mImageCaptureUri);
                intent.putExtra("outputX", 512);
                intent.putExtra("outputY", 512);
                intent.putExtra("aspectX", 1);
                intent.putExtra("aspectY", 1);
                intent.putExtra("scale", true);

                //TODO: don't use return-data tag because it's not return large image data and crash not given any message
                //intent.putExtra("return-data", true);

                //Create output file here
                intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(outPutFile));

                if (size == 1) {
                    Intent i   = new Intent(intent);
                    ResolveInfo res = (ResolveInfo) list.get(0);

                    i.setComponent( new ComponentName(res.activityInfo.packageName, res.activityInfo.name));

                    startActivityForResult(i, CROPING_CODE);
                } else {
                    for (ResolveInfo res : list) {
                        final CropingOption co = new CropingOption();

                        co.title  = getPackageManager().getApplicationLabel(res.activityInfo.applicationInfo);
                        co.icon  = getPackageManager().getApplicationIcon(res.activityInfo.applicationInfo);
                        co.appIntent= new Intent(intent);
                        co.appIntent.setComponent( new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
                        cropOptions.add(co);
                    }

                    CropingOptionAdapter adapter = new CropingOptionAdapter(getApplicationContext(), cropOptions);

                    AlertDialog.Builder builder = new AlertDialog.Builder(this);
                    builder.setTitle("Choose Croping App");
                    builder.setCancelable(false);
                    builder.setAdapter( adapter, new DialogInterface.OnClickListener() {
                        public void onClick( DialogInterface dialog, int item ) {
                            startActivityForResult( cropOptions.get(item).appIntent, CROPING_CODE);
                        }
                    });

                    builder.setOnCancelListener( new DialogInterface.OnCancelListener() {
                        @Override
                        public void onCancel( DialogInterface dialog ) {

                            if (mImageCaptureUri != null ) {
                                getContentResolver().delete(mImageCaptureUri, null, null );
                                mImageCaptureUri = null;
                            }
                        }
                    } );

                    AlertDialog alert = builder.create();
                    alert.show();
                }
            }
        }

        private Bitmap decodeFile(File f) {
            try {
                // decode image size
                BitmapFactory.Options o = new BitmapFactory.Options();
                o.inJustDecodeBounds = true;
                BitmapFactory.decodeStream(new FileInputStream(f), null, o);

                // Find the correct scale value. It should be the power of 2.
                final int REQUIRED_SIZE = 512;
                int width_tmp = o.outWidth, height_tmp = o.outHeight;
                int scale = 1;
                while (true) {
                    if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE)
                        break;
                    width_tmp /= 2;
                    height_tmp /= 2;
                    scale *= 2;
                }

                // decode with inSampleSize
                BitmapFactory.Options o2 = new BitmapFactory.Options();
                o2.inSampleSize = scale;
                return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
            } catch (FileNotFoundException e) {
            }
            return null;
        }
    }


4. Create Java file "CropingOption.java"


package com.limbani.imagecropping;

import android.content.Intent;
import android.graphics.drawable.Drawable;

public class CropingOption {
    public CharSequence title;
    public Drawable icon;
    public Intent appIntent;
}

5. Create Java file "CropingOptionAdapter.java"


package com.limbani.imagecropping;

import java.util.ArrayList;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class CropingOptionAdapter extends ArrayAdapter {
    private ArrayList mOptions;
    private LayoutInflater mInflater;

    public CropingOptionAdapter(Context context, ArrayList options) {
        super(context, R.layout.croping_selector, options);

        mOptions  = options;

        mInflater = LayoutInflater.from(context);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup group) {
        if (convertView == null)
            convertView = mInflater.inflate(R.layout.croping_selector, null);

        CropingOption item = (CropingOption) mOptions.get(position);

        if (item != null) {
            ((ImageView) convertView.findViewById(R.id.img_icon)).setImageDrawable(item.icon);
            ((TextView) convertView.findViewById(R.id.txt_name)).setText(item.title);

            return convertView;
        }

        return null;
    }
}

6. Add your activity class and user permission in "AndroidManifest.xml".


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

    <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">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>


7. ScreenShot".







Thanks :)
Download Code

Thursday, March 13, 2014

How to get absolute path when select image from gallery and SD Card (Kitkat and lower android version)?

In some special cast to need get image from gallery to display in application. so I am posting to get absolute path of the selected image from gallery using Intent.ACTION_GET_CONTENT.

In Kitkat version we get different Uri format(DocumentProvider)
Now
Uri format like this : content://com.android.providers.media.documents/document/image:3951
Before
Uri format like this : content://media/external/images/media/3951.

See the Kikat version change here

1. AbsolutePathActivity.java Activity Class

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class AbsolutePathActivity extends Activity 
{
 private static final int MY_INTENT_CLICK=302;
 private TextView txta;
 private Button btn_selectImage;

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

  txta = (TextView) findViewById(R.id.textView1);
  btn_selectImage = (Button) findViewById(R.id.btn_selectImage);

  btn_selectImage.setOnClickListener(new OnClickListener() 
  {
   @Override
   public void onClick(View v) 
   {
    Intent intent = new Intent(); 
    intent.setType("*/*"); 
    intent.setAction(Intent.ACTION_GET_CONTENT); 
    startActivityForResult(Intent.createChooser(intent, "Select File"),MY_INTENT_CLICK);
   }
  });

 }

 @Override
 public void onActivityResult(int requestCode, int resultCode, Intent data)
 {
  if (resultCode == RESULT_OK)
  {
   if (requestCode == MY_INTENT_CLICK)
   {
    if (null == data) return;

    String selectedImagePath;
    Uri selectedImageUri = data.getData();

    //MEDIA GALLERY
    selectedImagePath = ImageFilePath.getPath(getApplicationContext(), selectedImageUri);
    Log.i("Image File Path", ""+selectedImagePath);
    txta.setText("File Path : \n"+selectedImagePath);
   }
  }
 }
}

Copy below class on your application for getting Gallery image file Uri AbsolutePath.

2.ImageFilePath.java  

import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;

public class ImageFilePath 
{
 
 
 /**
  * Method for return file path of Gallery image 
  * 
  * @param context
  * @param uri
  * @return path of the selected image file from gallery
  */
 public static String getPath(final Context context, final Uri uri) 
 {

  //check here to KITKAT or new version
  final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

  // DocumentProvider
  if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
   
   // ExternalStorageProvider
   if (isExternalStorageDocument(uri)) {
    final String docId = DocumentsContract.getDocumentId(uri);
    final String[] split = docId.split(":");
    final String type = split[0];

    if ("primary".equalsIgnoreCase(type)) {
     return Environment.getExternalStorageDirectory() + "/" + split[1];
    }
   }
   // DownloadsProvider
   else if (isDownloadsDocument(uri)) {

    final String id = DocumentsContract.getDocumentId(uri);
    final Uri contentUri = ContentUris.withAppendedId(
      Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

    return getDataColumn(context, contentUri, null, null);
   }
   // MediaProvider
   else if (isMediaDocument(uri)) {
    final String docId = DocumentsContract.getDocumentId(uri);
    final String[] split = docId.split(":");
    final String type = split[0];

    Uri contentUri = null;
    if ("image".equals(type)) {
     contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
    } else if ("video".equals(type)) {
     contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
    } else if ("audio".equals(type)) {
     contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    }

    final String selection = "_id=?";
    final String[] selectionArgs = new String[] {
      split[1]
    };

    return getDataColumn(context, contentUri, selection, selectionArgs);
   }
  }
  // MediaStore (and general)
  else if ("content".equalsIgnoreCase(uri.getScheme())) {

   // Return the remote address
   if (isGooglePhotosUri(uri))
    return uri.getLastPathSegment();

   return getDataColumn(context, uri, null, null);
  }
  // File
  else if ("file".equalsIgnoreCase(uri.getScheme())) {
   return uri.getPath();
  }

  return null;
 }

 /**
  * Get the value of the data column for this Uri. This is useful for
  * MediaStore Uris, and other file-based ContentProviders.
  *
  * @param context The context.
  * @param uri The Uri to query.
  * @param selection (Optional) Filter used in the query.
  * @param selectionArgs (Optional) Selection arguments used in the query.
  * @return The value of the _data column, which is typically a file path.
  */
 public static String getDataColumn(Context context, Uri uri, String selection,
   String[] selectionArgs) {

  Cursor cursor = null;
  final String column = "_data";
  final String[] projection = {
    column
  };

  try {
   cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
     null);
   if (cursor != null && cursor.moveToFirst()) {
    final int index = cursor.getColumnIndexOrThrow(column);
    return cursor.getString(index);
   }
  } finally {
   if (cursor != null)
    cursor.close();
  }
  return null;
 }

 /**
  * @param uri The Uri to check.
  * @return Whether the Uri authority is ExternalStorageProvider.
  */
 public static boolean isExternalStorageDocument(Uri uri) {
  return "com.android.externalstorage.documents".equals(uri.getAuthority());
 }

 /**
  * @param uri The Uri to check.
  * @return Whether the Uri authority is DownloadsProvider.
  */
 public static boolean isDownloadsDocument(Uri uri) {
  return "com.android.providers.downloads.documents".equals(uri.getAuthority());
 }

 /**
  * @param uri The Uri to check.
  * @return Whether the Uri authority is MediaProvider.
  */
 public static boolean isMediaDocument(Uri uri) {
  return "com.android.providers.media.documents".equals(uri.getAuthority());
 }

 /**
  * @param uri The Uri to check.
  * @return Whether the Uri authority is Google Photos.
  */
 public static boolean isGooglePhotosUri(Uri uri) {
  return "com.google.android.apps.photos.content".equals(uri.getAuthority());
 }
}


3. activity_absolutepath.xml layout file

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="30dp" >

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Example code for get absolute path when select image from gallery"
        android:textSize="14sp"
        android:textStyle="bold" />

    <Button
        android:id="@+id/btn_selectImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:layout_marginTop="10dp"
        android:text="Select Image" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:textSize="14sp"
        android:textStyle="bold" />

</LinearLayout>

4. AndroidManifest.xml file

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.limbani.masterapp"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.limbani.masterapp.AbsolutePathActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

5. ScreenShot




And Gallery image file Absolute path write in Log as per above code.

That's it, And it's working in Kitkat and  lower version too.

Doanload APK file Here

enjoy :)
Thank you.