android 自定义相机源码,Android 自定义相机及分析源码

Android 自定义相机及分析源码

使用Android 系统相机的方法:

要想让应用有相机的action,咱们就必须在清单文件中做一些声明,好让系统知道,如下

action的作用就是声明action的类型,便于Intent的使用,category的作用就是注册,没有它。相关操作将不起作用。

一种方式是简单粗暴的实现,如下

Intent intent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

startActivityForResult(intent, REQ_1);

//然后在 onActivityResult方法中实现数据的获取,此处是展示在了一个ImageView上

if(resultCode==RESULT_OK){

if(requestCode==REQ_1){

Bundle bundle=data.getExtras();

Bitmap bitmap=(Bitmap) bundle.get("data");

imageView.setImageBitmap(bitmap);

}

小总结:这样的好处是简单快捷,但是在现在的android智能机中,好多相片都是很大的,这里获得的仅仅是一个缩略图罢了

另外一种方式是稍微温婉一点了,而且效果也更好一点,好处就在于它是先将照片信息存储到本地一个临时文件中,然后让ImageView去相关路径下进行读取,这样就可以获得清晰度很高的图片了。如下

/*

* 此方法的存在意义就是不在onActivityResult方法的data中获取我们拍照的缩略图,而是从我们的文件输出目录下直接查看原图

* 这样的好处就是可以对大容量的照片进行便捷的准确的操作

*/

public void onStartCarema2(View view){

Intent intent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

//见你给你路径传递回需要的处理方法中

Uri uri=Uri.fromFile(new File(myFilePath));

//设置文件的输出路径

intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);

startActivityForResult(intent, REQ_2);

}

//然后在onActivityResult方法中进行相关的处理就可以了

