Android Open Source - dejalist Crop Activity






From Project

Back to project page dejalist.

License

The source code is released under:

Apache License

If you think the Android project dejalist listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.luboganev.dejalist.crop;
/*from   w w  w  . j av a 2 s. c om*/
import java.io.File;
import java.io.IOException;
import java.util.UUID;

import com.luboganev.dejalist.R;
import com.luboganev.dejalist.Utils;

import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.provider.MediaStore.MediaColumns;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;

public class CropActivity extends FragmentActivity {
  private final static int REQUEST_CODE_PICK_IMAGE = 1;
  private final static int REQUEST_CODE_TAKE_PHOTO = 2;
  
  private final static String STATE_FILE_URI = "state_file_uri";
  private final static String STATE_DESTINATION_FILE_URI = "state_destination_file_uri";
  private final static String STATE_PHOTO_TMP_FILE = "state_photo_tmp_file";
  private final static String STATE_LAST_PHOTO_TMP_FILE = "state_last_photo_tmp_file";
  private final static String STATE_SOURCE = "state_source";
  
  public final static String EXTRA_DESTINATION_FILE = "extra_destination_file";
  public final static String EXTRA_SOURCE = "extra_source_image";
  public final static String EXTRA_SOURCE_IMAGE_URI = "extra_source_image_uri";
  public final static String EXTRA_ROTATION = "extra_rotation";
  public final static int EXTRA_SOURCE_IMAGE = 1;
  public final static int EXTRA_SOURCE_CAMERA = 2;
  
  private Bitmap bitmap;  
  private CropView preview;
  private BitmapFactory.Options bitmapOptions;
  private File photoFile = null;
  private File lastPhotoFile = null;
  private Uri uri = null;
  private Uri destinationUri = null;
  private int mSource = -1;
  private TextView noImageText;
  private boolean deleteTempPicturesOnDestroy = true;
  private int rotation;
  
  private File generateTempPictureFile(final Context context) {
    return new File(Environment.getExternalStorageDirectory(), UUID.randomUUID().toString() + ".jpg"); 
  }
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Setup the layout
    setContentView(R.layout.activity_crop);
    getActionBar().setDisplayShowTitleEnabled(false);
    getActionBar().setDisplayShowHomeEnabled(false);
    preview = (CropView) findViewById(R.id.image_editor_preview);
    noImageText = (TextView) findViewById(R.id.image_editor_no_image_text);
    
    // Try to restore state first
    restoreState(savedInstanceState);
    
    // Read intent data if not restored    
    if(destinationUri == null && getIntent() != null) {
      String s = getIntent().getStringExtra(EXTRA_DESTINATION_FILE);
      if(s != null) {
        destinationUri = Uri.parse(s);
      }
    }
    if(mSource == -1 && getIntent() != null){
      mSource = getIntent().getIntExtra(EXTRA_SOURCE, -1);
    }
    
    // load the custom actionbar
        getActionBar().setCustomView(R.layout.actionbar_crop_done_discard);
        getActionBar().setDisplayShowCustomEnabled(true);
        final View customActionBarView = getActionBar().getCustomView();
        customActionBarView.findViewById(R.id.actionbar_crop_done).setOnClickListener(
                new OnCustomActionBarItemClicked());
        customActionBarView.findViewById(R.id.actionbar_crop_discard).setOnClickListener(
            new OnCustomActionBarItemClicked());
        customActionBarView.findViewById(R.id.actionbar_crop_rotate_ccw).setOnClickListener(
            new OnCustomActionBarItemClicked());
        customActionBarView.findViewById(R.id.actionbar_crop_rotate_cw).setOnClickListener(
            new OnCustomActionBarItemClicked());
        
        CropUtils.recalculateMaxImagesize(getApplicationContext());
        
