android中用Camera来调用摄像头,只能用takePicture来拍照吗

android中用Camera来调用摄像头,只能用takePicture来拍照吗,第1张

android中用Camera来调用摄像头,只能用takePicture来拍照吗?

代码与范例:

首先需要在Manifest文件中添加以下内容:

以使程序获取摄像头使用以及自动对焦功能的使用权限。

CameraTestActivityjava

import androidappActivity;

import androidosBundle;

import androidviewWindow;

import androidviewWindowManager;

public class CameraTestActivity extends Activity {

@Override

public void onCreate(Bundle bundle) {

superonCreate(bundle);

getWindow()clearFlags(WindowManagerLayoutParamsFLAG_FORCE_NOT_FULLSCREEN);

getWindow()addFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN);

requestWindowFeature(WindowFEATURE_NO_TITLE); 设置横屏模式以及全屏模式

setContentView(new CameraView(this)); 设置View

}

}

CameraViewjava

import javaioFileOutputStream;

import androidcontentContext;

import androidhardwareCamera;

import androidosEnvironment;

import androidviewMotionEvent;

import androidviewSurfaceHolder;

import androidviewSurfaceView;

public class CameraView extends SurfaceView implements SurfaceHolderCallback, CameraPictureCallback {

private SurfaceHolder holder;

private Camera camera;

private boolean af;

public CameraView(Context context) {构造函数

super(context);

holder = getHolder();生成Surface Holder

holderaddCallback(this);

holdersetType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS);指定Push Buffer

}

public void surfaceCreated(SurfaceHolder holder) {Surface生成事件的处理

try {

camera = Cameraopen();摄像头的初始化

camerasetPreviewDisplay(holder);

} catch (Exception e) {

}

}

@Override

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {Surface改变事件的处理

CameraParameters parameters = cameragetParameters();

parameterssetPreviewSize(width, height);

camerasetParameters(parameters);设置参数

camerastartPreview();开始预览

}

public void surfaceDestroyed(SurfaceHolder holder) {Surface销毁时的处理

camerasetPreviewCallback(null);

camerasPreview();

camerarelease();

camera =null;

}

@Override

public boolean onTouchEvent(MotionEvent event) {屏幕触摸事件

if (eventgetAction() == MotionEventACTION_DOWN) {按下时自动对焦

cameraautoFocus(null);

af =true;

}

if (eventgetAction() == MotionEventACTION_UP && af ==true) {放开后拍照

cameratakePicture(null, null, this);

af =false;

}

returntrue;

}

public void onPictureTaken(byte[] data, Camera camera) {拍摄完成后保存照片

try {

String path = EnvironmentgetExternalStorageDirectory() +"/testjpg";

data2file(data, path);

} catch (Exception e) {

}

camerastartPreview();

}

private void data2file(byte[] w, String fileName) throws Exception {将二进制数据转换为文件的函数

FileOutputStream out =null;

try {

out =new FileOutputStream(fileName);

outwrite(w);

outclose();

} catch (Exception e) {

if (out !=null)

outclose();

throw e;

}

}

}

如何调用android 摄像头 拍照

在Android开发过程中,有时需要调用手机自身设备的功能,本文侧重摄像头拍照功能的调用。

:blogcsdn/mahoking/article/details/28225907

怎么调用android的摄像头拍照

我们要调用摄像头的拍照功能,显然

第一步必须加入调用摄像头硬件的权限,拍完照后我们要将保存在SD卡中,必须加入SD卡读写权限,所以第一步,我们应该在Android清单文件中加入以下代码

<uses-permission android:name="androidpermissionCAMERA"/>摄像头权限

SD卡读写权限

<uses-permissionandroid:name="androidpermissionMOUNT_UNMOUNT_FILESYSTEMS" />

<uses-permissionandroid:name="androidpermissionWRITE_EXTERNAL_STORAGE"/>

第二步,要将摄像头捕获的图像实时地显示在手机上。

我们是用SurfaceView这个视图组件来实现的,因此在mainxml中加入下列代码

<SurfaceView

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:id="@+id/surfaceview"

/>

第三步,设置窗口的显示方式

首先获得当前窗口Windowwindow = getWindow();得到窗口

接着设置没有标题requestWindowFeature(WindowFEATURE_NO_TITLE);没有标题

接着设置全屏 windowsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN,

WindowManagerLayoutParamsFLAG_FULLSCREEN);设置全屏

当然,我们在拍照过程中,屏幕必须一致处于高亮状态,因此接着加入下面代码

windowaddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON);设置高亮

至此,我们将窗口的显示方式规定死了,然后才能设置窗口上显示的组件(顺序非常重要)

