【问题标题】:LibGDX : How to retrieve a picture that was taken through the camera and saved locally?LibGDX:如何检索通过相机拍摄并保存在本地的图片?
【发布时间】:2016-04-28 18:30:05
【问题描述】:

我的应用程序做什么:

1- 用户可以通过设备相机拍照。 (作品)

2- 应用程序创建一个包含以下文件夹的新文件(使用以下文件夹进行测试以确保正确保存文件)

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- 应用程序使用 bmp.compress(quality=25)重新缩放+压缩图片到 1024x512,然后保存。 (作品)

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;
}

缩小。

         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- 确认 jpg 已正确保存。以上三种路径我都测试过了。

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- 读取保存的图片并将其呈现在屏幕上。 应用程序在这里崩溃!!!

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

错误

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

注意事项:

【问题讨论】:

    标签: java android camera libgdx load


    【解决方案1】:

    我正在使用platform specific code 进行此操作。该接口用于核心代码。

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

    这是在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;
        }
    }
    

    使用它可能看起来像这样:

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

    【讨论】:

    • 感谢您的快速回复!我会马上测试它,让你知道它是怎么回事!
    • 我将以上内容添加到我的代码中。但是,galleryOpener.openGallery() 会在我的设备上打开图库,但应用程序的流程直接继续执行以下代码,而无需等待我选择照片;因此以“batch.beging() texture=null”崩溃。如何,我是否强制 openGallery 方法等待我选择照片,然后再将控件返回 String selectedImagePath = galleryOpener.getSelectedImagePath();行吗?
    • 我还是卡住了...该控件只是不会等待用户在galleryOpener 中选择图片,然后才返回渲染循环。它只是继续以空指针崩溃。恐怕这个答案不起作用。
    • 嗯,你是对的。我不得不用两个不同的按钮来解决它。第一个打开图库,第二个将实际“处理”所选图片。您可以通过像 while (galleryOpener.getSelectedImagePath() == null) Thread.sleep(100); 这样的忙碌等待来解决它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-04
    • 2017-09-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多