       // If we need to have a defined source of the image through the starting intent!
     if(mSource == EXTRA_SOURCE_IMAGE) {
       // if the activity starts for the first time go straight to image open
       
       if(savedInstanceState == null || !savedInstanceState.containsKey(STATE_SOURCE))
       {
         // if an image uri is already provided open it
         if(getIntent().hasExtra(EXTRA_SOURCE_IMAGE_URI)) {
           uri = Uri.parse(getIntent().getStringExtra(EXTRA_SOURCE_IMAGE_URI));
           loadBitmap();
         }
         else openImage(); 
       }
         
         }
     else if(mSource == EXTRA_SOURCE_CAMERA) {
       // if the activity starts for the first time go straight to take photo
           if(savedInstanceState == null) takePhoto(); 
           else if(!savedInstanceState.containsKey(STATE_SOURCE)) takePhoto();
         }
     else finish();
  }
  
  private class OnCustomActionBarItemClicked implements OnClickListener {
    @Override
    public void onClick(View v) {
      switch(v.getId()) {
      case R.id.actionbar_crop_done:
        saveImage();
        break;
      case R.id.actionbar_crop_discard:
        setResult(Activity.RESULT_CANCELED);
                finish();
        break;
      case R.id.actionbar_crop_rotate_ccw:
        addToRotation(270);
        break;
      case R.id.actionbar_crop_rotate_cw:
        addToRotation(90);
        break;
      }
    }
  }
  
  @Override
  protected void onDestroy() {
    super.onDestroy();
    if(deleteTempPicturesOnDestroy) {
      deleteLastPhotoFile();
      deletePhotoFile();
    }
  }
  
  @Override
  protected void onResume() {
    super.onResume();
    showImageTools(uri != null);
    deleteTempPicturesOnDestroy = true;
  }
  
  private void openImage() {
    // Sends general image content request
      Intent intent = new Intent();
      intent.setType("image/*");
      intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(intent, REQUEST_CODE_PICK_IMAGE);
  }
  
  private void takePhoto() {
    Intent intent = new Intent();
    intent.setAction("android.media.action.IMAGE_CAPTURE");
    if(photoFile != null) {
      deleteLastPhotoFile();
      lastPhotoFile = photoFile;
    }
    photoFile = generateTempPictureFile(getApplicationContext());
    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
    startActivityForResult(intent, REQUEST_CODE_TAKE_PHOTO);
  }
  
  private void addToRotation(int degrees) {
    if(bitmap == null) {
      Toast.makeText(getApplicationContext(), R.string.toast_crop_no_image, Toast.LENGTH_SHORT).show();
      return;
    }
        rotation = (rotation + degrees) % 360;
        preview.setHighlight(null);             
        bitmap = CropUtils.rotate(bitmap, degrees);
        preview.setImageBitmapResetBase(bitmap, true);
        makeHighlight();
  }
  
  private void showImageTools(boolean show) {
    noImageText.setVisibility(show ? View.GONE : View.VISIBLE);
    if(mSource <= 0) getActionBar().setDisplayShowCustomEnabled(show);
  }
  
  private void restoreState(Bundle bundle) {
    if (bundle == null) return;
    if (bundle.containsKey(STATE_PHOTO_TMP_FILE))
      photoFile = new File(bundle.getString(STATE_PHOTO_TMP_FILE));
    if (bundle.containsKey(STATE_LAST_PHOTO_TMP_FILE))
      lastPhotoFile = new File(bundle.getString(STATE_LAST_PHOTO_TMP_FILE));
    rotation = bundle.getInt(EXTRA_ROTATION, 0);
    mSource = bundle.getInt(STATE_SOURCE, -1);
    String uriStr = bundle.getString(STATE_FILE_URI);
    if (uriStr != null) {
      uri = Uri.parse(uriStr);
      loadBitmap();
    }
    uriStr = bundle.getString(STATE_DESTINATION_FILE_URI);
    if (uriStr != null) {
      destinationUri = Uri.parse(uriStr);
    }
  }

  private Bundle saveState(Bundle bundle) {
    deleteTempPicturesOnDestroy = false;
    if (uri != null)
      bundle.putString(STATE_FILE_URI, uri.toString());
    if (destinationUri != null)
      bundle.putString(STATE_DESTINATION_FILE_URI, uri.toString());
    if (photoFile != null) {
      bundle.putString(STATE_PHOTO_TMP_FILE, photoFile.getAbsolutePath());
    }
    if (lastPhotoFile != null) {
      bundle.putString(STATE_LAST_PHOTO_TMP_FILE, lastPhotoFile.getAbsolutePath());
    }
    if (mSource != -1) {
      bundle.putInt(STATE_SOURCE, mSource);
    }
    bundle.putInt(EXTRA_ROTATION, rotation);
    return bundle;
  }
  
  @Override
  protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    saveState(outState);
  }
  
  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);
    switch (requestCode) {
      case REQUEST_CODE_TAKE_PHOTO:
        if (resultCode != RESULT_OK) {
          // if no image was ever loaded, this means initial state, then close the activity with cancel
          if (uri == null) {
            setResult(Activity.RESULT_CANCELED);
            finish();
          }
          photoFile = lastPhotoFile;
          lastPhotoFile = null;
  
          break;
        }
        if (photoFile == null || !photoFile.exists()) {
          photoFile = null;
          Toast.makeText(this, R.string.toast_crop_img_load_failed,
              Toast.LENGTH_LONG).show();
          return;
        }
        loadBitmap(Uri.fromFile(photoFile), 0);
      break;
      case REQUEST_CODE_PICK_IMAGE:
        if (resultCode != RESULT_OK) {
          // if no image was ever loaded, this means initial state, then close the activity with cancel
          if (uri == null) {
            setResult(Activity.RESULT_CANCELED);
            finish();
          }
          break;
        }
        
        deleteLastPhotoFile();
        deletePhotoFile();
        
        Uri selectedImage = intent.getData();
        if (selectedImage == null) {
          return;
        }

        if (selectedImage.toString().startsWith(
            "content://com.android.gallery3d.provider")) {
          // some devices/OS versions return an URI of com.android instead
          // of com.google.android
          String str = selectedImage.toString()
              .replace("com.android.gallery3d", "com.google.android.gallery3d");
          selectedImage = Uri.parse(str);
        }
        boolean picasaImage = selectedImage.toString().startsWith(
            "content://com.google.android.gallery3d");
        
        final String[] filePathColumn = { MediaColumns.DATA,
            MediaColumns.DISPLAY_NAME };
        Cursor cursor = getContentResolver().query(selectedImage,
            filePathColumn, null, null, null);
        if (cursor == null) {
          Toast.makeText(this, R.string.toast_crop_img_load_failed, Toast.LENGTH_LONG)
              .show();
          return;
        }
        
        cursor.moveToFirst();
        if (picasaImage) {
          int columnIndex = cursor.getColumnIndex(MediaColumns.DISPLAY_NAME);
          if (columnIndex == -1) {
            return;
          }
          Toast.makeText(getApplicationContext(), getString(R.string.toast_crop_not_local_image), Toast.LENGTH_SHORT).show();
          return;
        } else {
          int columnIndex = cursor.getColumnIndex(MediaColumns.DATA);
          if (columnIndex == -1) {
            return;
          }
          String name = cursor.getString(columnIndex);
          File file = new File(name);
          if (!file.exists() || !file.canRead()) {
            Toast.makeText(this, R.string.toast_crop_img_load_failed,
                Toast.LENGTH_LONG).show();
            return;
          }
          loadBitmap(Uri.fromFile(file), 0);
        }
        cursor.close();
      break;
    }
  }
  
  protected void loadBitmap(Uri sourceUri, int rotation) {
    this.uri = sourceUri;
    this.rotation = rotation;
    loadBitmap();
  }
  
  private void loadBitmap() {
    if (uri == null) return;
    // make some space for the new bitmap
    if(bitmapOptions != null) {
      preview.setImageBitmap(null);
      bitmapOptions = null;
    }
    BitmapFactory.Options o = CropUtils.getBitmapOptions(getContentResolver(), uri);
    bitmapOptions = new BitmapFactory.Options();
    bitmapOptions.inSampleSize = CropUtils.scalePow2(o.outHeight, o.outWidth);

    bitmap = CropUtils.getBitmap(bitmapOptions, getContentResolver(), uri);
    bitmap = CropUtils.rotate(bitmap, rotation);
    preview.setImageBitmapResetBase(bitmap, true);
    Utils.d("CropActivity", "SampleSize " + bitmapOptions.inSampleSize + " -> ("+bitmapOptions.outWidth+":"+bitmapOptions.outHeight+")");
    makeHighlight();
  }
  
  private void makeHighlight() {
    if (bitmap == null) return;
    CropHighlightView hv = new CropHighlightView(preview);
    int width = bitmap.getWidth();
    int height = bitmap.getHeight();
    Rect imageRect = new Rect(0, 0, width, height);

    // make the default size about 4/5 of the width or height
    int cropWidth = Math.min(width, height) * 4 / 5;
    int cropHeight = cropWidth;
    int x = (width - cropWidth) / 2;
    int y = (height - cropHeight) / 2;
    RectF cropRect = new RectF(x, y, x + cropWidth, y + cropHeight);
    hv.setup(preview.getImageMatrix(), imageRect, cropRect, false, true, 160f);
    hv.setFocus(true);
    preview.setHighlight(hv);
  }
  
  /**
   * Callback from the save progress dialog
   */
  protected void onSaveFinished(File file) {
    Intent intent = new Intent();
    intent.setData(Uri.fromFile(file));
    setResult(RESULT_OK, intent);
    finish();
  }
  
  private void saveImage() {
    if(bitmap == null) {
      Toast.makeText(getApplicationContext(), R.string.toast_crop_no_image, Toast.LENGTH_SHORT).show();
      return;
    }
    File destinationFile;
    if(destinationUri != null) {
      destinationFile = new File(destinationUri.getPath());
    }
    else {
      destinationFile = generateTempPictureFile(getApplicationContext());
    }
    try {
      if(bitmapOptions != null) {
        preview.setImageBitmap(null);
        bitmapOptions = null;
      }
      destinationFile.createNewFile();
      DialogFragment newFragment = 
          CropDialogSave.newInstance(uri, destinationFile, rotation, 
              preview.getCropRect());
      newFragment.show(getSupportFragmentManager(), "saveImage");
    } catch (IOException e) {
      Toast.makeText(getApplicationContext(), R.string.toast_crop_save_failed, Toast.LENGTH_SHORT).show();
    }
  }
  
  private void deleteLastPhotoFile() {
    if(lastPhotoFile != null) {
      lastPhotoFile.delete();
      lastPhotoFile = null;
    }
  }
  private void deletePhotoFile() {
    if(photoFile != null) {
      photoFile.delete();
      photoFile = null;
    }
  }
  
}