else if(requestCode==REQ_2){

FileInputStream fis=null;

try {

fis=new FileInputStream(myFilePath);

Bitmap bitmap=BitmapFactory.decodeStream(fis);

imageView.setImageBitmap(bitmap);

} catch (FileNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}finally{

try {

fis.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

//记得最后一定要关闭相关的流操作。否则会引起相关的异常的。

开发自定义的相机

由于开发自定义的相机要进行相关的权限的生命,所以一定不要忘记在清单文件中做相关的处理,如下

然后有以下几个步骤:

创建Camera,并完成初始化Camera,开始预览,释放资源三个方法

与Activity的SurfaceView进行绑定。

在系统的onPause(),onResume()方法中进行相关状态设置

对Camera进行参数设置,作用就是对照片类型和状态进行相关的设置

将拍得的照片进行展示,一般会新开一个Activity,用ImageView进行承载,我们还可以在此Activity上添加TextView,实现水印效果等其他的美化操作

另外,如果想加入自动聚焦的功能,就可以在SurfaceView上添加onClickListener(),对屏幕进行侦听,调用myCamera.autoFocus(null);方法即可

以上就是整个思路

接下来就是使用系统Camera的代码展示

(可以直接copy相关代码块,添加到你的应用中去,实现Camera这一功能。)

首先是MainActivity

布局

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingBottom="@dimen/activity_vertical_margin"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

android:orientation="vertical"

tools:context=".MainActivity" >

android:id="@+id/startCarema"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_margin="6dp"

android:text="StartCarema"

android:onClick="onStartCarema"

/>

android:id="@+id/startCarema2"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_margin="6dp"

android:text="StartCarema2"

android:onClick="onStartCarema2"

/>

android:id="@+id/customCarema"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_margin="6dp"

android:text="CustomCarema"

android:onClick="onCustomCarema"

/>

android:id="@+id/imageview"

android:layout_width="match_parent"

android:layout_height="match_parent"

/>

代码

package com.example.camerademo;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import android.app.Activity;

import android.content.Intent;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.net.Uri;

import android.os.Bundle;

import android.os.Environment;

import android.provider.MediaStore;

import android.view.View;

import android.widget.Button;

import android.widget.ImageView;

public class MainActivity extends Activity {

//为下面的获取请求所用

private static int REQ_1=1;

private static int REQ_2=2;

Button btn_startCareme,btn_startCarema2,btn_customCarema;

ImageView imageView;

//定义照片存储的路径

private String myFilePath;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

btn_startCareme=(Button) findViewById(R.id.startCarema);

btn_startCarema2=(Button) findViewById(R.id.startCarema2);

btn_customCarema=(Button) findViewById(R.id.customCarema);

imageView=(ImageView) findViewById(R.id.imageview);

//初始化不同手机的SD卡的路径

myFilePath=Environment.getExternalStorageDirectory().getPath();

myFilePath=myFilePath+"/"+"temperature.png";

}

public void onCustomCarema(View view){

Intent intent=new Intent(this,CustomCarema.class);

startActivity(intent);

}

public void onStartCarema(View view){

Intent intent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

startActivityForResult(intent, REQ_1);

}

/*

* 此方法的存在意义就是不在onActivityResult方法的data中获取我们拍照的缩略图,而是从我们的文件输出目录下直接查看原图

* 这样的好处就是可以对大容量的照片进行便捷的准确的操作

*/

public void onStartCarema2(View view){

Intent intent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

//见你给你路径传递回需要的处理方法中

Uri uri=Uri.fromFile(new File(myFilePath));

//设置文件的输出路径

intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);

startActivityForResult(intent, REQ_2);

}

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

// TODO Auto-generated method stub

super.onActivityResult(requestCode, resultCode, data);

if(resultCode==RESULT_OK){

if(requestCode==REQ_1){

Bundle bundle=data.getExtras();

Bitmap bitmap=(Bitmap) bundle.get("data");

imageView.setImageBitmap(bitmap);

}else if(requestCode==REQ_2){

FileInputStream fis=null;

try {

fis=new FileInputStream(myFilePath);

Bitmap bitmap=BitmapFactory.decodeStream(fis);

imageView.setImageBitmap(bitmap);

} catch (FileNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}finally{

try {

fis.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

}

}

接下来是自定义相机的代码

主界面布局

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical" >

android:id="@+id/capture"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_margin="6dp"

android:text="Capture"

android:onClick="onCapture"

/>

android:id="@+id/preview"

android:layout_width="match_parent"

android:layout_height="match_parent"

/>

ResultActivity的布局

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical" >

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="Capture Result"

android:textSize="28dp"

android:textColor="#BFAACD"

android:gravity="center"

/>

android:id="@+id/picture"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:scaleType="center"

/>

代码

首先是CustomCamera类,

package com.example.camerademo;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import android.app.Activity;

import android.content.Intent;

import android.graphics.ImageFormat;

import android.hardware.Camera;

import android.os.Bundle;

import android.view.SurfaceHolder;

import android.view.SurfaceView;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

@SuppressWarnings("unused")

public class CustomCarema extends Activity implements SurfaceHolder.Callback{

private Camera myCamera;

private SurfaceView preview;

private SurfaceHolder myHolder; //myHolder勇于展现surfaceView的图像

private Camera.PictureCallback myPictureCallBack=new Camera.PictureCallback() {

@Override

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

//将拍照得到的数据信息存储到本地

File tempFile=new File("/sdcard/temp.png");

try {

FileOutputStream fos=new FileOutputStream(tempFile);

fos.write(data);

fos.close();

//然后将这个照片的数据信息传送给要进行展示的Activity即可

Intent intent=new Intent(CustomCarema.this,ResultActivity.class);

intent.putExtra("PicturePath", tempFile.getAbsolutePath());

startActivity(intent);

//拍照结束之后销毁当前的Activity,进入到图片展示界面

CustomCarema.this.finish();

} catch (FileNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

};

@Override

protected void onCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

setContentView(R.layout.customcarema);

preview=(SurfaceView) findViewById(R.id.preview);

myHolder=preview.getHolder();

myHolder.addCallback(this);

//实现点击屏幕自动聚焦的功能,此处并不需要拍照,故只是聚焦

preview.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View arg0) {

// TODO Auto-generated method stub

myCamera.autoFocus(null);

}

});

}

@Override

protected void onResume() {

super.onResume();

if(myCamera==null){

myCamera=getCamera();

if(myHolder != null ){

setStartPreview(myCamera, myHolder);

}

}

}

@Override

protected void onPause() {

// TODO Auto-generated method stub

super.onPause();

releaseCamera();

}

/**

* 释放相机的资源

*/

private void releaseCamera(){

if(myCamera !=null ){

myCamera.setPreviewCallback(null);

myCamera.stopPreview();

myCamera.release();

myCamera=null;

}

}

/**

* 拍照的一些参数设置,点击此按钮之后会触发拍照的会掉,进而实现拍照的效果

* @param view

*/

public void onCapture(View view){

Camera.Parameters parameters=myCamera.getParameters();

//设置照片的类型

parameters.setPictureFormat(ImageFormat.JPEG);

parameters.setPictureSize(800, 600);

//设置为自动聚焦

parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);

//设置为自动聚焦是不够的,因为我们先得到的是最为清晰的图片,所以要在聚焦成功的时候才进行拍照

myCamera.autoFocus(new Camera.AutoFocusCallback() {

@Override

public void onAutoFocus(boolean success, Camera camera) {

// TODO Auto-generated method stub

if(success){

myCamera.takePicture(null, null, myPictureCallBack);

}

}

});

}

/**

* 获取系统的一个Camera对象

*/

private Camera getCamera(){

Camera camera=null;

try{

camera=Camera.open();

}catch(Exception e){

e.printStackTrace();

}

return camera;

}

/**

* 开始预览相机的内容,其实就是讲surfaceHolder与之绑定

*/

private void setStartPreview(Camera camera,SurfaceHolder holder){

//直接调用系统方式绑定预览

try {

camera.setPreviewDisplay(holder);

//由于系统默认使用横屏预览,,所以要进行设置

camera.setDisplayOrientation(90);

camera.startPreview();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

@Override

public void surfaceChanged(SurfaceHolder holder, int arg1, int arg2, int arg3) {

// TODO Auto-generated method stub

myCamera.stopPreview();

setStartPreview(myCamera, myHolder);

}

@Override

public void surfaceCreated(SurfaceHolder holder) {

// TODO Auto-generated method stub

setStartPreview(myCamera, myHolder);

}

@Override

public void surfaceDestroyed(SurfaceHolder arg0) {

// TODO Auto-generated method stub

releaseCamera();

}

}

然后是结果界面代码:

package com.example.camerademo;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import android.app.Activity;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Matrix;

import android.os.Bundle;

import android.widget.ImageView;

public class ResultActivity extends Activity {

@Override

protected void onCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

setContentView(R.layout.resultactivity);

String path=getIntent().getStringExtra("PicturePath");

ImageView imageview=(ImageView) findViewById(R.id.picture);

//由于这样稚嫩获得横屏,所以我们要使用流的形式来转换

// Bitmap bitmap=BitmapFactory.decodeFile(path);

// imageview.setImageBitmap(bitmap);

FileInputStream fis;

try {

fis = new FileInputStream(path);

Bitmap bitmap=BitmapFactory.decodeStream(fis);

Matrix matrix=new Matrix();

matrix.setRotate(90);

bitmap=Bitmap.createBitmap(bitmap, 0,0, bitmap.getWidth()

,bitmap.getHeight(),matrix,true);

imageview.setImageBitmap(bitmap);

} catch (FileNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

以上代码中已经做了下关的代码注释

总结:

安卓6.0以上版本记得加动态权限,不然会报空指针哦,还有点击拍照事件那里  别忘了加进去,不然拍照没反应

以上就是Android 自定义相机的实例详解,如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/438744.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[你必须知道的.NET]第十三回:从Hello, world开始认识IL

本文将介绍以下内容: IL代码分析方法 Hello, world历史 .NET学习方法论1. 引言 1988年Brian W. Kernighan和Dennis M. Ritchie合著了软件史上的经典巨著《The C programming Language》,我推荐所有的程序人都有机会重温这本历史上的经典之作。从那时起…

android服务器怎么做的,[Android]Android 制作一个HTTP服务器应用

上传文件开始想用apache的开源库获取文件,但是失败了,要么文件不全,要么就完全为空,还是自己写。文件上传请求头的部分内容contentType:multipart/form-data; boundary----WebKitFormBoundaryHpUAY0qCryu0Oc7o我们需要获取boundar…

[你必须知道的.NET]第十四回:认识IL代码---从开始到现在

本文将介绍以下内容: IL代码分析方法 IL命令解析 .NET学习方法论 1. 引言 自从『你必须知道.NET』系列开篇以来,受到大家很多的关注和支持,给予了anytao巨大的鼓励和动力。俱往昔,我发现很多的园友都把…

android 获取服务对象,android 如何取得正在运行的service对象

在写有关推送的代码,用的长连接的方式。具体逻辑:登录时 启service,service中启一个线程,线程中构建一个CommunicateManegr对象,此对象里面有一个BlockingDeque双端队列处理包的顺序问题, 还有若干线程分别…

[你必须知道的.NET]第十五回:继承本质论

本文将介绍以下内容: 什么是继承?继承的实现本质1. 引言 关于继承,你是否驾熟就轻,关于继承,你是否了如指掌。 本文不讨论继承的基本概念,我们回归本质,从编译器运行的角度来揭示.NET继承中的…

海岸鸿蒙2018年标准物质,海岸鸿蒙——20年权威的标准物质研制单位

摘要:海岸鸿蒙创办于1996年,是专业从事国家标准物质研发、生产、销售的高新技术企业。海岸鸿蒙创办于1996年,是专业从事国家标准物质研发、生产、销售的高新技术企业。海岸鸿蒙自创办以来,一直秉持“以市场为导向,以科…

[你必须知道的.NET]第十六回:深入浅出关键字---using全接触

本文将介绍以下内容: using指令的多种用法using语句在Dispose模式中的应用1. 引言 在.NET大家庭中,有不少的关键字承担了多种角色,例如new关键字就身兼数职,除了能够创建对象,在继承体系中隐藏基类成员,还在…

华为双系统是鸿蒙系统吗,华为p50pro是鸿蒙系统吗-华为p50pro有双系统吗

华为p50pro的外观基本上就是延续了上一代的风格,没有什么太大的变化,不过影像能力还是非常令人期待的,下面一起来了解华为p50pro的系统方面,看看有没有你暂所不知的消息。近日,有消息曝光了华为 P50 Pro将会有 Harmony…

[你必须知道的.NET]第十七回:貌合神离:覆写和重载

本文将介绍以下内容: 什么是覆写,什么是重载覆写与重载的区别覆写与重载在多态特性中的应用1. 引言 覆写(override)与重载(overload),是成就.NET面向对象多态特性的基本技术之一,两…

鸿蒙系统正式开源,余承东:鸿蒙系统正式开源,友商也可以使用!

鸿蒙OS2.0正式开源:从PPT走向前台,该谁脸红了?在9月10日的开发者大会上,华为鸿蒙2.0发布,已经不再是某些人嘴中的PPT、又哄又蒙的鸿蒙了。说鸿蒙是PPT的言论,在前不久还能看到,如今鸿蒙已经发布…

[你必须知道的.NET]第十八回:对象创建始末(上)

本文将介绍以下内容: 对象的创建过程内存分配分析内存布局研究1. 引言 了解.NET的内存管理机制,首先应该从内存分配开始,也就是对象的创建环节。对象的创建,是个复杂的过程,主要包括内存分配和初始化两个环节。例如&…

viper4android fxifi,ViPer4android. FX顶级音效!

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼名称:OPPO X903 杜比音效脉冲反馈样本 For VIPER4Android FX v2.0样本数量:72适配V4A版本:ViPER4Android FX v2.2.0.1 或更高适用范围:耳机内放制作者:漫游因特网授权&…

[你必须知道的.NET]第十九回:对象创建始末(下)

本文将介绍以下内容: 对象的创建过程内存分配分析内存布局研究接上回[第十八回:对象创建始末(上)],继续对对象创建话题的讨论>>> 2.2 托管堆的内存分配机制 引用类型的实例分配于托管堆上,而线…

android material 颜色值,Android Material Colors 谷歌 Material Design 标准颜色

Android Material Colors谷歌 Material Design 标准颜色。调色板资源文件通过 doc-getter 自动抓取生成。运行 Demo 来查看效果。UsageGradlecompile com.takwolf.android.materialdesign:color:0.0.1Stylecolor/material_indigo_500color/material_indigo_700color/material_p…

突然吐字不清_要注意说话吐字不清小心是脑中风前兆

任何疾病发病之前往往会有一些前兆出现,像是脑中风这种疾病在发作之前也是有前兆的,若是朋友们能够尽早的发现就能够在发病前进行治疗了。朋友们要注意的是说话吐字不清小心是脑中风前兆,这是脑中风发病前的典型前兆,还有头晕、呕…

[你必须知道的.NET]第二十回:学习方法论

本文,源自我回答刚毕业朋友关于.NET学习疑惑的回复邮件。 本文,其实早计划在《你必须知道的.NET》写作之初的后记部分,但是因为个中原因未能如愿,算是补上本书的遗憾之一。 本文,作为[《你必须知道的.NET》]系列的第20…

c++ vs release没有exe_未来安全 | 第一次Geant4培训总结 | 有没有你关注的问题呢?...

Geant4简介Geant4是蒙卡工具包,模拟很多粒子,记录一些统计量,用这些统计量去估计真实的物理实验的结果。蒙卡模拟程序,从最老的MCNP,到PENELOPE,FLUKA等。MCNP是用输入卡片(输入文件)实现的,在一…

[你必须知道的.NET]第二十一回:认识全面的null

说在,开篇之前 null、nullable、??运算符、null object模式,这些闪亮的概念在你眼前晃动,我们有理由相信“存在即合理”,事实上,null不光合理,而且重要。本文,从null的基本认知开始&#xff0…

html用表格做个人主页页面,利用HTML的表格进行页面布局

在DIVCSS布局出现前,基本上所用的网站都使用table来进行布局。因为table布局很简单,但是table布局不灵活且代码很多。下面将介绍怎样使用table来进行布局。实例:我们来布局一个常见网站后台程序的架构。布局图如下所示:实例代码&a…

cesium坡度坡向分析_景观设计分析图制作技巧到底是什么?

国外设计中,人们都开始用动态分析图啦厉害的不要不要啊!如果你也想做如此高逼格的分析图记得往下看!景观设计分析为:人文,背景,区位,现状,历史,功能,流线&…