[英]How Can I Capture Multiple Images and send the images to next Activity and display them using CameraX [Android Studio]
Am using the latest cameraX我正在使用最新的相机X
def camerax_version = "1.0.0-beta11"
I able to take picture and save image to External Storage in a folder using this below code我可以使用以下代码拍照并将图像保存到文件夹中的外部存储
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();
}
});
Now the point is on how to extract the image before saving it to external storage.现在的重点是如何在将图像保存到外部存储之前提取图像。 What I want to achieve is to capture multiple images and save it in buffer and send those images to next Activity and display them in a imageView using list or something.
我想要实现的是捕获多个图像并将其保存在缓冲区中并将这些图像发送到下一个活动并使用列表或其他东西将它们显示在 imageView 中。
Now this can be achieved using onImageCapturedCallback
on imageCapture
which gives me a ImageProxy which then have to convert to Byte Array.现在这可以使用
imageCapture
上的onImageCapturedCallback
来实现,它给了我一个 ImageProxy 然后必须转换为字节数组。 But this process apples to only small size and single image.但是这个过程只适用于小尺寸和单一图像。 How can I achieve this for higher resolution and multiple images .
对于更高分辨率和多张图像,我怎样才能做到这一点。
Below is the code I used to capture ImageProxy
and set imageCapture to "YUV", Sadly it didn't work at all下面是我用来捕获
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);
}
});
Can I add Image to ArrayList
and then sent them over?我可以将 Image 添加到
ArrayList
然后将它们发送过来吗?
Thanks in Advance..提前致谢..
There are two ways that I did for my project.我为我的项目做了两种方法。 The code is in kotlin language.
代码是 kotlin 语言的。 You can understand it easily.
你可以很容易地理解它。
val image = imageProxy.image
val bitmap = Bitmap.createBitmap(image.width, image.height,
Bitmap.Config.ARGB_8888)
If it didn't work you can use a YuvtoRgbConvertor I have the full kotlin code if you want or you can write your own.如果它不起作用,您可以使用 YuvtoRgbConvertor 如果您愿意,我有完整的 kotlin 代码,或者您可以编写自己的代码。 then you can convert the bitmap like this.
然后你可以像这样转换位图。
val convertor = YuvToRgbConvertor
convertor.yuvToRgb(image , bitmap)
That is what I have done for my project.这就是我为我的项目所做的。
What I suggest you is to store in an array list.我建议您存储在数组列表中。 and then pass an array list to other activities.
然后将数组列表传递给其他活动。
What you have to do is create an array list and store uri.tostring in the array list您要做的是创建一个数组列表并将 uri.tostring 存储在数组列表中
String newurl=uri.toString
`arraylist.add(newurl)`
This way you can add multiple image URLs in ArrayList and display with the help of the Picasso library.这样,您可以在 ArrayList 中添加多个图像 URL,并在 Picasso 库的帮助下显示。 No need to fetch images from the database.
无需从数据库中获取图像。
The easiest way that I found was this我发现的最简单的方法是这个
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();
}
}
});
You can change the path according to your code.您可以根据您的代码更改路径。
First you need to close the image after capturing inside the takepicture callback image.close() will close the current image .首先,您需要在 takepicture 回调中关闭图像。close() 将关闭当前图像。 the create ArrayList globaly and add the imageURL in the arraylist .
全局创建 ArrayList 并将 imageURL 添加到 arraylist 中。 After theat you can send the arraylist to any activity by intent.
在 theat 之后,您可以按意图将数组列表发送到任何活动。
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);
}
});
I think this will help you, any doubts just refer here to my blog post我认为这会对您有所帮助,任何疑问都可以在这里参考我的博客文章
This is the function for converting the ImageProxy to bitmap这是将 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);
}
And save the bitmap to your local storage并将位图保存到本地存储
// 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();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.