因为搜了好多资料,内容差不多,但是看的好蛋疼,就写了个。照相机实现!!

简介:

如若转载请注明:王亟亟的大牛之路

在贴代码和讲实践之前先上图,让各位看官知道这是什么玩意
初始化的视图,就一个Activity
这里写图片描述
拍照时的状态,因为不是美图秀秀啊之类的摄像软件,所以这个清晰度已经够了
这里写图片描述
选择相册内图片的截图
这里写图片描述

先来说下Camera类
Android手机关于Camera的使用,一是拍照,二是摄像。
我们可以使用两类方法:一是借助Intent和MediaStroe调用系统Camera App程序来实现拍照和摄像功能,二是根据Camera API自写Camera程序。(例子是第一种,因为对拍摄内容没有更多的要求)

授权
在AndroidMainfest.xml中声明使用照相机.
Camera权限, 你必须在AndroidMainfest.xml中声明使用照相机的权限,例如

注:如果你是调用系统Camera程序的话,就不必声明
Camera特性,你必须在AndroidMainfest.xml中声明照相机特性,例如:

<uses-feature android:name="android.hardware.camera" />

如果你的程序可能需要使用照相机,但并不是一定的,那么可以设置android:required属性,比如:

<uses-feature android:name="android.hardware.camera"android:required="false" />

存储权限,如果你的程序想在扩展存储设备上(如sd卡)存储你的照片或者拍摄的视频,那么必须声明如下权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

音频录制权限, 为了录制音频或者视频,你必须在AndroidMainfest.xml文件中设置如下权限:
<uses-permission android:name="android.permission.RECORD_AUDIO" />

使用系统Camera程序
这是一种可以让你的程序以最少的编码,然后可以快速使用照相机的方法,它通过一个Intent来调用系统的Camera程序。一个Camera的intent可以发起一个请求,来让系统的Camera应用程序去拍摄照片或者录制视频,而且可以返回拍摄或者录制的结果给你自己的应用程序,那么接下来,我们将讨论如何使用这种方法。

i. 构造一个Camera Intent – 创建一个拍摄照片或者视频的Intent, 我们可以使用如下两种方法:
MediaStore.ACTION_IMAGE_CAPTURE – 一个intent action,用来向系统Camera程序请求拍摄图片。
MediaStore.ACTION_VIDEO_CAPTURE – 一个intent action, 用来向系统Camera程序请求录制视频。

ii. 开启Camera intent – 通过调用startActivityForResult()来执行Camera intent, 在你调用这个方法之后,系统Camera程序就是出现在用户界面,然后用户就可以拍摄照片或者视频了。

iii. 接收Intent 结果 – 在你的应用程序里面建立一个onActivityResult()方法来接收来自系统Camera程序的执行结果。当用户拍摄了照片或者视频(也许取消了拍摄操作),系统就会调用这个方法。

图片拍摄Intent
使用系统Camera来拍摄图片,是一种以最快的速度,最少的代码,让你的程序能够拍照的方法。一个图片拍摄的intent可以包含如下扩展信息:
i. MediaStore.EXTRA_OUTPUT – 指定一个Uri对象,系统Camera程序会把拍摄的图片存储到指定位置。这个设置一般是强烈推荐的。如果你不指定这个Uri路径,那么系统Camera程序会把图片以一个默认的名字,存储在一个默认的位置。我们可以通过返回的intent,然后用Intent.getData()方法来获取这个值。

ii. 下面这个例子可以告诉大家怎么构造一个拍摄图片的intent,并且执行它。

private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
    private Uri fileUri;
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); 
    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
    startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
    }

当startActivityForResult()方法执行之后,用户就会看到系统的Camera界面。当用户完成拍摄照片(或者取消拍摄)之后,用户界面就会返回你自己的应用程序。那么你必须拦截onActivityResult方法,以便接收执行结果和继续你自己代码的逻辑。

**c. 视频录制intent**
使用系统Camera来录制视频,是一种以最快的速度,最少的代码,让你的程序能够录制视频的方法。一个视频录制的intent可以包含如下扩展信息:

MediaStore.EXTRA_OUTPUT -- 指定一个Uri对象,系统Camera程序会把录制的视频存储到指定位置。这个设置一般是强烈推荐的。如果你不指定这个Uri路径,那么系统Camera程序会把视频以一个默认的名字,存储在一个默认的位置。我们可以通过返回的intent,然后用Intent.getData()方法来获取这个值。

MediaStore.EXTRA_VIDEO_QUALITY -- 视频质量,0(低质量,比较小的文件来存储视频), 1(高质量,比较大的文件来存储视频)

MediaStore.EXTRA_DURATION_LIMIT  -- 设置一个值来限制视频时间长度,秒为单位。

MediaStore.EXTRA_SIZE_LIMIT -- 设置一个值来限制视频大小,byte为单位。

**理论上的东西就讲这么些,源码和外面的翻译网上有,现在上代码!**
主Activity,就一个Activity

public class MainActivity extends ActionBarActivity implements View.OnClickListener {
//图片自定义控件
ImageView imageview;
//按钮控件
Button makephoto, choicephoto;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//检查策略
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads().detectDiskWrites().detectNetwork()
.penaltyLog().build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects().detectLeakedClosableObjects()
.penaltyLog().penaltyDeath().build());

    //获取id,否则空指针
    findViewById();
    initListener();
}
  @Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}
   @Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}
    private void findViewById() {
    imageview = (ImageView) findViewById(R.id.imageview);
    choicephoto = (Button) findViewById(R.id.choicephoto);
    makephoto = (Button) findViewById(R.id.makephoto);
}

private void initListener() {
    choicephoto.setOnClickListener(this);
    makephoto.setOnClickListener(this);
}
   //用于OnClickListener
@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.makephoto:
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            long time = Calendar.getInstance().getTimeInMillis();
            intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Environment
                    .getExternalStorageDirectory() + "/DCIM/", time
                    + ".jpg")));
            startActivityForResult(intent, 1);
            break;
        case R.id.choicephoto:
            Intent intent2 = new Intent(Intent.ACTION_PICK, null);
            intent2.setDataAndType(
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI,// 获取所有图片信息
                    "image/*");
            startActivityForResult(intent2, 2);
            break;
        default:
            break;
    }
} 

    //拍照必须回调的方法
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == 0)
        return;
    // 拍照
    if (requestCode == 1) {
        // 设置文件保存路径
        File picture = new File(Environment.getExternalStorageDirectory()
                + "/tempImage.jpg");
        startPhotoZoom(Uri.fromFile(picture));
    }
    if (data == null)
        return; 

    // 读取相册缩放图片
    if (requestCode == 2 && resultCode == RESULT_OK
            && null != data) {
        Uri selectedImage = data.getData();
        String[] filePathColumn = {MediaStore.Images.Media.DATA};

        Cursor cursor = getContentResolver().query(selectedImage,
                filePathColumn, null, null, null);
        cursor.moveToFirst();

        int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
        String picturePath = cursor.getString(columnIndex);
        cursor.close();
        imageview.setImageBitmap(BitmapFactory.decodeFile(picturePath));
    }

    // 处理结果
    if (requestCode == 3) {
        Bundle extras = data.getExtras();
        if (extras != null) {
            Bitmap photo = extras.getParcelable("data");
            //File fImage = new File("D:\\sdcard.img");
            try {

                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                //FileOutputStream stream = new FileOutputStream(fImage);
                photo.compress(Bitmap.CompressFormat.JPEG, 75, stream);// (0-100)压缩文件

                stream.close();
            } catch (IOException e) {

                e.printStackTrace();
            }
            //ByteArrayOutputStream stream = new ByteArrayOutputStream();
            imageview.setImageBitmap(photo); // 把图片显示在ImageView控件上
        }
    }
    super.onActivityResult(requestCode, resultCode, data);
}

