简体   繁体   中英

LibGDX : How to retrieve a picture that was taken through the camera and saved locally?

What my application does:

1- The user can take a picture through the device camera. (works)

2- The application creates a new File with the following folders (tested with the following folders to make sure that it saves the file properly) :

a. File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "images");
-  File mediaFile = new File(mediaStorageDir.getPath()+File.separator+fileName + ".jpg");

b. File mediaStorageDir = new File(Gdx.files.getExternalStoragePath().toString());
-  File mediaFile = new File(mediaStorageDir.getPath()+File.separator+fileName+".jpg");

c. File mediaStorageDir = new File(Gdx.files.getLocalStoragePath().toString());
-  File mediaFile = new File(mediaStorageDir.getPath()+File.separator+fileName+".jpg");

3- The application rescales+compresses the picture down to 1024x512 with bmp.compress(quality=25), then saves it. (works)

public boolean compressToFile(byte[] data, int quality, File fileHandle) {
    File mediaFile = fileHandle;
    Pixmap pixmap = new Pixmap(data, 0, data.length);

    if(quality<0)
        quality = 0;
    if(quality>100)
        quality = 100;

    FileOutputStream fos;
    int x=0,y=0;
    int xl=0,yl=0;
    try {
        Bitmap bmp = Bitmap.createBitmap(pixmap.getWidth(), pixmap.getHeight(), Bitmap.Config.ARGB_8888);
        // we need to switch between LibGDX RGBA format to Android ARGB format
        for (x=0,xl=pixmap.getWidth(); x<xl;x++) {
            for (y=0,yl=pixmap.getHeight(); y<yl;y++) {
                int color = pixmap.getPixel(x, y);
                // RGBA => ARGB
                int RGB = color >> 8;
                int A = (color & 0x000000ff) << 24;
                int ARGB = A | RGB;
                bmp.setPixel(x, y, ARGB);
            }
        }

        fos = new FileOutputStream(mediaFile, false);
        boolean compressed = bmp.compress(CompressFormat.JPEG, quality, fos);
        if(compressed)
            System.out.println("zgzg2020:: compressed SUCCESS!");
        else
            System.out.println("zgzg2020:: compressed FAILED!");
        fos.close();

        int WIDTH = 1024, HEIGHT = 512;
        File f = mediaFile;
        Bitmap shrunkBmp = downsizeImage(f, WIDTH, HEIGHT);
        fos = new FileOutputStream(mediaFile, false);
        shrunkBmp.compress(CompressFormat.JPEG, 100, fos);
        fos.close();

        return true;
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    }

    return false;
}

Scale down.

         public Bitmap downsizeImage(File file, int width, int height) {
        BitmapFactory.Options opts = new BitmapFactory.Options ();
        opts.inSampleSize = 2;   // for 1/2 the image to be loaded
        Bitmap thumb = Bitmap.createScaledBitmap(BitmapFactory.decodeFile(file.getPath(), opts), width, height, false);
        return thumb;
    }

4- To confirm that the jpg was saved properly. I've tested with all the three above paths.

System.out.println("b4 pictureFile= " + file.getPath().toString() + "=> " + file.exists());//Returns false.
compressToFile(data, quality, file);//Here is where the compression, scale down, write to disk.
System.out.println("af pictureFile= " + file.getPath().toString() + "=> " + file.exists());//Returns true

5- Read that saved picture and render it on screen. The application crashes here!!!

mode = Mode.render;
System.out.println("AssessPath:"+file.toString());//to confirm the path
texture = new Texture(file.toString());//(FAILS!!)

ERROR

com.badlogic.gdx.utils.GdxRuntimeException: Couldn't load file

Notes:

I'm doing this with platform specific code . This interface is used in the core code.

public interface GalleryOpener {
    void openGallery();    
    String getSelectedImagePath();
}

And this is the implementation on android.

public class AndroidLauncher extends AndroidApplication implements GalleryOpener {

    public static final int SELECT_IMAGE_CODE = 1;
    private String selectedImagePath;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();

        initialize(new GreenWall(this), config);
    }

    @Override
    public GalleryOpener galleryOpener() {
        return this;
    }

    @Override
    public void openGallery() {
        selectedImagePath = null;

        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent, "Select Image"), SELECT_IMAGE_CODE);
    }

    @Override
    public String getSelectedImagePath() {
        return selectedImagePath;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK && requestCode == SELECT_IMAGE_CODE) {
            Uri imageUri = data.getData();
            selectedImagePath = getPath(imageUri);
        }
        //super.onActivityResult(requestCode, resultCode, data);
    }

    private String getPath(Uri uri) {
        if (uri.getScheme().equalsIgnoreCase("file")) {
            return uri.getPath();
        }

        Cursor cursor = getContentResolver().query(uri, new String[]{MediaStore.Images.Media.DATA}, null, null, null);
        if (cursor == null) {
            return null;
        }

        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();

        String filePath = cursor.getString(column_index);
        cursor.close();

        return filePath;
    }
}

Using this can look like that:

galleryOpener.openGallery();
String selectedImagePath = galleryOpener.getSelectedImagePath();
if (selectedImagePath != null) {
    FileHandle fileHandle = Gdx.files.absolute(selectedImagePath);
    Texture texture = new Texture(fileHandle);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM