Java 如何捕获多个图像并将其发送到下一个活动,并使用CameraX[Android Studio]显示它们

Java 如何捕获多个图像并将其发送到下一个活动,并使用CameraX[Android Studio]显示它们,java,android,android-studio,android-camerax,Java,Android,Android Studio,Android Camerax,我正在使用最新的cameraX def camerax_version = "1.0.0-beta11" 我能够使用下面的代码拍摄照片并将图像保存到文件夹中的外部存储 File photoFile = new File(outputDirectory, "Image_" + System.currentTimeMillis() + ".jpg"); ImageCapture.OutputFileOptions

我正在使用最新的cameraX

def camerax_version = "1.0.0-beta11"
我能够使用下面的代码拍摄照片并将图像保存到文件夹中的外部存储

File photoFile = new File(outputDirectory, "Image_" + System.currentTimeMillis() + ".jpg");

            ImageCapture.OutputFileOptions outputFileOptions = new ImageCapture.OutputFileOptions.Builder(photoFile).build();

            imageCapture.takePicture(outputFileOptions, ContextCompat.getMainExecutor(getBaseContext()), new ImageCapture.OnImageSavedCallback() {
                @Override
                public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {
                    Uri.fromFile(photoFile);
                    Toast.makeText(getBaseContext(), "Image Saved" + photoFile.getAbsolutePath(), Toast.LENGTH_SHORT).show();
                }

                @Override
                public void onError(@NonNull ImageCaptureException exception) {
                    Toast.makeText(getBaseContext(), "Error Saving Image" + photoFile.getAbsolutePath(), Toast.LENGTH_SHORT).show();
                }
            });
现在重点是如何在将图像保存到外部存储器之前提取图像。我想要实现的是捕获多个图像并将其保存在缓冲区中,然后将这些图像发送到下一个活动,并使用列表或其他方式在imageView中显示它们

现在可以使用
imageCapture
上的
onImageCapturedCallback
来实现这一点,它给了我一个ImageProxy,然后必须转换为字节数组。但这一过程只适用于小尺寸和单一图像。 对于更高分辨率和多幅图像,我如何实现这一点

下面是我用来捕获
ImageProxy
并将imageCapture设置为“YUV”的代码,遗憾的是它根本不起作用

    imageCapture.takePicture(ContextCompat.getMainExecutor(getBaseContext()), new ImageCapture.OnImageCapturedCallback() {
        @Override
        public void onCaptureSuccess(@NonNull ImageProxy image) {
            super.onCaptureSuccess(image);
            @SuppressLint("UnsafeExperimentalUsageError") Image cimage = image.getImage();
            Image.Plane[] planes = cimage.getPlanes();
            ByteBuffer yBuffer = planes[0].getBuffer();
            ByteBuffer uBuffer = planes[1].getBuffer();
            ByteBuffer vBuffer = planes[2].getBuffer();

            int ySize = yBuffer.remaining();
            int uSize = uBuffer.remaining();
            int vSize = vBuffer.remaining();

            byte[] nv21 = new byte[ySize + uSize + vSize];

            yBuffer.get(nv21,0,ySize);
            vBuffer.get(nv21,ySize,vSize);
            uBuffer.get(nv21,ySize + vSize,uSize);

            YuvImage yuvImage = new YuvImage(nv21,ImageFormat.NV21,cimage.getWidth(),cimage.getHeight(),null);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            yuvImage.compressToJpeg(new Rect(0,0,yuvImage.getWidth(),yuvImage.getHeight()),100,out);
            byte[] imageBytes = out.toByteArray();

            Intent intent = new Intent(MainActivity.this,MainActivity2.class);
            intent.putExtra("image",imageBytes);
            MainActivity.this.startActivity(intent);

        }

        @Override
        public void onError(@NonNull ImageCaptureException exception) {
            super.onError(exception);
        }
    });
我可以将图像添加到
ArrayList
中,然后将它们发送过来吗


提前感谢。

我为我的项目采取了两种方式。代码是用kotlin语言编写的。 你很容易理解

val image = imageProxy.image
val bitmap = Bitmap.createBitmap(image.width, image.height, 
Bitmap.Config.ARGB_8888)
如果它不起作用,你可以使用YuvtoRgbConvertor,如果你愿意,我有完整的kotlin代码,或者你可以自己编写。然后可以像这样转换位图

val convertor = YuvToRgbConvertor
convertor.yuvToRgb(image , bitmap)

这就是我为我的项目所做的。

我建议您将其存储在数组列表中。然后将数组列表传递给其他活动

您需要做的是创建一个数组列表并在数组列表中存储uri.tostring

String newurl=uri.toString
`arraylist.add(newurl)`

通过这种方式,您可以在ArrayList中添加多个图像URL,并在毕加索库的帮助下显示。无需从数据库中获取图像。

我发现的最简单的方法是

preview.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Bitmap scaledBitmap = null;

                ContextWrapper cw = new ContextWrapper(getApplicationContext());
                String PATH = Environment.getExternalStorageDirectory() + "/download/";
                File file = new  File(PATH + "myImage.jpeg");

                if (file.exists()) {
                    myImage.setImageDrawable(Drawable.createFromPath(file.toString()));
                }
                else {
                    myImage.setImageDrawable(Drawable.createFromPath(null));
                    Toast.makeText(nextPage.this, "Not found", Toast.LENGTH_LONG).show();
                }
            }
        });

您可以根据代码更改路径。

我建议先将图像转换为位图,然后使用ImageProxy.close获取下一帧并捕获它,然后将所有位图保存到ArrayList中,然后您可以显示它们。@mmdrezabaqalpour然后我可以使用Intent.putExtra()将这些位图发送到新活动吗;?是的,只要位图是parcelabe对象,您就可以有意发送它。intent.putParcelableArrayListExtra()@mmdrezabaqalpour在ImageCaptureCallback期间,我必须将imageCapture设置为YUV格式才能将图像转换为位图。这会显著降低图像质量。有没有办法……我有一些方法,如果对你有用的话,我会贴出来作为答案。