Java Source Code List

com.larswerkman.colorpicker.ColorPicker.java
com.larswerkman.colorpicker.OpacityBar.java
com.larswerkman.colorpicker.SVBar.java
com.larswerkman.colorpicker.SaturationBar.java
com.larswerkman.colorpicker.ValueBar.java
com.luboganev.dejalist.Utils.java
com.luboganev.dejalist.crop.CropActivity.java
com.luboganev.dejalist.crop.CropDialogSave.java
com.luboganev.dejalist.crop.CropHighlightView.java
com.luboganev.dejalist.crop.CropUtils.java
com.luboganev.dejalist.crop.CropView.java
com.luboganev.dejalist.crop.ImageViewTouchBase.java
com.luboganev.dejalist.crop.RotateBitmap.java
com.luboganev.dejalist.data.BackupIntentService.java
com.luboganev.dejalist.data.CacheManager.java
com.luboganev.dejalist.data.DejalistContract.java
com.luboganev.dejalist.data.DejalistDatabase.java
com.luboganev.dejalist.data.DejalistProvider.java
com.luboganev.dejalist.data.ProductImageFileHelper.java
com.luboganev.dejalist.data.SelectionBuilder.java
com.luboganev.dejalist.data.entities.Category.java
com.luboganev.dejalist.data.entities.Product.java
com.luboganev.dejalist.ui.AboutActivity.java
com.luboganev.dejalist.ui.CategoriesListCursorAdapter$ViewHolder$$ViewInjector.java
com.luboganev.dejalist.ui.CategoriesListCursorAdapter.java
com.luboganev.dejalist.ui.CategoryDialogFragment$$ViewInjector.java
com.luboganev.dejalist.ui.CategoryDialogFragment.java
com.luboganev.dejalist.ui.CheckableRelativeLayout.java
com.luboganev.dejalist.ui.ChecklistActionTaker.java
com.luboganev.dejalist.ui.ChecklistController.java
com.luboganev.dejalist.ui.ChecklistCursorAdapter$ViewHolder$$ViewInjector.java
com.luboganev.dejalist.ui.ChecklistCursorAdapter.java
com.luboganev.dejalist.ui.ChecklistFragment$$ViewInjector.java
com.luboganev.dejalist.ui.ChecklistFragment.java
com.luboganev.dejalist.ui.ConfirmBackResDialogFragment.java
com.luboganev.dejalist.ui.MainActivity$$ViewInjector.java
com.luboganev.dejalist.ui.MainActivity.java
com.luboganev.dejalist.ui.NavigationCursorAdapter$ViewHolder$$ViewInjector.java
com.luboganev.dejalist.ui.NavigationCursorAdapter.java
com.luboganev.dejalist.ui.ProductActivity$$ViewInjector.java
com.luboganev.dejalist.ui.ProductActivity.java
com.luboganev.dejalist.ui.ProductsGalleryActionTaker.java
com.luboganev.dejalist.ui.ProductsGalleryController.java
com.luboganev.dejalist.ui.ProductsGalleryCursorAdapter$ViewHolder$$ViewInjector.java
com.luboganev.dejalist.ui.ProductsGalleryCursorAdapter.java
com.luboganev.dejalist.ui.ProductsGalleryFragment$$ViewInjector.java
com.luboganev.dejalist.ui.ProductsGalleryFragment.java
com.luboganev.dejalist.ui.SetProductsCategoryDialogFragment.java
com.luboganev.dejalist.ui.UndoBarController.java