setContentView(Rlayoutmain);

第四步,设置SurficeView显示控件的属性

找到surficeView

surfaceView = (SurfaceView)findViewById(Ridsurfaceview);

设置它的像素为800x600

surfaceViewgetHolder()setFixedSize(800,480);

下面设置surfaceView不维护自己的缓冲区,而是等待屏幕的渲染引擎将内容推送到用户面前

surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS);

第五步,就是为surficeView加入回调方法(callBack)

surfaceViewgetHolder()addCallback(newSurfaceCallback());

上面的回调类是我们自己定义的,代码如下

private class SurfaceCallback implementsSurfaceHolderCallback{

@Override

public void surfaceCreated(SurfaceHolderholder) {

try {

camera = Cameraopen();打开硬件摄像头,这里导包得时候一定要注意是androidhardwareCamera

WindowManager wm = (WindowManager)getSystemService(ContextWINDOW_SERVICE);得到窗口管理器

Display display = wmgetDefaultDisplay();得到当前屏幕

CameraParameters parameters =cameragetParameters();得到摄像头的参数

parameterssetPreviewSize(displaygetWidth(),displaygetHeight());设置预览照片的大小

parameterssetPreviewFrameRate(3);设置每秒3帧

parameterssetPictureFormat(PixelFormatJPEG);设置照片的格式

parameterssetJpegQuality(85);设置照片的质量

parameterssetPictureSize(displaygetHeight(),displaygetWidth());设置照片的大小,默认是和屏幕一样大

camerasetParameters(parameters);

camerasetPreviewDisplay(surfaceViewgetHolder());通过SurfaceView显示取景画面

camerastartPreview();开始预览

isPreview = true;设置是否预览参数为真

} catch (IOException e) {

Loge(TAG, etoString());

}

}

@Override

public void surfaceChanged(SurfaceHolderholder, int format, int width,

int height) {

TODO Auto-generated method stub

}

@Override

public void surfaceDestroyed(SurfaceHolderholder) {

if(camera!=null){

if(isPreview){如果正在预览

camerasPreview();

camerarelease();

}

}

}

}

第六步,我们必须对按键事件进行监听,如是拍照还是聚焦,代码如下

public boolean onKeyDown(int keyCode,KeyEvent event) {处理按键事件

if(camera!=null&&eventgetRepeatCount()==0)代表只按了一下

{

switch(keyCode){

case KeyEventKEYCODE_BACK:如果是搜索键

cameraautoFocus(null);自动对焦

break;

case KeyEventKEYCODE_DPAD_CENTER:如果是中间键

cameratakePicture(null, null, new TakePictureCallback());将拍到的照片给第三个对象中,这里的TakePictureCallback()是自己定义的,在下面的代码中

break;

}

}

return true;阻止事件往下传递,否则按搜索键会变成系统默认的

}

------------------------------------------------------------------------------------------

private final class TakePictureCallbackimplements PictureCallback{

public void onPictureTaken(byte[] data,Camera camera) {

try {

Bitmap bitmap =BitmapFactorydecodeByteArray(data, 0, datalength);

File file = newFile(EnvironmentgetExternalStorageDirectory(),SystemcurrentTimeMillis()+"jpg");

FileOutputStream outputStream = newFileOutputStream(file);

bitmappress(CompressFormatJPEG, 100,outputStream);

outputStreamclose();

camerasPreview();

camerastartPreview();处理完数据之后可以预览

} catch (Exception e) {

Loge(TAG, etoString());

}

}

}

注意,代码中有两个回调类,一个是SurfaceCallback(),另外一个是TakePictureCallback(),初学者可能一时难以理解,通俗地讲,前者是用来监视surficeView这个暂时存放数据的显示控件的,根据它的显示情况调用不同的方法,包括surfaceCreated(),surfaceChanged(),surfaceDestroyed(),也就不难理解为什么会有这三个回调方法了(注意,在surfaceDestroyed()方法中必须释放摄像头,详细代码参见上方)。TakePictureCallback()是为了监视是否拍照而设计的接口,期中也仅有一个方法,camera将拍照得到的数据传入方法,我们便可以对拍照得到的数据进行进一步处理

vivoxplay只能用前置摄像头,不能用主摄像头

您好!

不能使用主摄像头提示什么呢,请你具体描述一下,以便我们更好的为您解答。

如果有任何问题可以随时来咨询我们的。非常感谢您对我们vivo的支持,祝您生活愉快!

PC camera 摄像头只能用光盘驱动吗?

有的不带盘的摄像头是免驱的,只要XP_SP2就会自认,另外你可以搜搜PC-CAMERA的万能驱动,不行的话还是老实点用盘装

