新的camera2 API让我很困惑.我想开发一个使用该设备相机的应用程序(适用于Android API 10 - 21).如前所述这里,我应该使用"相机" API.
但是,当我尝试将"Camera"API (android.hardware.Camera)添加到清单的用户功能时,它被标记为已弃用.另一方面,我无法将其更改为"camera2"API (android.hardware.camera2),因为它只与Android API 21+(Android 5 - Lollipop)兼容 - 也会链接它,但我只能添加2个链接.
我不仅希望我的应用程序在旧版本的Android上运行,而且还需要最新版本的...
我有一个执行图像分析的Android应用程序,该应用程序通过以下方式管理IntentService- 该过程每次都需要几秒钟,并且准确,快速地工作.
但是当应用程序在应用程序中重复大约50次时(如图所示),它开始变得非常缓慢,直到应用程序和设备变得无法使用.当设备重新启动并且应用程序再次打开时,它会照常运行.
使用Android Studio进行检查我可以看到,每次运行分析时,应用程序的内存分配每次都会上升大约1MB.因此崩溃时显然内存不足.
我已经使用此标志完成分析并转到结果以尝试修复后台活动;
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
Run Code Online (Sandbox Code Playgroud)
效果极小,我理解IntentService管理自己关闭.所以不知道我还能做些什么来尝试减少内存分配或者至少清除分配并停止添加它?
更多详情:
这是2017年,我终于开始从Camera1切换到Camera2.在Camera1中,我非常依赖于setPreviewCallbackWithBuffer()执行实时帧处理,但是在Camera2中,它的工作速度要慢得多,几乎无法使用.
相比之下,在Moto G3上Camera1可以很容易地产生30-40 FPS而在Camera2上我的速度不能超过10-15 FPS.
这就是我的创作方式 ImageReader
imageReader = ImageReader
.newInstance(
previewSize.width, // size is around 1280x720
previewSize.height,
ImageFormat.YUV_420_888, // note, it is not JPEG
2 // max number of images, does not really affect performance
);
imageReader.setOnImageAvailableListener(
callback,
CameraThread.getInstance().createHandler()
);
Run Code Online (Sandbox Code Playgroud)
回调本身可以完成最小的工作:
Image image = reader.acquireNextImage();
image.close();
Run Code Online (Sandbox Code Playgroud)
我已经检查了类似的答案,比如这个.然而他们的问题是他们使用的是JPEG图像格式而不是YUV_420_888.
如何实现类似于Camera1的性能?
在服务中使用相机时,移动屏幕变得不可触摸(由透明窗口锁定)并且仅在出现错误之下
Access denied finding property "camera.hal1.packagelist"
Run Code Online (Sandbox Code Playgroud)
将是什么原因及其解决方案?请帮忙..
我写了一个从YUV_420_888到Bitmap的转换,考虑到以下逻辑(据我所知):
总结该方法:内核的坐标x和y与Y平面(2d分配)的非填充部分的x和y以及输出位图的x和y都是一致的.然而,U平面和V平面具有与Y平面不同的结构,因为它们使用1个字节覆盖4个像素,此外,可能具有多于一个的PixelStride,此外它们可能也有一个可以与Y平面不同的填充.因此,为了通过内核有效地访问U和V,我将它们放入1-d分配并创建索引"uvIndex",该索引给出了在给定的1-d分配中相应的U-和V的位置( x,y)坐标(非填充)Y平面(以及输出位图).
为了保持rs-Kernel的精简,我通过LaunchOptions限制x范围来排除yPlane中的填充区域(这反映了y平面的RowStride,因此可以在内核中忽略).所以我们只需要考虑uvIndex中的uvPixelStride和uvRowStride,即用于访问u值和v值的索引.
这是我的代码:
Renderscript内核,名为yuv420888.rs
#pragma version(1)
#pragma rs java_package_name(com.xxxyyy.testcamera2);
#pragma rs_fp_relaxed
int32_t width;
int32_t height;
uint picWidth, uvPixelStride, uvRowStride ;
rs_allocation ypsIn,uIn,vIn;
// The LaunchOptions ensure that the Kernel does not enter the padding zone of Y, so yRowStride can be ignored WITHIN the Kernel.
uchar4 __attribute__((kernel)) doConvert(uint32_t x, uint32_t y) {
// index for accessing the uIn's and vIn's
uint uvIndex= uvPixelStride * (x/2) + uvRowStride*(y/2);
// get the y,u,v values
uchar yps= rsGetElementAt_uchar(ypsIn, x, y);
uchar …Run Code Online (Sandbox Code Playgroud) 新API,也许只在LG G3上,似乎有些变化.
我正在使用示例代码.
在我的nexus 4上,代码运行完美,但在LGG3上更新到Android 6.0却没有.有任何想法吗?
我玩设置,但没有运气,这仍然适用于Nexus 4:
mPreviewRequestBuilder.set(CaptureRequest.BLACK_LEVEL_LOCK, false);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AWB_LOCK, false);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_AUTO);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, false);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_ANTIBANDING_MODE, CaptureRequest.CONTROL_AE_ANTIBANDING_MODE_AUTO);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 0);
//mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, Range.create(1000,1000));
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, 0);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
mPreviewRequestBuilder.set(CaptureRequest.COLOR_CORRECTION_MODE, CaptureRequest.CONTROL_MODE_AUTO);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT,
CaptureRequest.CONTROL_CAPTURE_INTENT_PREVIEW);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
Run Code Online (Sandbox Code Playgroud) 在尝试使用Android Camera2实现触控聚焦功能时,我遇到了一个问题.
理论很简单:
MeteringRectangle出来的结果,并在一个新的使用CaptureRequest有很多例子展示了如何处理第一点和最后一点,但没有多少以可理解的方式处理第二点和第三点.文档和示例并不是很清楚,可能会让人感到困惑.
开始了...
该CameraCharacteristics.SENSOR_ORIENTATIONIS形容为
顺时针角度,输出图像需要通过该角度以原始方向旋转到设备屏幕上.
知道传感器坐标系定义为(0,0)是有源像素阵列中的左上角像素,我将其读作将传感器坐标系中捕获的图像旋转到可能产生的位置所需的角度图像在原始方向上看起来很直立.因此,如果传感器的顶部朝向具有纵向原始方向的手机的右侧,SENSOR_ORIENTATION则将为90°.

