Camera plugin captures images with wrong orientation - flutter

Im using camera plugin to capture images, but it produces images in landscape orientation even though I keep the phone in portrait orientation.
I tried rotating the images after capturing using a different package, but that was very inefficient as the process takes too long to complete.
Can someone tell why is it happening and is there any solution.
How I initialize the controller
controller = CameraController(
widget.cameras[1],
ResolutionPreset.medium,
imageFormatGroup: ImageFormatGroup.jpeg,
);
and I listen to the controllers imageStream.
Device: Mi Poco F1 |
Android version: 10
I need to capture a minimum of 10 frames per second and push it to a web socket continuously for 30 seconds.
So, even though the solutions in the first 2 comments actually work, they are inefficient for my requirement as they cause the UI to freeze.

Related

Camera X - Accessing both Front and Back Cameras simultaneously using Camera X API

Trying to preview both cameras (front and back) concurrently using Android X API -
Camera camera = cameraProvider.bindToLifecycle((LifecycleOwner)this, cameraSelector, preview); //Back-Camera
Camera camera2 = cameraProvider.bindToLifecycle((LifecycleOwner)this, cameraSelector2, preview2); //Front-Camera
With the above code-snippet, only front camera comes up. If I change the order above, back camera shows up as expected.
Tried acquiring the instances of Camera feature (cameraProvider = ProcessCameraProvider.getInstance(this)) twice, however I found strange observation by mapping one camera per one provider. Upon home press and launching app again, either one of the preview (Back or Front) shows up and there is no pattern found.
Can anyone throw more lights on this? Is it anything to do with the target device i.e. device incompatibility? The target device I am using is OnePlus 5.
CameraX doesn't support opening more than 1 camera at a time, which is why when you attempt to open 2 cameras by calling ProcessCameraProvider.bindToLifecycle() twice, only the second camera is opened.
ProcessCameraProvider provides access to the cameras on the device, and as its name suggests, it has the scope of the process/application, i.e it's a Singleton, once it's initialized, you'll get the same instance with each consequent call to ProcessCameraProvider.getInstance().

How to make video captured by front camera not being inverse Android?