//剪裁图片
public void startPhotoZoom(Uri uri) {
    Intent intent = new Intent("com.android.camera.action.CROP");
    intent.setDataAndType(uri, "image/*");
    intent.putExtra("crop", "true");
    // aspectX aspectY 是宽高的比例
    intent.putExtra("aspectX", 1);
    intent.putExtra("aspectY", 1);
    // outputX outputY 是裁剪图片宽高
    intent.putExtra("outputX", 300);
    intent.putExtra("outputY", 400);
    intent.putExtra("return-data", true);
    startActivityForResult(intent, 3);
}

}

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:id="@+id/toolLayout">

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="拍照"
            android:id="@+id/makephoto"
            android:layout_weight="1"
            android:background="@color/green"
            android:textColor="@color/white" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="选择相册"
            android:id="@+id/choicephoto"
            android:layout_weight="1"
            android:background="@color/white"
            android:textColor="@color/light_blue" />
    </LinearLayout>

    <RelativeLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_above="@+id/toolLayout"
        android:id="@+id/contentLayout">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/imageview"
            android:layout_gravity="clip_horizontal"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:background="@color/gray" />

    </RelativeLayout>
</RelativeLayout>

colors:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="gray">#5e5e5e</color>
    <color name="green">#ff00bf00</color>
    <!-- 白色 -->
    <color name="white">#FFFFFF</color>
    <!-- 浅蓝 -->
    <color name="light_blue">#005293</color>
</resources>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="example.wjj.camera">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
</manifest>

具体功能还是看源码吧!
下载地址:http://yunpan.cn/cQXjwrrHXRIjf 访问密码 05e3
有问题欢迎QQ452270579联系!

目录
相关文章
|
23天前
|
开发框架 前端开发 JavaScript
微信小游戏案例三 抓星星
微信小游戏案例三 抓星星
83 0
微信小游戏案例三 抓星星
|
4月前
|
网络安全 Python
我不善言辞,但还是想教你做个没用的东西
一个可以禁用任意程序的上下行网络的小工具,有倒计时功能
|
6月前
|
前端开发 JavaScript 程序员
程序员教你用代码制作3d爱心跳动特效,正好拿去送给女神给她个惊喜
使用HTML、CSS和JavaScript实现了一个三维网格采样器`MeshSurfaceSampler`,适用于任意浏览器,推荐谷歌。代码创建了一个类,从缓冲几何体的三角形网格中进行随机采样。提供了设置权重属性、构建分布和自定义随机数生成器的功能。用户只需将代码复制到文本文档并保存为HTML文件,即可运行。适合编程爱好者尝试,也可分享给他人。
194 1
四、巧用Camtasia来剪视频 | 微课系列教程
因为平时我们要用到的视频操作很多,视频拼接、细节修正、从长视频中取一部分等等。那么本课以微课录制后的视频裁剪为例,教大家一些简单的视频剪切和音频杂音处理,最后导出视频。
111 0
|
小程序 Windows
电脑可以刷微信朋友圈,这下能更好地摸鱼了?
电脑可以刷微信朋友圈,这下能更好地摸鱼了?
超火 3D 照片墙,你学废了吗?
超火 3D 照片墙,你学废了吗?
151 0
|
小程序 C# 程序员
七夕快到了!表白小程序制作详解,撩翻你的女神!
大家可能都会在抖音上刷过,那种表白小程序,但在我看来表白还是亲口说出来比较好,这类小程序只适合在平常的一些小节日给对方一个惊喜。话不多说,现在进入正题:         首先,要在电脑上安装微软的编译软件,我这里是使用的VS2017,安装的时候如果没有别的需要,直接选择下载wpf的组件就好。
1867 0
|
机器学习/深度学习 新零售