联想A798T拍照怎么只能用前置摄像头呢/如何双摄像头切换

刷机包有问题,你先下载个别的相机看看能不能切换摄像头,或是有没有相关的相机补丁,不行的话你再刷回来就好了。

尊贵的用户,您好:

很抱歉给您带来疑惑了。若您需要切换前后置摄像头,可进入主菜单--相机--点击“+”后面的小相机图标即可切换,请您尝试。

若如果您尝试,没有该切换图标,建议到系统设置--应用程序--拍照--清除数据后试试,同时您也可以下载第三方拍照软件进行尝试,若使用第三方软件也会出现该情况,建议您备份下资料,恢复出厂设置后进行尝试,若依然不行,可抽空带上保修卡或发票联系当地的维修站点检测处理。

官网授权维修站点查询::support1lenovo/lenovo/wsi/station/servicestation。

感谢您对联想的支持,祝您生活愉快!

求助关于java调用摄像头拍照怎样禁止虚拟摄像头拍照

这个问题和java语言本身没啥关系。首先看你是用什么读取的摄像头来获得照片。

比如说你用flash来读取摄像头获得照片,那么有相关的api获得摄像头列表(此时的摄像头列表是全部的,包括虚拟摄像头的)

但是,你可以读取本地真实的摄像头(bs模式请用ocs控件读取,读取方式参照SystemManagementObject),然后比较真实的摄像头和现在正在拍照使用的摄像头即可。

真实实践过 望采纳。

win7上怎么调用摄像头拍照

打开“我的电脑”

下面应该有个“扫描仪和照相机”

打开你的照相机就可以拍照了

你好,我的手机拍照不知道怎么了,只能用前摄像头,后摄像头不能用,

你可以把手机重启一下试试。

或者你可以从应用宝里面下载个第三方拍照软件。然后拍照看看怎么样。

或者你恢复出厂设置。应该会好很多的。也有可能是你摄像损毁了。

从 Android 50 开始,Google 引入了一套全新的相机框架 Camera2(androidhardwarecamera2)并且废弃了旧的相机框架 Camera1(androidhardwareCamera)。作为一个专门从事相机应用开发的开发者来说,这一刻我等了太久了,Camera1 那寥寥无几的 API 和极差的灵活性早已不能满足日益复杂的相机功能开发。Camera2 的出现给相机应用程序带来了巨大的变革,因为它的目的是为了给应用层提供更多的相机控制权限,从而构建出更高质量的相机应用程序。本文是 Camera2 教程的开篇作,本章将介绍以下几个内容:

Camera2 的 API 模型被设计成一个 Pipeline(管道),它按顺序处理每一帧的请求并返回请求结果给客户端。下面这张来自官方的图展示了 Pipeline 的工作流程,我们会通过一个简单的例子详细解释这张图。

为了解释上面的示意图,假设我们想要同时拍摄两张不同尺寸的,并且在拍摄的过程中闪光灯必须亮起来。整个拍摄流程如下:

一个新的 CaptureRequest 会被放入一个被称作 Pending Request Queue 的队列中等待被执行,当 In-Flight Capture Queue 队列空闲的时候就会从 Pending Request Queue 获取若干个待处理的 CaptureRequest,并且根据每一个 CaptureRequest 的配置进行 Capture *** 作。最后我们从不同尺寸的 Surface 中获取数据并且还会得到一个包含了很多与本次拍照相关的信息的 CaptureResult,流程结束。

相机功能的强大与否和硬件息息相关,不同厂商对 Camera2 的支持程度也不同,所以 Camera2 定义了一个叫做 Supported Hardware Level 的重要概念,其作用是将不同设备上的 Camera2 根据功能的支持情况划分成多个不同级别以便开发者能够大概了解当前设备上 Camera2 的支持情况。截止到 Android P 为止,从低到高一共有 LEGACY、LIMITED、FULL 和 LEVEL_3 四个级别:

相机的所有 *** 作和参数配置最终都是服务于图像捕获,例如对焦是为了让某一个区域的图像更加清晰,调节曝光补偿是为了调节图像的亮度。因此,在 Camera2 里面所有的相机 *** 作和参数配置都被抽象成 Capture(捕获),所以不要简单的把 Capture 直接理解成是拍照,因为 Capture *** 作可能仅仅是为了让预览画面更清晰而进行对焦而已。如果你熟悉 Camera1,那你可能会问 setFlashMode() 在哪? setFocusMode() 在哪? takePicture() 在哪?告诉你,它们都是通过 Capture 来实现的。

Capture 从执行方式上又被细分为单次模式、多次模式和重复模式三种,我们来一一解释下:

