我需要一种方法来控制Android设备上的摄像头闪光灯,同时录制视频.我正在制作一个闪光灯应用程序,并使用闪烁的频闪灯拍摄视频将导致能够记录高速移动的物体,如风扇叶片.
只能通过启动视频预览并在摄像机参数中设置FLASH_MODE_TORCH来启用闪光灯.这看起来像这样:
Camera c = Camera.open();
Camera.Parameters p = c.getParameters();
p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
c.setParameters(p);
c.startPreview();
Run Code Online (Sandbox Code Playgroud)
预览开始后,我可以来回翻转该参数以打开和关闭灯光.这很有效,直到我尝试录制视频.麻烦的是,为了将相机送到MediaRecorder,我首先必须解锁它.
MediaRecorder m = new MediaRecorder();
c.unlock(); // the killer
m.setCamera(c);
Run Code Online (Sandbox Code Playgroud)
解锁后,我无法再更改摄像机参数,因此无法更改闪光灯状态.
我不知道是否真的可以这样做,因为我不是最好的java-hacking,但这是我所知道的:
所以,我仍然可以访问相机,但它不会听我说的任何东西.(这是Camera.unlock()的目的)
编辑:
检查本机代码后,我可以看到在CameraService.cpp中,我对Camera.setParameters(Parameters)的调用被拒绝,因为我的进程ID与摄像头服务记录的进程ID不匹配.所以这似乎是我的障碍.
EDIT2:
看起来MediaPlayerService是在录制视频时控制摄像机的主要服务.我不知道是否可能,但如果我能以某种方式在我自己的进程中启动该服务,我应该能够跳过Camera.unlock()调用.
EDIT3:
最后一个选择是,如果我能以某种方式获得指向CameraHardwareInterface的指针.从它的外观来看,这是一个特定于设备的接口,可能不包括PID检查.这个问题的主要问题是我能找到指针的唯一地方是在CameraService中,CameraService没有说话.
编辑4 :(几个月后)
在这一点上,我认为不可能做我原本想要的.我不想删除有人确实回答的问题,但我并没有积极寻求答案.(虽然,收到有效答案会很棒.)
如何将返回的Bitmap转换BitmapFactory.decodeFile()为YUV格式(simillar到相机的onPreviewFrame()返回字节数组)?
我正在开发一个Android应用程序,部分应用程序必须拍照并将它们保存到SD卡.onPictureTaken方法返回一个包含捕获图像数据的字节数组.
我需要做的就是将字节数组保存到.jpeg图像文件中.我试图在BitmapFactory.decodeByteArray(获取Bitmap)和bImage.compress(到OutputStream),普通OutputStream和BufferedOutputStream的帮助下完成此操作.所有这三种方法似乎都给了我同样奇怪的错误.我的Android手机(800万像素摄像头和一个体面的处理器),似乎保存照片(大小看起来正确),但以一种损坏的方式(图像被切片,每个切片被移动;或者我只是得到几乎各种颜色的水平线) ; 奇怪的是,带有500万像素摄像头和快速处理器的Android平板电脑似乎可以正确保存图像.
所以我想也许处理器无法跟上保存大图像,因为我在大约3张图片后得到了OutOfMemory Exceptions(即使压缩质量为40).但那么内置的相机应用程序是如何做到的,而且速度也快得多?我很确定(从调试)OutputStream写入所有数据(字节),它应该没问题,但它仍然被破坏.
***简而言之,将字节数组保存到jpeg文件的最佳/最快方式(可行)是什么?
马克,先谢谢你
我试过的代码(以及其他一些细微的变化):
try {
Bitmap image = BitmapFactory.decodeByteArray(args, 0, args.length);
OutputStream fOut = new FileOutputStream(externalStorageFile);
long time = System.currentTimeMillis();
image.compress(Bitmap.CompressFormat.JPEG,
jpegQuality, fOut);
System.out.println(System.currentTimeMillis() - time);
fOut.flush();
fOut.close();
} catch (Exception e) {
}
Run Code Online (Sandbox Code Playgroud)
和
try {
externalStorageFile.createNewFile();
FileOutputStream fos = new FileOutputStream(externalStorageFile);
fos.write(args);
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud) 我试图允许用户录制与录制时可以看到的实际屏幕预览不同的视频.这似乎可以从这个有关getSupportedVideoSizes功能的文档中说明:
如果返回的列表不为null,则返回的列表将包含至少一个Size,如果将摄像机用作视频源,则返回列表中的一个大小必须传递给MediaRecorder.setVideoSize()以用于摄像机应用程序.在这种情况下,预览的大小可以与视频记录期间记录的视频的分辨率不同.
这表明某些手机将从此fn返回null(根据我的经验,Galaxy SIII会这样做),但对于那些不这样做的手机,可以提供与实际视频不同的分辨率的预览.这种理解是否正确?有些手机允许这种行为吗?
尝试解决方案:
在功能的官方描述中setPreviewDisplay,用于设置视频录制的漫长过程中,提到:
如果使用null surface调用此方法或根本不调用此方法,则介质记录器将不会更改摄像机的预览表面.
这似乎是我想要的,但不幸的是,如果我这样做,整个视频录制过程完全搞砸了.我假设在录制视频的过程中,此函数不能传递null或根本不调用.也许在其他情况下这是可以的.不幸的是,这似乎对我没有帮助.
我唯一接下来的步骤是查看TextureViews并使用预览纹理而不是典型的SurfaceView实现,以便使用openGL将纹理拉伸到我想要的大小(与实际分辨率不同)(并裁剪屏幕上的任何多余部分) ,然后使用Surface setPreviewDisplay的Surface(SurfaceTexture surfaceTexture)构造函数为该函数构造一个Surface.我想避免使用TextureViewICS下面的不兼容性,也因为这会增加显着的复杂性.
这似乎是一个微妙的过程,但我希望有人可以在这方面提供一些建议.
谢谢.
我正在使用纹理视图在我的Android应用程序中显示相机的预览.然而,我注意到,每次我的应用程序暂停时,我都会收到此错误:
03-18 18:23:44.315: W/BufferQueue(19582): [unnamed-19582-20] cancelBuffer: BufferQueue has been abandoned!
Run Code Online (Sandbox Code Playgroud)
谁能告诉我这里发生了什么?当我的应用程序暂停时,我所做的就是从这里取消所有这些内容onSurfaceTextureDestroyed()
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mCamera.release();
return true;
}
Run Code Online (Sandbox Code Playgroud) 在服务中使用相机时,移动屏幕变得不可触摸(由透明窗口锁定)并且仅在出现错误之下
Access denied finding property "camera.hal1.packagelist"
Run Code Online (Sandbox Code Playgroud)
将是什么原因及其解决方案?请帮忙..
我正在开发一款具有自定义相机屏幕的应用程序,我应该实现自拍对焦,就像Android(更具体地说,Galaxy S4)相机应用程序一样.
我已尝试使用此处列出的步骤,但似乎没有引起任何明显的聚焦.对焦模式设置为连续图片(我们仅支持特定设备).
当用户点击相机预览时,我需要关注图像的上半部分.为此,我使用代码片段
Parameters parameters = mCamera.getParameters();
if (parameters.getMaxNumFocusAreas() > 0) {
ArrayList<Area> focusAreas = new ArrayList<Camera.Area>(1);
focusAreas.add(new Area(new Rect(-1000, -1000, 1000, 0), 750));
parameters.setFocusAreas(focusAreas);
mCamera.setParameters(parameters);
}
Run Code Online (Sandbox Code Playgroud)
我不想要自动聚焦,因为聚焦图像需要很长时间.我只对图像的上半部分感兴趣.有没有人成功实现Tap to Focus和连续图片模式?
我想使用android camera api以低分辨率捕获图像,但是当我捕获图像时,它将采用设备相机的默认分辨率.所以我想在捕获时捕获低分辨率或小尺寸的图像,或者如何将大图像压缩成android中的小尺寸?
android image-compression android-camera android-camera-intent
如果我只使用CAMERA_FACING_BACK或CAMERA_FACING_FRONT所有工作正常.
切换CAMERA_FACING_BACK到时我遇到了麻烦CAMERA_FACING_FRONT.
我的代码片段:
public class PhotoCameraActivity extends Activity implements OnClickListener {
private SurfaceView cameraView;
private Button turnButton;
private Camera camera = null;
private Callback listener;
private static int camId = Camera.CameraInfo.CAMERA_FACING_BACK;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.photo_camera_main);
prepareActivity();
}
private void prepareActivity() {
cameraView = (SurfaceView) findViewById(R.id.photo_camera_surface_view);
turnButton = (ImageButton) findViewById(R.id.turn_button);
turnButton.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (v.equals(turnButton)) {
if (Camera.getNumberOfCameras() > 1 && camId < Camera.getNumberOfCameras() …Run Code Online (Sandbox Code Playgroud) 我希望这不是一个重复的问题,但我正在制作一个应用程序,我想要一个按钮打开相机应用程序(单独的默认Android相机).我怎么做到这一点?我知道有一个功能:
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE)
Run Code Online (Sandbox Code Playgroud)
我需要使用它吗?如何从xml文件中调用该按钮?
此外,我是否需要担心存储该图片或视频,或者默认的相机应用程序会处理这个问题?
android ×10
android-camera ×10
bytearray ×1
c++ ×1
camera ×1
java ×1
jpeg ×1
process ×1
surfaceview ×1
textureview ×1
yuv ×1