2

Using Android Camera2, I want to use a region to ignore the top 25% of the image when computing the exposure. I'm using this:

// Compute the metering rectangle to ignore the top 25% of the picture:
Rect newRect = new Rect(mActiveArraySize.left, (int) (mActiveArraySize.height() * 0.25), mActiveArraySize.right, mActiveArraySize.bottom);
MeteringRectangle meteringRectangle = new MeteringRectangle(newRect, 1);
MeteringRectangle[] meteringRectangleArr = { meteringRectangle };

// Set the metering rectangle:
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_REGIONS, meteringRectangleArr);

// Set the request:
try { mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), null, mBackgroundHandler); }
catch (CameraAccessException e) { e.printStackTrace(); }

And it's working on my Nexus 5X. But on a Samsung Galaxy Note 5 (and, I guess, on all Samsung devices), it doesn't work, my area is ignored.

I saw this question: Android Camera2 API - Set AE-regions not working, with the op saying that he managed to get it working by using the Samsung SDK. I'd really prefer to avoid that.

Does someone managed to get the AE regions working with Samsung devices?

Tim Autin
  • 6,043
  • 5
  • 46
  • 76
  • I have the same problem. Tried it on 3 phones including LG Nexus 5 with no luck :( By the way, did you set any of CONTROL_AE_PRECAPTURE_TRIGGER, CONTROL_AE_MODE, CONTROL_AE_LOCK parameters? – Mikhail Aug 28 '17 at 16:07

1 Answers1

0

Recently I had the same problem and finally found a solution that helped me.

All I needed to do was to step 1 pixel from the edges of the active sensor rectangle. In your example, instead of this rectangle:

Rect newRect = new Rect(mActiveArraySize.left,
                        (int) (mActiveArraySize.height() * 0.25),
                        mActiveArraySize.right,
                        mActiveArraySize.bottom);

I would use this:

Rect newRect = new Rect(mActiveArraySize.left + 1,
                        (int)(mActiveArraySize.height() * 0.25),
                        mActiveArraySize.right + 1,
                        mActiveArraySize.bottom - 2);

I subtracted 2 from the bottom because the botommost pixel of the active array is mActiveArraySize.height() - 1, and I need to subtract one more pixel.

It seems that many vendors have poorly implemented this part of documentation

If the metering region is outside the used android.scaler.cropRegion returned in capture result metadata, the camera device will ignore the sections outside the crop region and output only the intersection rectangle as the metering region in the result metadata. If the region is entirely outside the crop region, it will be ignored and not reported in the result metadata.

Mikhail
  • 844
  • 8
  • 18
  • Thanks a lot, I'll try that and accept your answer if it works for me! You may have saved me weeks of work implementing Samsung's SDK... – Tim Autin Sep 12 '17 at 06:32
  • So, I finally got the time to try your solution, with no luck. On the Samsung Galaxy Note 5, the active array size is [0,0][5328,3000]. If I use a metering region of [1,1000][5326,1500], it doesn't work (it has no effect, exposure is still computed from the whole screen). Could you give me the active array size & metering region you managed to get working on a Samsung device? – Tim Autin Jun 07 '18 at 13:14
  • @TimAutin On Samsung A7 the sensor rectangle which I get from camera characteristics is: Rect(0, 0 - 4624, 3466). Then I crop it to align aspect ratio with the visible preview area, which gives: Rect(0, 508 - 4624, 2957). Then I use exposure metering region Rect(1, 1120 - 4623, 2549) (I need to cut parts of the image from the top and bottom due to specific of my app). It seems to work for me. – Mikhail Jun 22 '18 at 09:14