CameraManager 是一个负责查询和建立相机连接的系统服务,它的功能不多,这里列出几个 CameraManager 的关键功能:

CameraCharacteristics 是一个只读的相机信息提供者,其内部携带大量的相机信息,包括代表相机朝向的 LENS_FACING ;判断闪光灯是否可用的 FLASH_INFO_AVAILABLE ;获取所有可用 AE 模式的 CONTROL_AE_AVAILABLE_MODES 等等。如果你对 Camera1 比较熟悉,那么 CameraCharacteristics 有点像 Camera1 的 CameraCameraInfo 或者 CameraParameters 。

CameraDevice 代表当前连接的相机设备,它的职责有以下四个:

熟悉 Camera1 的人可能会说 CameraDevice 就是 Camera1 的 Camera 类,实则不是,Camera 类几乎负责了所有相机的 *** 作,而 CameraDevice 的功能则十分的单一,就是只负责建立相机连接的事务,而更加细化的相机 *** 作则交给了稍后会介绍的 CameraCaptureSession。

Surface 是一块用于填充图像数据的内存空间,例如你可以使用 SurfaceView 的 Surface 接收每一帧预览数据用于显示预览画面,也可以使用 ImageReader 的 Surface 接收 JPEG 或 YUV 数据。每一个 Surface 都可以有自己的尺寸和数据格式,你可以从 CameraCharacteristics 获取某一个数据格式支持的尺寸列表。

CameraCaptureSession 实际上就是配置了目标 Surface 的 Pipeline 实例,我们在使用相机功能之前必须先创建 CameraCaptureSession 实例。一个 CameraDevice 一次只能开启一个 CameraCaptureSession,绝大部分的相机 *** 作都是通过向 CameraCaptureSession 提交一个 Capture 请求实现的,例如拍照、连拍、设置闪光灯模式、触摸对焦、显示预览画面等等。

CaptureRequest 是向 CameraCaptureSession 提交 Capture 请求时的信息载体,其内部包括了本次 Capture 的参数配置和接收图像数据的 Surface。CaptureRequest 可以配置的信息非常多,包括图像格式、图像分辨率、传感器控制、闪光灯控制、3A 控制等等,可以说绝大部分的相机参数都是通过 CaptureRequest 配置的。值得注意的是每一个 CaptureRequest 表示一帧画面的 *** 作,这意味着你可以精确控制每一帧的 Capture *** 作。

CaptureResult 是每一次 Capture *** 作的结果,里面包括了很多状态信息,包括闪光灯状态、对焦状态、时间戳等等。例如你可以在拍照完成的时候,通过 CaptureResult 获取本次拍照时的对焦状态和时间戳。需要注意的是,CaptureResult 并不包含任何图像数据,前面我们在介绍 Surface 的时候说了,图像数据都是从 Surface 获取的。

如果要我给出强有力的理由解释为什么要使用 Camera2,那么通过 Camera2 提供的高级特性可以构建出更加高质量的相机应用程序应该是最佳理由了。

如果你熟悉 Camera1,并且打算从 Camera1 迁移到 Camera2 的话,希望以下几个建议可以对你起到帮助:

本章到此结束,主要是介绍了 Camera2 的一些基础概念,让大家能够基本了解 Camera2 的工作流程和基础概念,并且知道使用 Camera2 能够做些什么。如果你对 Camera2 还是感到很陌生,不要紧,后续的教程会带领大家逐步深入了解 Camera2。

Camera默认的预览格式是 NV21,4:2:0 结构的,每个U、V用于4个Y

参考下下面的代码

Converts YUV420 NV21 to ARGB8888

@param data byte array on YUV420 NV21 format

@param width pixels width

@param height pixels height

@retur a ARGB8888 pixels int array Where each int is a pixels ARGB

/

public static int[] convertYUV420_NV21toARGB8888(byte [] data, int width, int height) {

int size = widthheight;

int offset = size;

int[] pixels = new int[size];

int u, v, y1, y2, y3, y4;

// i along Y and the final pixels

// k along pixels U and V

for(int i=0, k=0; i < size; i+=2, k+=1) {

y1 = data[i ]&0xff;

y2 = data[i+1]&0xff;

y3 = data[width+i ]&0xff;

y4 = data[width+i+1]&0xff;

v = data[offset+k ]&0xff;

u = data[offset+k+1]&0xff;

v = v-128;

u = u-128;

pixels[i ] = convertYUVtoARGB(y1, u, v);

pixels[i+1] = convertYUVtoARGB(y2, u, v);

pixels[width+i ] = convertYUVtoARGB(y3, u, v);

pixels[width+i+1] = convertYUVtoARGB(y4, u, v);

if (i!=0 && (i+2)%width==0)

i+=width;

}

return pixels;

}

