Time Stamp image taken from Default Camera

I am trying to Time Stamp a image i am getting from the camera. This source is code provided from the developers website, and i am trying to make add on to it. With creating a time stamp bitmap and merging over the image taken by the camera via a intent. Please any insight, recommendations, or review would be extremely appreciated. I do have some code in the example i've created that i may or may not need. Android Developer Original Source Code http://developer.android.com/training/camera/photobasics.html

public class PhotoIntentActivity extends Activity {

private static final int ACTION_TAKE_PHOTO_B = 1;

private static final String BITMAP_STORAGE_KEY = "viewbitmap";
private static final String IMAGEVIEW_VISIBILITY_STORAGE_KEY = "imageviewvisibility";
private ImageView mImageView;
private Bitmap mImageBitmap;



private String mCurrentPhotoPath;

private static final String JPEG_FILE_PREFIX = "IMG_";
private static final String JPEG_FILE_SUFFIX = ".jpg";

private AlbumStorageDirFactory mAlbumStorageDirFactory = null;


/* Photo album for this application */
private String getAlbumName() {
    return getString(R.string.album_name);
}

//change from private to public 5:32 7/13
public File getAlbumDir() {
    File storageDir = null;

    if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {

        storageDir = mAlbumStorageDirFactory.getAlbumStorageDir(getAlbumName());

        if (storageDir != null) {
            if (! storageDir.mkdirs()) {
                if (! storageDir.exists()){
                    Log.d("TimeStamped", "failed to create directory");
                    return null;
                }
            }
        }

    } else {
        Log.v(getString(R.string.app_name), "External storage is not mounted READ/WRITE.");
    }

    return storageDir;
}
//change from private to public 5:32 7/13
public File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = JPEG_FILE_PREFIX + timeStamp + "_";
    File albumF = getAlbumDir();
    File imageF = File.createTempFile(imageFileName, JPEG_FILE_SUFFIX, albumF);
    return imageF;
}
//change from private to public 5:32 7/13
public File setUpPhotoFile() throws IOException {

    File f = createImageFile();
    mCurrentPhotoPath = f.getAbsolutePath();

    return f;
}


//change from private to public 5:32 7/13
public void setPic() {


    /* There isn't enough memory to open up more than a couple camera photos */
    /* So pre-scale the target bitmap into which the file is decoded */

    /* Get the size of the ImageView */
    int targetW = mImageView.getWidth();
    int targetH = mImageView.getHeight();

    /* Get the size of the image */
    BitmapFactory.Options bmOptions = new BitmapFactory.Options();
    bmOptions.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
    int photoW = bmOptions.outWidth;
    int photoH = bmOptions.outHeight;

    /* Figure out which way needs to be reduced less */
    int scaleFactor = 1;
    if ((targetW > 0) || (targetH > 0)) {
        scaleFactor = Math.min(photoW/targetW, photoH/targetH); 
    }

    /* Set bitmap options to scale the image decode target */
    bmOptions.inJustDecodeBounds = false;
    bmOptions.inSampleSize = scaleFactor;
    bmOptions.inPurgeable = true;

    /* Decode the JPEG file into a Bitmap */
  //        Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
 //     
 //     /* Associate the Bitmap to the ImageView */
 //     mImageView.setImageBitmap(bitmap);
    Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions); 
    //Time Stamp the Bitmap
    Bitmap replacedBitmap = timestampItAndSave(bitmap); 


// replacing bitmap with a time stamped bitmap  
    mImageView.setImageBitmap(replacedBitmap); 
    mImageView.setVisibility(View.VISIBLE);
}
//  new code        

//toEdit
// new code 5:38 7/13 changed from private
public Bitmap timestampItAndSave(Bitmap toEdit){
    Bitmap dest = Bitmap.createBitmap(toEdit.getWidth(), toEdit.getHeight(), Bitmap.Config.ARGB_8888);

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String dateTime = sdf.format(Calendar.getInstance().getTime()); // reading local time in the system

    Canvas cs = new Canvas(dest);
    Paint tPaint = new Paint();
    tPaint.setTextSize(35);
    tPaint.setColor(Color.BLUE);
    tPaint.setStyle(Style.FILL);
    float height = tPaint.measureText("yY");
    cs.drawBitmap(dest, 100 ,100, tPaint);
    cs.drawText(dateTime, 20f, height+15f, tPaint);


    try {
        dest.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(new File(Environment.getExternalStorageDirectory() + "/timestamped")));
   //           dest.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(new File(Environment.getExternalStorageDirectory() + "/timestamped")));

    } catch (FileNotFoundException e) {
    e.printStackTrace();
    return null;
  }
    return dest;
}

 public Bitmap combineImages(Bitmap bitmap, Bitmap dest) { // can add a 3rd parameter 'String loc' if you want to save the new image - left some code to do that at the bottom 
        Bitmap timestampedandmerged = null; 




        int width, height = 0; 

        if(bitmap.getWidth() > dest.getWidth()) { 
          width = bitmap.getWidth(); 
          height = bitmap.getHeight() + dest.getHeight(); 
        } else { 
          width = dest.getWidth(); 
          height = bitmap.getHeight() + dest.getHeight(); 
        } 

        timestampedandmerged = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 

        Canvas comboImage = new Canvas(timestampedandmerged); 

        comboImage.drawBitmap(bitmap, 0f, 0f, null); 
        comboImage.drawBitmap(dest, 0f, bitmap.getHeight(), null); 



         // this is an extra bit I added, just incase you want to save the new image somewhere and then return the location
       // new code 5:38 7/13
        String tmpImg = String.valueOf(System.currentTimeMillis()) + ".png"; 
       // new code 5:38 7/13
        OutputStream os = null; 
        try { 
          os = new FileOutputStream(timestampedandmerged + tmpImg); 
          timestampedandmerged.compress(CompressFormat.PNG, 100, os); 
        } catch(IOException e) { 
          Log.e("combineImages", "problem combining images", e); 
        } 
        // new code 5:38 7/13
        return timestampedandmerged; 
      } 


