- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这是一个尚未解答的问题,因为我已经浏览了 SO 中的所有问题。
...等等,但真正的问题是,我有一个完美工作的双摄像头,在多个设备上进行了测试,例如:Google Pixel XL、LETV 1S、Elephone S7、LG 设备,几乎大多数设备都有两个图像信号处理器,但三星设备除外,测试时仅显示 1 个相机预览。
到目前为止,我已经尝试使用 OpenGL、已弃用的相机 API、Camera2 API 以及最后的三星相机 Api 打开两个相机,但结果仍然相同。
下面是三星 API CameraPreview
public class SCamera {
private SCamera mSCamera;
private SCameraManager mSCameraManager;
private SCameraDevice mSCameraDevice;
private SCameraCaptureSession mSCameraSession;
private SCameraCharacteristics mCharacteristics;
private SCaptureRequest.Builder mPreviewBuilder;
/**
* Current Preview Size.
*/
private Size mPreviewSize;
/**
* Current Picture Size.
*/
private Size mPictureSize;
/**
* ID of the current {@link com.samsung.android.sdk.camera.SCameraDevice}.
*/
private String mCameraId;
/**
* for camera preview.
*/
private TextureView mTextureView;
/**
* A camera related listener/callback will be posted in this handler.
*/
private Handler mBackgroundHandler;
private HandlerThread mBackgroundHandlerThread;
/**
* A image saving worker Runnable will be posted to this handler.
*/
private HandlerThread mImageSavingHandlerThread;
/**
* An orientation listener for jpeg orientation
*/
private int mLastOrientation = 0;
private Semaphore mCameraOpenCloseLock = new Semaphore(1);
/**
* Lens facing. Camera with this facing will be opened
*/
private int mLensFacing;
private List<Integer> mLensFacingList;
private Activity context;
public SamsungApiManager(Activity context, TextureView textureView, int cameraId) {
this.context = context;
this.mTextureView = textureView;
startBackgroundThread();
// initialize SCamera
mSCamera = new SCamera();
try {
mSCamera.initialize(context);
} catch (SsdkUnsupportedException e) {
e.printStackTrace();
return;
}
createUI();
checkRequiredFeatures(cameraId);
openCamera(mLensFacing);
}
private void checkRequiredFeatures(int cameraId) {
try {
// Find available lens facing value for this device
Set<Integer> lensFacings = new HashSet<>();
for (String id : mSCamera.getSCameraManager().getCameraIdList()) {
SCameraCharacteristics cameraCharacteristics =
mSCamera.getSCameraManager().getCameraCharacteristics(id);
lensFacings.add(cameraCharacteristics.get(SCameraCharacteristics.LENS_FACING));
}
mLensFacingList = new ArrayList<>(lensFacings);
mLensFacing = mLensFacingList.get(cameraId);
setDefaultJpegSize(mSCamera.getSCameraManager(), mLensFacing);
} catch (CameraAccessException e) {
e.printStackTrace();
Log.e("Camera", "Cannot access the camera.", e);
}
}
/**
* Starts back ground thread that callback from camera will posted.
*/
private void startBackgroundThread() {
mBackgroundHandlerThread = new HandlerThread("Background Thread");
mBackgroundHandlerThread.start();
mBackgroundHandler = new Handler(mBackgroundHandlerThread.getLooper());
mImageSavingHandlerThread = new HandlerThread("Saving Thread");
mImageSavingHandlerThread.start();
}
/**
* Starts a preview.
*/
synchronized private void startPreview() {
if (mSCameraSession == null) return;
try {
// Starts displaying the preview.
mSCameraSession.setRepeatingRequest(mPreviewBuilder.build(), null, mBackgroundHandler);
} catch (CameraAccessException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
}
/**
* Stops back ground thread.
*/
private void stopBackgroundThread() {
if (mBackgroundHandlerThread != null) {
mBackgroundHandlerThread.quitSafely();
try {
mBackgroundHandlerThread.join();
mBackgroundHandlerThread = null;
mBackgroundHandler = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (mImageSavingHandlerThread != null) {
mImageSavingHandlerThread.quitSafely();
try {
mImageSavingHandlerThread.join();
mImageSavingHandlerThread = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void setDefaultJpegSize(SCameraManager manager, int facing) {
try {
for (String id : manager.getCameraIdList()) {
SCameraCharacteristics cameraCharacteristics = manager.getCameraCharacteristics(id);
if (cameraCharacteristics.get(SCameraCharacteristics.LENS_FACING) == facing) {
List<Size> jpegSizeList = new ArrayList<>();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& cameraCharacteristics.get(SCameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
.getHighResolutionOutputSizes(ImageFormat.JPEG) != null) {
jpegSizeList.addAll(Arrays.asList(
cameraCharacteristics.get(SCameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
.getHighResolutionOutputSizes(ImageFormat.JPEG)));
}
jpegSizeList.addAll(Arrays.asList(
cameraCharacteristics.get(SCameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
.getOutputSizes(ImageFormat.JPEG)));
mPictureSize = jpegSizeList.get(0);
}
}
} catch (CameraAccessException e) {
Log.e("Camera", "Cannot access the camera.", e);
}
}
/**
* Opens a {@link com.samsung.android.sdk.camera.SCameraDevice}.
*/
synchronized public void openCamera(int facing) {
try {
if (!mCameraOpenCloseLock.tryAcquire(3000, TimeUnit.MILLISECONDS)) {
Log.e("Error", "time out");
}
mSCameraManager = mSCamera.getSCameraManager();
mCameraId = null;
// Find camera device that facing to given facing parameter.
for (String id : mSCamera.getSCameraManager().getCameraIdList()) {
SCameraCharacteristics cameraCharacteristics =
mSCamera.getSCameraManager().getCameraCharacteristics(id);
if (cameraCharacteristics.get(SCameraCharacteristics.LENS_FACING) == facing) {
mCameraId = id;
break;
}
}
if (mCameraId == null) {
Log.e("Error", "no id found");
return;
}
// acquires camera characteristics
mCharacteristics = mSCamera.getSCameraManager().getCameraCharacteristics(mCameraId);
StreamConfigurationMap streamConfigurationMap =
mCharacteristics.get(SCameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
// Acquires supported preview size list that supports SurfaceTexture
mPreviewSize =
getOptimalPreviewSize(streamConfigurationMap.getOutputSizes(SurfaceTexture.class),
(double) mPictureSize.getWidth() / mPictureSize.getHeight());
Log.d("Camera",
"Picture Size: " + mPictureSize.toString() + " Preview Size: " + mPreviewSize.toString());
if (contains(mCharacteristics.get(SCameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES),
SCameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
List<Size> rawSizeList = new ArrayList<>();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& streamConfigurationMap.getHighResolutionOutputSizes(ImageFormat.RAW_SENSOR)
!= null) {
rawSizeList.addAll(Arrays.asList(
streamConfigurationMap.getHighResolutionOutputSizes(ImageFormat.RAW_SENSOR)));
}
rawSizeList.addAll(
Arrays.asList(streamConfigurationMap.getOutputSizes(ImageFormat.RAW_SENSOR)));
}
// Opening the camera device here
mSCameraManager.openCamera(mCameraId, new SCameraDevice.StateCallback() {
@Override
public void onDisconnected(SCameraDevice sCameraDevice) {
mCameraOpenCloseLock.release();
}
@Override
public void onError(SCameraDevice sCameraDevice, int i) {
mCameraOpenCloseLock.release();
}
public void onOpened(SCameraDevice sCameraDevice) {
mCameraOpenCloseLock.release();
mSCameraDevice = sCameraDevice;
createPreviewSession();
}
}, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
Log.e("Camera", "Cannot open the camera.", e);
} catch (InterruptedException e) {
throw new RuntimeException("Interrupted while trying to lock camera opening.", e);
}
}
/**
* Closes a camera and release resources.
*/
synchronized private void closeCamera() {
try {
mCameraOpenCloseLock.acquire();
if (mSCameraSession != null) {
mSCameraSession.close();
mSCameraSession = null;
}
if (mSCameraDevice != null) {
mSCameraDevice.close();
mSCameraDevice = null;
}
mSCameraManager = null;
} catch (InterruptedException e) {
Log.e("Camera", "Interrupted while trying to lock camera closing.", e);
} finally {
mCameraOpenCloseLock.release();
}
}
/**
* Configures requires transform {@link android.graphics.Matrix} to TextureView.
*/
private void configureTransform(int viewWidth, int viewHeight) {
if (null == mTextureView || null == mPreviewSize) {
return;
}
int rotation = context.getWindowManager().getDefaultDisplay().getRotation();
Matrix matrix = new Matrix();
RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
RectF bufferRect = new RectF(0, 0, mPreviewSize.getHeight(), mPreviewSize.getWidth());
float centerX = viewRect.centerX();
float centerY = viewRect.centerY();
if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
float scale = Math.max((float) viewHeight / mPreviewSize.getHeight(),
(float) viewWidth / mPreviewSize.getWidth());
matrix.postScale(scale, scale, centerX, centerY);
matrix.postRotate(90 * (rotation - 2), centerX, centerY);
} else {
matrix.postRotate(90 * rotation, centerX, centerY);
}
mTextureView.setTransform(matrix);
mTextureView.getSurfaceTexture()
.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
}
private boolean contains(final int[] array, final int key) {
for (final int i : array) {
if (i == key) {
return true;
}
}
return false;
}
/**
* Create a {@link com.samsung.android.sdk.camera.SCameraCaptureSession} for preview.
*/
synchronized private void createPreviewSession() {
if (null == mSCamera
|| null == mSCameraDevice
|| null == mSCameraManager
|| null == mPreviewSize
|| !mTextureView.isAvailable()) {
return;
}
try {
SurfaceTexture texture = mTextureView.getSurfaceTexture();
// Set default buffer size to camera preview size.
texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
Surface surface = new Surface(texture);
// Creates SCaptureRequest.Builder for preview with output target.
mPreviewBuilder = mSCameraDevice.createCaptureRequest(SCameraDevice.TEMPLATE_PREVIEW);
mPreviewBuilder.addTarget(surface);
// Creates SCaptureRequest.Builder for still capture with output target.
//mCaptureBuilder = mSCameraDevice.createCaptureRequest(SCameraDevice.TEMPLATE_STILL_CAPTURE);
// Creates a SCameraCaptureSession here.
List<Surface> outputSurface = new ArrayList<Surface>();
outputSurface.add(surface);
//outputSurface.add(mJpegReader.getSurface());
mSCameraDevice.createCaptureSession(outputSurface, new SCameraCaptureSession.StateCallback() {
@Override
public void onConfigureFailed(SCameraCaptureSession sCameraCaptureSession) {
}
@Override
public void onConfigured(SCameraCaptureSession sCameraCaptureSession) {
mSCameraSession = sCameraCaptureSession;
startPreview();
}
}, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
/**
* Prepares an UI, like button, dialog, etc.
*/
private void createUI() {
// Set SurfaceTextureListener that handle life cycle of TextureView
mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
// "onSurfaceTextureAvailable" is called, which means that SCameraCaptureSession is not created.
// We need to configure transform for TextureView and crate SCameraCaptureSession.
configureTransform(width, height);
createPreviewSession();
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return true;
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
// SurfaceTexture size changed, we need to configure transform for TextureView, again.
configureTransform(width, height);
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
});
}
/**
* Returns required orientation that the jpeg picture needs to be rotated to be displayed upright.
*/
private int getJpegOrientation() {
int degrees = mLastOrientation;
if (mCharacteristics.get(SCameraCharacteristics.LENS_FACING)
== SCameraCharacteristics.LENS_FACING_FRONT) {
degrees = -degrees;
}
return (mCharacteristics.get(SCameraCharacteristics.SENSOR_ORIENTATION) + degrees + 360) % 360;
}
/**
* find optimal preview size for given targetRatio
*/
private Size getOptimalPreviewSize(Size[] sizes, double targetRatio) {
final double ASPECT_TOLERANCE = 0.001;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
Display display = context.getWindowManager().getDefaultDisplay();
Point displaySize = new Point();
display.getSize(displaySize);
int targetHeight = Math.min(displaySize.y, displaySize.x);
// Try to find an size match aspect ratio and size
for (Size size : sizes) {
double ratio = (double) size.getWidth() / size.getHeight();
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
if (Math.abs(size.getHeight() - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.getHeight() - targetHeight);
}
}
// Cannot find the one match the aspect ratio. This should not happen.
// Ignore the requirement.
if (optimalSize == null) {
Log.w("Camera", "No preview size match the aspect ratio");
minDiff = Double.MAX_VALUE;
for (Size size : sizes) {
if (Math.abs(size.getHeight() - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.getHeight() - targetHeight);
}
}
}
return optimalSize;
}
}
以下是我如何同时访问两个摄像头:
private void openFrontCam() {
textureFront.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
sCamera =
new SCamera(DualCamera.this, textureFront, 0);
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
});
}
private void openBackCam() {
textureBack.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
sCamera =
new SCamera(DualCamera.this, textureBack, 1);
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
});
}
现在我的理解是,有些人声称他们在三星设备上使用了双摄像头功能 like in this detailed answer ,除非三星已锁定该功能仅供自己使用。
到目前为止,我已经用尽了所有选项,但不知道还可以尝试什么。
谢谢。
最佳答案
我仅在 Samsung Galaxy S8、S8+ 和 Note 8 设备上使用其内部库 SemCamera.jar 和带有 glsl 着色器的 OpenGL 成功解锁了此功能。但它不兼容较旧的三星设备或最新的 S9 设备。在对他们的库存相机应用程序进行逆向工程以查看该功能是否存在之后,我发现它已从他们的代码中完全删除。因此,他们的框架阻止第三方应用程序使用此功能,显然不是出于安全原因。我们希望在不久的将来他们能够在下一个Camera SDK中分享双摄像头功能。
关于java - 如何在三星 Galaxy 设备上同时打开前置和后置摄像头?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47176727/
我正在编写一个具有以下签名的 Java 方法。 void Logger(Method method, Object[] args); 如果一个方法(例如 ABC() )调用此方法 Logger,它应该
我是 Java 新手。 我的问题是我的 Java 程序找不到我试图用作的图像文件一个 JButton。 (目前这段代码什么也没做,因为我只是得到了想要的外观第一的)。这是我的主课 代码: packag
好的,今天我在接受采访,我已经编写 Java 代码多年了。采访中说“Java 垃圾收集是一个棘手的问题,我有几个 friend 一直在努力弄清楚。你在这方面做得怎么样?”。她是想骗我吗?还是我的一生都
我的 friend 给了我一个谜语让我解开。它是这样的: There are 100 people. Each one of them, in his turn, does the following
如果我将使用 Java 5 代码的应用程序编译成字节码,生成的 .class 文件是否能够在 Java 1.4 下运行? 如果后者可以工作并且我正在尝试在我的 Java 1.4 应用程序中使用 Jav
有关于why Java doesn't support unsigned types的问题以及一些关于处理无符号类型的问题。我做了一些搜索,似乎 Scala 也不支持无符号数据类型。限制是Java和S
我只是想知道在一个 java 版本中生成的字节码是否可以在其他 java 版本上运行 最佳答案 通常,字节码无需修改即可在 较新 版本的 Java 上运行。它不会在旧版本上运行,除非您使用特殊参数 (
我有一个关于在命令提示符下执行 java 程序的基本问题。 在某些机器上我们需要指定 -cp 。 (类路径)同时执行java程序 (test为java文件名与.class文件存在于同一目录下) jav
我已经阅读 StackOverflow 有一段时间了,现在我才鼓起勇气提出问题。我今年 20 岁,目前在我的家乡(罗马尼亚克卢日-纳波卡)就读 IT 大学。足以介绍:D。 基本上,我有一家提供簿记应用
我有 public JSONObject parseXML(String xml) { JSONObject jsonObject = XML.toJSONObject(xml); r
我已经在 Java 中实现了带有动态类型的简单解释语言。不幸的是我遇到了以下问题。测试时如下代码: def main() { def ks = Map[[1, 2]].keySet()
一直提示输入 1 到 10 的数字 - 结果应将 st、rd、th 和 nd 添加到数字中。编写一个程序,提示用户输入 1 到 10 之间的任意整数,然后以序数形式显示该整数并附加后缀。 public
我有这个 DownloadFile.java 并按预期下载该文件: import java.io.*; import java.net.URL; public class DownloadFile {
我想在 GUI 上添加延迟。我放置了 2 个 for 循环,然后重新绘制了一个标签,但这 2 个 for 循环一个接一个地执行,并且标签被重新绘制到最后一个。 我能做什么? for(int i=0;
我正在对对象 Student 的列表项进行一些测试,但是我更喜欢在 java 类对象中创建硬编码列表,然后从那里提取数据,而不是连接到数据库并在结果集中选择记录。然而,自从我这样做以来已经很长时间了,
我知道对象创建分为三个部分: 声明 实例化 初始化 classA{} classB extends classA{} classA obj = new classB(1,1); 实例化 它必须使用
我有兴趣使用 GPRS 构建车辆跟踪系统。但是,我有一些问题要问以前做过此操作的人: GPRS 是最好的技术吗?人们意识到任何问题吗? 我计划使用 Java/Java EE - 有更好的技术吗? 如果
我可以通过递归方法反转数组,例如:数组={1,2,3,4,5} 数组结果={5,4,3,2,1}但我的结果是相同的数组,我不知道为什么,请帮助我。 public class Recursion { p
有这样的标准方式吗? 包括 Java源代码-测试代码- Ant 或 Maven联合单元持续集成(可能是巡航控制)ClearCase 版本控制工具部署到应用服务器 最后我希望有一个自动构建和集成环境。
我什至不知道这是否可能,我非常怀疑它是否可能,但如果可以,您能告诉我怎么做吗?我只是想知道如何从打印机打印一些文本。 有什么想法吗? 最佳答案 这里有更简单的事情。 import javax.swin
我是一名优秀的程序员,十分优秀!