lundi 29 juin 2015

Taking a picture then check its orientation, then rotate it then save it


I've tried to create an application (with Unity3D) that uses an Intent to take a photo and save it.

My issue is that saving the picture then checking its orientation to rotate it if needed and then saving again, is really long.

I think that's due to the fact that I'm using too much tools.

Do you have some tips to reduce the process time?

Here's my (edited) code, thanks in advance :

package com.falsename.my;

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

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.provider.MediaStore;
import android.util.Log;

public class PhotoPlugin implements myAndroidPlugin 
{
    private boolean canTakePhotos;
    private String mCurrentPhotoPath;
    private static PhotoPlugin instance;
    private myActivity activity;
    private File photoFile;

    static final int REQUEST_IMAGE_CAPTURE = 1;

    private File createImageFile() throws IOException 
    {
        // Create an image file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = this.activity.getExternalFilesDir(null);
        File image = File.createTempFile(
            imageFileName,  /* prefix */
            ".jpg",         /* suffix */
            storageDir      /* directory */
        );

        // Save a file: path for use with ACTION_VIEW intents
        mCurrentPhotoPath = image.getAbsolutePath();
        return image;
    }


    private void dispatchTakePictureIntent(myActivity a) 
    {
        if(canTakePhotos)
        {
            Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            // Ensure that there's a camera activity to handle the intent
            if (takePictureIntent.resolveActivity(a.getPackageManager()) != null) {
                // Create the File where the photo should go
                photoFile = null;
                try {
                    photoFile = createImageFile();
                } catch (IOException ex) {
                    Log.e("my", ex.toString());
                }
                // Continue only if the File was successfully created
                if (photoFile != null) {
                    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                            Uri.fromFile(photoFile));
                    takePictureIntent.putExtra(MediaStore.EXTRA_SCREEN_ORIENTATION,
                             ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                    a.startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
                }
            }
        }
    }


    public static void TakePicture()
    {
        instance.dispatchTakePictureIntent(instance.activity);    
    }

    @Override
    public void onActivityCreated(Context c, myActivity a) 
    {
        instance = this;
        this.activity = a;
        canTakePhotos = a.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);        
    }


    @Override
    public void onActivityResume(myActivity a) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onActivityPause(myActivity a) {

    }

    @Override
    public void onActivityNewIntent(myActivity a, Intent intent) 
    {

    }


    @Override
    public void onActivityResult(myActivity a,
        int requestCode, int resultCode, Intent data)
    {    
            if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_IMAGE_CAPTURE)
            {
                a.SendMessage("PhotoListener", "OnPhotoTaken", "");

                PhotoPluginOrientationCheckerParams params = new PhotoPluginOrientationCheckerParams();
                params.activity = a;
                params.path = this.mCurrentPhotoPath;
                params.file = this.photoFile;

                new PhotoPluginOrientationChecker().execute(params);
            }
    }    
}

and :

package com.falsename.my;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import android.content.ContentResolver;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.AsyncTask;
import android.util.Log;

public class PhotoPluginOrientationChecker extends AsyncTask<PhotoPluginOrientationCheckerParams, Void, Void>
{    
    myActivity a;
    String path; 
    File file;

    @Override
    protected Void doInBackground(PhotoPluginOrientationCheckerParams ... params) {

        a = params[0].activity;
        path = params[0].path;
        file = params[0].file;

        try 
        {
            ExifInterface ei = new ExifInterface(path);
            int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

            switch(orientation) 
            {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    SaveBitmap(RotateBitmap(getBitmapFromUri(a, Uri.fromFile(file)), 90));
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    SaveBitmap(RotateBitmap(getBitmapFromUri(a, Uri.fromFile(file)), 180));
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    SaveBitmap(RotateBitmap(getBitmapFromUri(a, Uri.fromFile(file)), 270));
                    break;
            }
        }
        catch(IOException e)
        {
            Log.e("my", "Photo error");
        }

        return null;
    }

    @Override
    protected void onPostExecute(Void result) 
    {
        a.SendMessage("PhotoListener", "OnPhotoSaved", path);    
    }


    private void SaveBitmap(Bitmap bitmap)
    {
        FileOutputStream out = null;
        try
        {
            out = new FileOutputStream(path);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); // bmp is your Bitmap instance
            // PNG is a lossless format, the compression factor (100) is ignored
        } 
        catch (Exception e) 
        {
            e.printStackTrace();
        } 
        finally 
        {
            try
            {
                if (out != null) 
                {
                    out.close();
                }
            } 
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    }

    public static Bitmap RotateBitmap(Bitmap source, float angle)
    {
          Matrix matrix = new Matrix();
          matrix.postRotate(angle);
          return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
    }

    public Bitmap getBitmapFromUri(myActivity a, Uri imageUri) 
    {
        ContentResolver cr = a.getContentResolver();
        cr.notifyChange(imageUri, null);
        Bitmap bitmap;
        try {
            bitmap = android.provider.MediaStore.Images.Media.getBitmap(cr, imageUri);
            return bitmap;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

with :

package com.falsename.my;

import java.io.File;

public class PhotoPluginOrientationCheckerParams 
{
    public myActivity activity;
    public String path;
    public File file;
}


Aucun commentaire:

Enregistrer un commentaire