获得的显示方向mActivity.getWindowManager().getDefaultDisplay().getRotation();记录为:
返回屏幕从"自然"方向的旋转.返回的值可能是Surface.ROTATION_0(无旋转),Surface.ROTATION_90,Surface.ROTATION_180或Surface.ROTATION_270.例如,如果设备具有自然高的屏幕,并且用户将其侧面转向横向,则此处返回的值可以是Surface.ROTATION_90或Surface.ROTATION_270,具体取决于它的转向.角度是屏幕上绘制图形的旋转,这是设备物理旋转的相反方向.例如,如果设备逆时针旋转90度,则补偿渲染将顺时针旋转90度,因此返回的值将为Surface.ROTATION_90.
我发现这个定义比传感器定位更清晰,没有解释的地方.
现在事情开始变得难看......
我决定使用Camera2Raw示例中提供的方法来获取从传感器方向到设备方向的旋转.
/**
* Rotation need to transform from the camera sensor orientation to the device's current
* orientation.
*
* @param c the {@link CameraCharacteristics} to query for the camera sensor
* orientation.
* @param deviceOrientation the current device orientation relative to the native device
* orientation.
* @return the …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用Android相机,对于API 23或更高版本,它需要在运行时请求权限.根据文档,我可以使用ActivityCompat或ContextCompat来实现.我不明白这两者之间有什么区别和他们的权衡.
谢谢你的时间.
android android-camera android-camera-intent android-camera2
我目前正在使用Javacv,它利用public void onPreviewFrame(byte[] data, Camera camera)相机功能.
由于相机已被弃用,我一直在研究camera2和MediaProjection.这两个库都使用ImageReader类.
目前我ImageReader使用以下代码实例化这样的:
ImageReader.newInstance(DISPLAY_WIDTH, DISPLAY_HEIGHT, PixelFormat.RGBA_8888, 2);
并附上OnImageAvailableListener这样的:
private final ImageReader.OnImageAvailableListener mOnImageAvailableListener
= new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
mBackgroundHandler.post(new processImage(reader.acquireNextImage()));
}
Run Code Online (Sandbox Code Playgroud)
我尝试使用RGBA_8888Javacv 的格式按照这个帖子:https://github.com/bytedeco/javacv/issues/298但这对我不起作用.
所以我正在考虑使用Render脚本将这些Image转换为NV21(YUV_420_SP)格式(这是onPreviewFrame函数中相机的默认输出),因为这对我来说对camera库有用.
我还阅读了这个和本网站的帖子进行转换,但这些对我不起作用,我担心它们会太慢.此外,我对C的了解非常有限.基本上看起来我想要https://developer.android.com/reference/android/renderscript/ScriptIntrinsicYuvToRGB.html的反向操作
那么你怎么能从一个Image匹配onPreviewFrame函数输出的字节数组,即NV21(YUV_420_SP)格式?最好使用Renderscript,因为它更快.
我尝试过使用ImageFormat.YUV_420_888 …
camera android image-processing renderscript android-camera2
我在我的应用程序中使用android camera2拍摄连续图像,这时我使用camera2获得的图像预览亮度与原始相机相比非常暗.我看到了这个,但答案中没有类似的要求.
我试图设置camera2亮度的建议在这里:
请注意,此控件仅在android.control.aeMode!= OFF时有效.即使android.control.aeLock == true,此控件也会生效.
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
captureRequestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, true);
captureRequestBuilder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 6);
Run Code Online (Sandbox Code Playgroud)
但它仍然显示预览为暗图像,如下所示.
看到这里的区别:
我需要传递的值是什么,作为第二个参数:
captureRequestBuilder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 6);
Run Code Online (Sandbox Code Playgroud)
我保持6,因为正如doc的建议:
例如,如果曝光值(EV)步长为0.333,则"6"表示+2 EV的曝光补偿; -3意味着-1 EV的曝光补偿.
但亮度仍然没有影响..