如何捕获多个图像并将图像发送到下一个Activity并使用CameraX显示[Android Studio]

4uqofj5v  于 2023-08-07  发布在  Android
关注(0)|答案(4)|浏览(106)

我用的是最新的相机

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


现在重点是如何在将图像保存到外部存储之前提取图像。我想实现的是捕获多个图像并将其保存在缓冲区中,然后将这些图像发送到下一个Activity,并使用列表或其他方式在imageView中显示它们。
现在,这可以通过在imageCapture上使用onImageCapturedCallback来实现,这给了我一个ImageProxy,然后必须将其转换为Byte Array。但这种方法只适用于小尺寸和单一图像。如何实现更高分辨率和多张图像
下面是我用来捕获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然后发送过来吗?
Thanks in Advance..

wvmv3b1j

wvmv3b1j1#

我为我的项目做了两种方法。代码是用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)


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

ahy6op9u

ahy6op9u2#

我建议你把它存储在一个数组列表中。然后将数组列表传递给其他活动。
您要做的是创建一个数组列表,并将uri.toString存储在数组列表中

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

字符串
通过这种方式,您可以在ArrayList中添加多个图像URL,并在Picasso库的帮助下显示。不需要从数据库中获取图像。

wr98u20j

wr98u20j3#

我发现的最简单的方法是

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

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

lskq00tm

lskq00tm4#

首先你需要在takepicture回调图像中捕获后关闭图像。close()将关闭当前图像。全局创建ArrayList并在arraylist中添加imageURL。之后,您可以通过Intent将数组列表发送到任何Activity。

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);
        image.close();
    }

    @Override
    public void onError(@NonNull ImageCaptureException exception) {
        super.onError(exception);
    }
});

字符串
我想这会对你有帮助的,任何疑问都可以refer here to my blog post
这是将ImageProxy转换为位图的函数

// output of the image capture image proxy to bitmap
public Bitmap imageProxyToBitmap(ImageProxy image) {
    ByteBuffer buffer = image.getPlanes()[0].getBuffer();
    buffer.rewind();
    byte[] bytes = new byte[buffer.capacity()];
    buffer.get(bytes);
    byte[] clonedBytes = bytes.clone();
    return BitmapFactory.decodeByteArray(clonedBytes, 0, clonedBytes.length);
}


并将位图保存到本地存储中

// used for save the files internal storage , can view in the gallery or internal storage
public String saveTOInternamMemory(Activity activity, Bitmap bitmapImage){

    File myPath = getInternalStorageDir(internalStorageDir,imageFormat,Environment.DIRECTORY_PICTURES);

    Log.d(TAG, "directory: " + myPath.getAbsolutePath());

    FileOutputStream fos = null;
    try {
        fos = new FileOutputStream(myPath);
        // Use the compress method on the BitMap object to write image to the OutputStream
        bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos);
        Log.d(TAG, "bit exception: Success" );
    } catch (Exception e) {
        Log.d(TAG, "bit exception: " + e.getMessage());
        e.printStackTrace();
    } finally {
        try {
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
            Log.d(TAG, "io exce: " + e.getMessage());
        }
    }
    Log.d(TAG, "absolute path " + myPath.getAbsolutePath());
    return myPath.getAbsolutePath();
}

相关问题