I recording video using MediaRecorder.When using back-camera,it working fine,but when using front camera,the video captured is being flipped/inverse.Means that the item in right,will appear on the left.The camera preview is working fine,just final captured video flipped.
Here is the camera preview looks like
But the final video appear like this(all the item in left hand side,appear on right hand side)
What I tried so far:
I tried to apply the matrix when prepare recorder,but it seems does change anything.
private boolean prepareRecorder(int cameraId){
//# Create a new instance of MediaRecorder
mRecorder = new MediaRecorder();
setCameraDisplayOrientation(this,cameraId,mCamera);
int angle = getVideoOrientationAngle(this,cameraId);
mRecorder.setOrientationHint(angle);
if(cameraId == Camera.CameraInfo.CAMERA_FACING_FRONT){
Matrix matrix = new Matrix();
matrix.preScale(1.0f,-1.0f);
}
//all other code to prepare recorder here
}
I already read for all this question below,but all this seems didnt solve my problem.For information,I using SurfaceView for the camera preview,so this question here doesn't help.
1) Android flip front camera mirror flipped video
2) How to keep android from inverting the image from the front facing camera?
3) Prevent flipping of the front facing camera
So my question is :
1) How to capture a video by front camera which the video not being inverse(exactly the same with camera preview)?
2) How to achieve this when the Camera preview is using SurfaceView but not TextureView ? (cause all the question I mention above,tell about using TextureView)
All possible solution is mostly welcome..Tq
EDIT
I made 2 short video clip to clarify the problem,please download and take a look
1) The video during camera preview of recording
2) The video of the final product of recording
So, if the system camera app produces video similar to your app, you didn't do something wrong. Now it's time to understand what happens to front-facing camera video recording.
The front facing camera is not different from the rear facing camera in the way it captures still pictures or video. There is a difference how the phone displays camera preview on the screen. To make it look more natural to the user, Android (and all other systems) mirrors the preview, so that you can see yourself as if in a mirror.
It is important to understand that this only applies to the way the preview is presented to you. If you pick up any video conferencing app, connect two devices that you hold in two hands, and look at yourself, you will see to your surprise that the two instances of yourself are flipped.
This is not a bug, this is the natural way to present the video to the other party.
See the sketch:
This is how you see the scene:
This is how your peer sees the same scene
Normally, recording of a video is done from the point if view of your peer, as in the second picture. This is the natural setup for, e.g., video conferencing.
But Snapchat and some other social apps choose to store the front-facing video clip as if you record it from the mirror (as if the recorder is in your hand on the first picture). Some people like this feature, others hate it (see https://forums.androidcentral.com/general-help-how/664539-front-camera-pics-mirrored-reversed-only-snapchat.html and https://www.reddit.com/r/nexus6/comments/3846ay/has_anyone_found_a_fix_for_snapchat_flipping)
You cannot use MediaRecorder for that. You can use the lower-level API of MediaCodec to record processed frames. You need to flip each frame 'manually', and this may be a significant performance hit, because normally the MediaRecorder 'connects' the camera to hardware encoder in a very efficient way, without need even to copy the pixels to user memory. This answer shows how you can manipulate the way camera is rendered to texture.
You can achieve this by recording video manually from surface view.
In such case preview and recording will match exactly.
I've been using this library for this purpose:
https://github.com/spaceLenny/recordablesurfaceview
Here is the guide how to use it (not with camera but with OpenGL drawing): https://withintent.uncorkedstudios.com/recording-screen-video-on-android-with-recordablesurfaceview-451c9daa213e

Weird frames appear when using TextureView to play video in ListView

I managed to play multiple videos in one screen circularly, I added TextureViews to ListView with BaseAdapter which is very common and I created a IjkMediaPlayer (IjkMediaplay github)instance for each textureview. I have reused textureview in getView() callback of BaseAdapter, once getView() called, I stop the previous video and play the new video.
This works fine in most of time, but occasionally, TextureView will display some frames which is not belong to the current video, the frames display for very short time during the playback just like a flash.
With effort, I finally found where the strange frames come, they are from the video which is playing outside of the screen.
The weird frames will not appear if I push up the listview to make the outside textureview show up.
I have record a video to show the scene, in the video you will see 2 videos are playing circularly and a weird frame appear occasionally.
I assert that the weird frame(a white phone on the desk in the frame) is from the video below which is playing outside the screen.
click to download the video
Is this a bug of TextureView on Android, and how to avoid the weird playing?
Who can give me some advices?

Any way to determine if the camera is idle?

I'm working with the raw camera image, but need to restart the preview following the capture of an image. When i call startPreview() following takePicture, the android hangs because the camera is till in use. I've waited till after the raw image has been written to disk, but the camera is still in use, so the start preview still hangs the system.
camera.takePicture(null, null, null);
(test needed here){
camera.startPreview();
}
Putting the start preview in the rawcallback hangs the android.
When calling takePicture, the jpegCallback occurs after the camera is finished, so it is safe to start the preview, but this also creates a .jpg.
The question is following the takePicture, is there any way to determine when the camera is idle? (other than the jpegCallback?).
I've found ways around the problem, such as starting the preview on a timer, but still wonder if there is any way to determine the actual status of the camera and a way to test when it is save to restart the preview.
After calling the takePicture() function, you must wait until the JPEG callback has returned for the camera to be ready to use again. There is no way to monitor its status. The documentation explicitly states the following:
After calling this method, you must not call startPreview() or take
another picture until the JPEG callback has returned.
If you need some fast way of grabbing frames (i.e. images) without stopping and restarting the camera preview, you can implement the PreviewCallback interface which will simply allow you to grab preview frames without stopping the preview at all. Just remember that you will need to convert these from YUV format (which is not difficult using Android's YUVImage class.

barcodereader sample application

I am using the barcodereader sample application provided in the cascades samples to embed a QRCode scanner into my application.
As it stands the sample is great, but I want the scanner to open as soon as the user navigates to my screen and I want to get rid of the opening slider images that are in the sample.
Firstly, I have tried removing the images and their animations and adding the action:
onCreationCompleted: {
camera.open()
}
to the Page. This opens the camera perfectly as expected, but for some reason, the bacrode just doesn't scan.
So, I wound back a step, and this time I just put the code in exactly as is and just changed the code to read:
onCreationCompleted: {
startupAnimation.play()
}
As expected, the screen open, plays the annimation, but still it fails to read barcodes, however, if I invoke the animation again (by tapping the screen), the animation plays again and the scanner reads the barcode without any issues at all.
All I can think of is that this is a timing issue and that I need some sort of delay after the screen has been created before the camera can be started as a barcode reader?
Anyone able to help?
Thanks,
Douglas
To get scanning right away at application launch, you need to make sure the camera is actually set up and initialized.
Basically, in onCreationComplete, open the camera. In onCameraOpened, start the viewfinder. In onViewfinderStarted, set the barcode detector camera to be the camera.