private static int convertYUVtoARGB(int y, int u, int v) {

int r,g,b;

r = y + (int)(1402fu);

g = y - (int)(0344fv + 0714fu);

b = y + (int)(1772fv);

r = r>255 255 : r<0 0 : r;

g = g>255 255 : g<0 0 : g;

b = b>255 255 : b<0 0 : b;

return 0xff000000 | (r<<16) | (g<<8) | b;

}

Android Framework 提供了Camera的一个方法:

public final void takePicture (CameraShutterCallback shutter, CameraPictureCallback raw, CameraPictureCallback postview, CameraPictureCallback jpeg)

如果有Raw data的话,raw Callback是可以得到raw数据的,不是所有的android手机都向framework出raw数据,不过你可以试试;

我还知道一个方法是直接调driver,来取raw数据,通过HAL没有试过。

          如今生活当中每一个人都离不开手机,拍摄照片更加常见,刚好最近在研究Android中的Camera的“方向”问题,总结一下。好了,进入正题,通过手机的Camera拍摄出来的照片来自于相机的图像传感器,相机被固定到手机后,相机的图像传感器的图像采集方向就固定住了,因此相机传感器的采集图像的方向我们是改变不了,只能对采集后获得的数据进行旋转,以便得到正确的预览。我们可以通过CameraInfo对象的orientation属性来获取图像传感器的图像采集方向,orientation属性就描述着相机的图像传感器采集图像的方向,orientation是一个角度值,只能是0,90,180,270四个中的一个,表示的含义就是图像传感器采集图像的角度,忘记说了,这里的角度是相对于手机的“自然方向”来说的,何为“自然方向”?是指当宽比高短时,我们看到的手机的方向(竖屏),可以这样理解,这个值是相机所采集的需要顺时针旋转至自然方向的角度值,因为如果我们要想在手机的自然方向上正确预览相机拍照的数据,我们必须对相机传感器采集的图像进行顺时针旋转,这个旋转的角度就是orientation,注意只能对拍照后获得的数据进行旋转,我们是无法改变相机传感器采集图像的方向的,因为它在相机被固定到手机上后,就被固定死了。 

             图像传感器的预览方向默认情况下是和图像传感器的图像采集方向是一致,也就是前面提到的orientation值,那这里为什么说默认呢?是因为相机传感器的预览方向是可以改变的,不像图像传感器的图像采集方向无法改变,通过Camera对象的setDisplayOrientation方法改变预览方向(顺时针旋转)。对大部分手机来说,后置摄像头的orientation为90,也就是说我们需要对拍照采集的数据顺时针旋转90度,才能够在自然方向正确预览我们拍摄后的,需要通过Camera对象的setDisplayOrientation顺时针旋转90度才能在自然方向正确预览我们的摄像头画面。同样对于大部分手机来说,前置摄像头的orientation通常为270度,也就是说我们需要对拍照采集的数据顺时针旋转270度,才能够在自然方向正确预览我们拍摄后的,但是我们预览方向我们却不是顺时针旋转270度,而是90度,这是为什么呢?因为前者摄像头会在旋转预览方向之前,会对预览方向来一个水平的镜像翻转,这就是为什么我们通过前者摄像头像是在照镜子一般,可能还不太理解,我们会通过来对上面的分析进行演示。 

后置摄像头orientation=90,此时图像传感器采集图像的方向90度,相对于自然方向,如下:

此时图像采集的方向我们是无法改变的,但是能够改变预览的方向,通过setDisplayOrientation(90)顺时针旋转预览方向,以便在自然方向进行正确预览。

我们来看看前置摄像头orientation=270的情况,铭记前置摄像头预览方向在旋转之前会进行一个水平镜像翻转(可以理解为逆时针旋转180),这就是为什么我们通过手机前置摄像头预览时,看到的像是在照镜子一般。

此时我们需要将获取到的数据进行顺时针旋转270度,才能够在手机自然方向正确预览。接下来看看前者摄像头预览方向,注意咯

好了,就到这,水平有限,有什么错误的地方,希望各位大神留言,拜托了。

以上就是关于android中用Camera来调用摄像头,只能用takePicture来拍照吗全部的内容,包括:android中用Camera来调用摄像头,只能用takePicture来拍照吗、Android Camera2 教程 · 第一章 · 概览、Android Camera提取出来的yuv420源数据怎么提取y,u,v分量等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9348524.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-27
下一篇2023-04-27

发表评论

登录后才能评论

评论列表(0条)

    保存