I have an app saving camera images continuously by using ImageReader.
Now I have a requisite need to add multiple SurfaceView dynamically for showing different size of preview after camera session created.
Because the surface of ImageReader was added before session created like this:
mBuilder = mCameraDevice!!.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)
mBuilder!!.addTarget(mImageReader!!.surface)
val surfaces = ArrayList<Surface>()
surfaces.add(mImageReader!!.surface)
mCameraDevice!!.createCaptureSession(surfaces, mSessionCallback, mBackgroundHandler)
And my new SurfaceView will be create after createCaptureSession.
So how should I add another preview surface to device for receiver data from camera2?
This is not possible with the camera2 directly, for different output resolutions. If you need to change the resolution of an output, you have to create a new capture session with the new outputs you want.
If you want multiple SurfaceViews of the same size, you can use the surface sharing APIs added in API level 26 and later in OutputConfiguration (https://developer.android.com/reference/android/hardware/camera2/params/OutputConfiguration).
If that's not sufficient, the other option is to connect the camera to a SurfaceTexture with the maximum SurfaceView resolution you might want, and then render lower resolution outputs from that via OpenGL, creating EGL windows for each new SurfaceView you want to draw to. That's a lot of code needed to set up the EGL context and rendering, but should be fairly efficient.
I'm trying to implement tap to focus on a Samsung Xcover4 for an industrial application (specific to this device).
The idea is to have the device stuffed into a kind of box with a hole where the camera is, and to use it to scan cards with qr codes on it.
So the "scan zone" is always the same, and should be set when the app start with a tap. Once it's done, camera should always focus on that zone and compute exposure on that spot
I'm using Xzing library, so I hacked the CameraManager manager class a little and it's working ok for the fixed focus zone.
I found the "spot" metering value by dumping native camera parameters, but one thing I can't figure out is how to set its position. I guess it can be done, since samsung does it in the native camera app.
ArrayList<Camera.Area> focusAreas = new ArrayList<Camera.Area>();
focusAreas.add(new Camera.Area(focusArea, 1000));
cameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
cameraParameters.setFocusAreas(focusAreas);
cameraParameters.setMeteringAreas(focusAreas);
cameraParameters.setZoom(0);
cameraParameters.set("metering", "spot");
camera.setParameters(cameraParameters);
camera.autoFocus(autoFocusManager);
Below is the list of natvie camera paremeters.
3dnr=false;
Infinity=Infinity;
antibanding=50hz;
antibanding-values=auto,50hz;
auto-exposure-lock-supported=true;
auto-whitebalance-lock-supported=true;
best-capture=0;
brightness=0;
brightness-max=2;
brightness-min=-2;
burst-capture=0;
burstshot-fps-values=(4,4);
constant-growth-rate-zoom-supported=true;
contrast=auto;
drc=false;
dual_mode=-1;
dualrecording-hint=-1;
dynamic-range-control=off;
effect=none;
effect-available-fps-values=(10000,15000);
effect-values=none,mono,negative,sepia,posterize;
effectrecording-hint=0;
exposure-compensation=0;
exposure-compensation-step=0.1;
fast-fps-mode=-1;
flash-mode=off;
flash-mode-values=off,auto,on,torch;
fnumber-value-denominator=10;
fnumber-value-numerator=19;
focal-length=3.70;
focallength-35mm-value=28;
focallength-value-denominator=100;
focallength-value-numerator=370;
focus-areas=(257,416,263,422,1000);
focus-distances=0.10,1.20,Infinity;
focus-mode=auto;
focus-mode-values=auto,macro,continuous-video,continuous-picture;
hdr-mode=0;
horizontal-view-angle=62.2;
hue=0;
hue-max=2;
hue-min=-2;
imageuniqueid-value=V13LLIA02PM V13LLKB16SA
;
intelligent-mode=-1;
iso=auto;
iso-values=auto,100,200,400,800;
jpeg-quality=96;
jpeg-thumbnail-height=384;
jpeg-thumbnail-quality=100;
jpeg-thumbnail-size-values=512x384,512x288,384x384,320x240,0x0;
jpeg-thumbnail-width=512;
max-exposure-compensation=20;
max-num-detected-faces-hw=16;
max-num-detected-faces-sw=0;
max-num-focus-areas=1;
max-num-metering-areas=0;
max-zoom=30;
maxaperture-value-denominator=100;
maxaperture-value-numerator=185;
metering=center;
metering-areas=;
metering-values=matrix,center,spot;
min-exposure-compensation=-20;
odc=false;
phase-af=off;
phase-af-values=off;
picture-format=jpeg;
picture-format-values=jpeg;
picture-size=4128x3096;
picture-size-values=4128x3096,4128x2322,3264x2448,3264x1836,3088x3088,2160x2160,2048x1536,2048x1152,1920x1080,1440x1080,1280x720,960x720,640x480,320x240;
preferred-preview-size-for-video=1280x720;
preview-format=yuv420sp;
preview-format-values=yuv420sp,yuv420p;
preview-fps-range=15000,30000;
preview-fps-range-values=(15000,15000),(24000,24000),(15000,30000),(30000,30000);
preview-frame-rate=30;
preview-frame-rate-values=15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30;
preview-size=1280x720;
preview-size-values=1280x720,1056x704,960x720,880x720,720x720,720x480,640x480,352x288,320x240,176x144;
rotation=0;
rt-hdr=off;
rt-hdr-values=off;
saturation=0;
saturation-max=2;
saturation-min=-2;
scene-mode=auto;
scene-mode-values=auto,action,portrait,landscape,night,night-portrait,theatre,beach,snow,sunset,steadyphoto,fireworks,sports,party,candlelight;
sharpness=0;
sharpness-max=2;
sharpness-min=-2;
smooth-zoom-supported=false;
vertical-view-angle=39.4;
video-frame-format=nv21;
video-size=1920x1080;
video-size-values=1920x1080,1440x1080,1072x1072,1280x720,960x720,800x450,720x480,640x480,480x320,352x288,320x240,176x144;
video-snapshot-supported=true;
video-stabilization-supported=false;
vrmode=-1;
wdr=0;
whitebalance=auto;
whitebalance-values=auto,incandescent,fluorescent,daylight,cloudy-daylight;
zoom=0;
zoom-ratios=100,104,109,114,120,125,131,138,144,151,158,166,174,182,190,200,209,219,229,240,251,263,276,289,303,317,332,348,364,381,400;
zoom-supported=true
Thank you.
In my android app, I am trying to do some image recognition, and I want to open the camera and see the camera generated images before even taking a pic, like the camera browse mode.
Basically as you browse I want to continuously grab the current screen and then read it and generate some object to update some text on the screen. Something like this
#Override
// this gets called every 5 seconds while in camera browse mode. bitmap is the image of the camera currently
public void getScreen(Bitmap bitmap) {
MyData data = myalgorithm(bitmap);
displayCountOnScreen(data);
}
I saw this app https://play.google.com/store/apps/details?id=com.fingersoft.cartooncamera&hl=en
and in camera browse mode, they change the screen and put some other GUI stuff on the screen. I want to do that too.
Anyone know how I can do this?
Thanks
If all you want to do is put some GUI elements on the screen, then there is no need to fetch all the preview frames as Bitmaps (though you could do that as well, if you want):
Create a layout with a SurfaceView for where you want the video data to appear, and then put other views on top.
In onCreate, you can get it like this:
surfaceView = (SurfaceView)findViewById(R.id.cameraSurfaceView);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this); // For when you need to know when it changes.
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
When you create a camera, you need to pass it a Surface to display the preview on, see:
http://developer.android.com/reference/android/hardware/Camera.html#setPreviewDisplay(android.view.SurfaceHolder):
Camera camera = ...
...
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
If you want to do image recognition, what you want are the raw image bytes to work with. In this case, register a PreviewCallback, see here:
http://developer.android.com/reference/android/hardware/Camera.html#setPreviewCallbackWithBuffer(android.hardware.Camera.PreviewCallback)
I had this problem with my app (ScareApp) that uses the front facing camera to record video. I "think" I've finally resolved the issue, so thought I would post it here for any developers that run into the same thing....
Basically..
The android MediaRecorder allows you to define the Video and Audio Encoder, and according to the docs, DEFAULT can be used for each.
However, this refers to the main camera's settings, which is often a far higher spec than the front facing camera.
DEFAULT on the Droid Razr for example, selects an encoding (MPEG_4_SP) that isn't available for the Front facing camera, and this results in an empty (0kb) file being produced (or on some other devices a Camera 100 - start failed error).
My other option was to use the CameraProfile.get method to lookup what the HIGH_QUALITY settings, but again, this by default uses the main camera.
To get around this, you can set the ID of the front facing camera by using
CameraProfile.get(<CameraID>, CamcorderProfile.QUALITY_HIGH);
My current work around is as follows:
CamcorderProfile profile = CamcorderProfile.get(FrontFacingCameraId, CamcorderProfile.QUALITY_HIGH);
if(profile != null) {
_recorder.setAudioEncoder(profile.audioCodec);
_recorder.setVideoEncoder(profile.videoCodec);
}else {
//default to basic H263 and AMR_NB if profile not found
_recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
_recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
}
Or alternatively, you can skip setting the Encoders, and just use
_recorder.setProfile(profile);
But as my app allows the user to select the resolution, I need to set the encoder's.
Hopefully this will help someone and save the time and hassle it has caused me!
Cheers,
Mark
I am working on an app that will allow a user to take quick click and forget snapshots. Most of the app is done except for the camera working that way I would like. Right now I have the camera working but I can't seem to find a way to disable the shutter sound and I cant find a way to disable displaying the preview. I was able to cover the preview up with a control but I would rather just not have it displayed if possible.
To sum things up, these are the items that I would like to disable while utilizing the built in Camera controls.
Shutter sound
Camera screen display
Image preview onPictureTaken
Does anyone know of a resource that could point me in the right direction, I would greatly appreciate it. I have been following CommonsWare's example from this sample fairly closely.
Thank you.
This is actually a property in the build.prop of a phone. I'm unsure if its possible to change this. Unless you completely override it and use your own camera code. Using what you can that is available in the SDK.
Take a look at this:
CameraService.cpp
. . .
CameraService::Client::Client(const sp<CameraService>& cameraService,
const sp<ICameraClient>& cameraClient,
const sp<CameraHardwareInterface>& hardware,
int cameraId, int cameraFacing, int clientPid) {
mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
mOrientation = getOrientation(0, mCameraFacing == CAMERA_FACING_FRONT);
mOrientationChanged = false;
cameraService->setCameraBusy(cameraId);
cameraService->loadSound();
LOG1("Client::Client X (pid %d)", callingPid)
}
void CameraService::loadSound() {
Mutex::Autolock lock(mSoundLock);
LOG1("CameraService::loadSound ref=%d", mSoundRef);
if (mSoundRef++) return;
mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
}
As can be noted, the click sound is started without your interaction.
This is the service used in the Gingerbread Source code.
The reason they DON'T allow this is because it is illegal is some countries. Only way to achieve what you want is to have a custom ROM.
Update
If what being said here: http://androidforums.com/t-mobile-g1/6371-camera-shutter-sound-effect-off.html
still applies, then you could write a timer that turns off the sound (Silent Mode) for a couple of seconds and then turn it back on each time you take a picture.
You may use the data from the preview callback using a function to save it at a picture on some type of trigger such as a button, using onclick listener. you could compress the image to jpeg or png. In this way, there no shutterCallback to be implemented. and therefore you can play any sound you want or none when taking a picture.
You can effectively hide the preview surface by giving it dimensions of 1p in the xml file (I found an example the said 0p but for some reason that was giving me errors).
It may be illegal to have a silent shutter in some places, but it doesn't appear that the US is such a place, as my HTC One gives me an option to silence it, and in fact, since Android 4.2 you can do this:
Camera.CameraInfo info=new Camera.CameraInfo();
if (info.canDisableShutterSound) {
camera.enableShutterSound(false);
}