private void galleryAddPic() {
        Intent mediaScanIntent = new Intent("android.intent.action.MEDIA_SCANNER_SCAN_FILE");
        File f = new File(mCurrentPhotoPath);
        Uri contentUri = Uri.fromFile(f);
        mediaScanIntent.setData(contentUri);
        this.sendBroadcast(mediaScanIntent);
}

private void dispatchTakePictureIntent(int actionCode) {

    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    switch(actionCode) {
    case ACTION_TAKE_PHOTO_B:
        File f = null;

        try {
            f = setUpPhotoFile();
            mCurrentPhotoPath = f.getAbsolutePath();
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
        } catch (IOException e) {
            e.printStackTrace();
            f = null;
            mCurrentPhotoPath = null;
        }
        break;

    default:
        break;          
    } // switch

    startActivityForResult(takePictureIntent, actionCode);
}


private void handleBigCameraPhoto() {

    if (mCurrentPhotoPath != null) {
        setPic();
        galleryAddPic();
        mCurrentPhotoPath = null;
    }

}

Button.OnClickListener mTakePicOnClickListener = 
    new Button.OnClickListener() {

    public void onClick(View v) {
        dispatchTakePictureIntent(ACTION_TAKE_PHOTO_B);
    }
};


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    mImageView = (ImageView) findViewById(R.id.imageView1);
    mImageBitmap = null;

    Button picBtn = (Button) findViewById(R.id.btnIntend);
    setBtnListenerOrDisable( 
            picBtn, 
            mTakePicOnClickListener,
            MediaStore.ACTION_IMAGE_CAPTURE
    );


    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
        mAlbumStorageDirFactory = new FroyoAlbumDirFactory();
    } else {
        mAlbumStorageDirFactory = new BaseAlbumDirFactory();
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
    case ACTION_TAKE_PHOTO_B: {
        if (resultCode == RESULT_OK) {
            handleBigCameraPhoto();
        }
        break;
    } // ACTION_TAKE_PHOTO_B
  } 

}

   // Some lifecycle callbacks so that the image can survive orientation change

protected void onSaveInstanceState(Bundle outState) {
    outState.putParcelable(BITMAP_STORAGE_KEY, mImageBitmap);
        outState.putBoolean(IMAGEVIEW_VISIBILITY_STORAGE_KEY, (mImageBitmap != null) );
        super.onSaveInstanceState(outState);
}


protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    mImageBitmap = savedInstanceState.getParcelable(BITMAP_STORAGE_KEY);
    mImageView.setImageBitmap(mImageBitmap);
    mImageView.setVisibility(
            savedInstanceState.getBoolean(IMAGEVIEW_VISIBILITY_STORAGE_KEY) ? 
                    ImageView.VISIBLE : ImageView.INVISIBLE
    );

}

/**
 * Indicates whether the specified action can be used as an intent. This
 * method queries the package manager for installed packages that can
 * respond to an intent with the specified action. If no suitable package is
 * found, this method returns false.
 * http://android-developers.blogspot.com/2009/01/can-i-use-this-intent.html
 *
 * @param context The application's environment.
 * @param action The Intent action to check for availability.
 *
 * @return True if an Intent with the specified action can be sent and
 *         responded to, false otherwise.
 */
public static boolean isIntentAvailable(Context context, String action) {
    final PackageManager packageManager = context.getPackageManager();
    final Intent intent = new Intent(action);
    List<ResolveInfo> list =
        packageManager.queryIntentActivities(intent,
                PackageManager.MATCH_DEFAULT_ONLY);
    return list.size() > 0;
}

private void setBtnListenerOrDisable( 
        Button btn, 
        Button.OnClickListener onClickListener,
        String intentName
) {
    if (isIntentAvailable(this, intentName)) {
        btn.setOnClickListener(onClickListener);            
    } else {
        btn.setText( 
            getText(R.string.cannot).toString() + " " + btn.getText());
        btn.setClickable(false);
    }
}

}

Answers


Well one crude but quick way would be to create an ImageButton consisting of the image and simply set text over the image. I think this works. Try it out and let me know.


Need Your Help

spring mvc not returning json content - error 406

java jquery spring spring-mvc jackson

I am using Spring MVC with JSON as specified in Ajax Simplification Spring 3.0 article.

Activate a single ELPA package out of many

emacs elpa

I want to start Emacs from a clean state and activate only one package in ~/.emacs.d/elpa/, not all of them. Specifically, I need to load a bleeding-edge version of Org-mode, while clean Emacs load...