文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android自定义相机实现定时拍照功能

2022-06-06 04:41

关注

这篇博客为大家介绍Android自定义相机,并且实现倒计时拍照功能。

首先自定义拍照会用到SurfaceView控件显示照片的预览区域,以下是布局文件:

activity_main.xml


<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
 android:layout_width="match_parent" 
 android:layout_height="match_parent" > 
 <SurfaceView 
  android:id="@+id/surface_view" 
  android:layout_width="match_parent" 
  android:layout_height="match_parent" /> 
 <RelativeLayout 
  android:layout_width="match_parent" 
  android:layout_height="match_parent" 
  android:orientation="vertical" > 
  <ImageView 
   android:id="@+id/start" 
   android:layout_width="wrap_content" 
   android:layout_height="wrap_content" 
   android:layout_centerHorizontal="true" 
   android:layout_alignParentBottom="true" 
   android:layout_marginBottom="10dp" 
   android:src="@drawable/capture"/> 
  <TextView 
   android:id="@+id/count_down" 
   android:layout_width="match_parent" 
   android:layout_height="match_parent" 
   android:layout_gravity="center" 
   android:gravity="center" 
   android:textSize="80sp"/> 
 </RelativeLayout> 
</FrameLayout> 

MainActivity.java


package com.jackie.timercamera; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Matrix; 
import android.hardware.Camera; 
import android.media.AudioManager; 
import android.media.MediaPlayer; 
import android.net.Uri; 
import android.os.Bundle; 
import android.os.Environment; 
import android.os.Handler; 
import android.support.v7.app.AppCompatActivity; 
import android.util.Log; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
import android.view.View; 
import android.widget.ImageView; 
import android.widget.TextView; 
import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.IOException; 
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback, 
  View.OnClickListener, Camera.PictureCallback { 
 private SurfaceView mSurfaceView; 
 private ImageView mIvStart; 
 private TextView mTvCountDown; 
 private SurfaceHolder mHolder; 
 private Camera mCamera; 
 private Handler mHandler = new Handler(); 
 private int mCurrentTimer = 10; 
 private boolean mIsSurfaceCreated = false; 
 private boolean mIsTimerRunning = false; 
 private static final int CAMERA_ID = 0; //后置摄像头 
// private static final int CAMERA_ID = 1; //前置摄像头 
 private static final String TAG = MainActivity.class.getSimpleName(); 
 @Override 
 protected void onCreate(Bundle savedInstanceState) { 
  super.onCreate(savedInstanceState); 
  setContentView(R.layout.activity_main); 
  initView(); 
  initEvent(); 
 } 
 @Override 
 protected void onPause() { 
  super.onPause(); 
  stopPreview(); 
 } 
 private void initView() { 
  mSurfaceView = (SurfaceView) findViewById(R.id.surface_view); 
  mIvStart = (ImageView) findViewById(R.id.start); 
  mTvCountDown = (TextView) findViewById(R.id.count_down); 
 } 
 private void initEvent() { 
  mHolder = mSurfaceView.getHolder(); 
  mHolder.addCallback(this); 
  mIvStart.setOnClickListener(this); 
 } 
 @Override 
 public void surfaceCreated(SurfaceHolder holder) { 
  mIsSurfaceCreated = true; 
 } 
 @Override 
 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
  startPreview(); 
 } 
 @Override 
 public void surfaceDestroyed(SurfaceHolder holder) { 
  mIsSurfaceCreated = false; 
 } 
 private void startPreview() { 
  if (mCamera != null || !mIsSurfaceCreated) { 
   Log.d(TAG, "startPreview will return"); 
   return; 
  } 
  mCamera = Camera.open(CAMERA_ID); 
  Camera.Parameters parameters = mCamera.getParameters(); 
  int width = getResources().getDisplayMetrics().widthPixels; 
  int height = getResources().getDisplayMetrics().heightPixels; 
  Camera.Size size = getBestPreviewSize(width, height, parameters); 
  if (size != null) { 
   //设置预览分辨率 
   parameters.setPreviewSize(size.width, size.height); 
   //设置保存图片的大小 
   parameters.setPictureSize(size.width, size.height); 
  } 
  //自动对焦 
  parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); 
  parameters.setPreviewFrameRate(20); 
  //设置相机预览方向 
  mCamera.setDisplayOrientation(90); 
  mCamera.setParameters(parameters); 
  try { 
   mCamera.setPreviewDisplay(mHolder); 
  } catch (Exception e) { 
   Log.d(TAG, e.getMessage()); 
  } 
  mCamera.startPreview(); 
 } 
 private void stopPreview() { 
  //释放Camera对象 
  if (mCamera != null) { 
   try { 
    mCamera.setPreviewDisplay(null); 
    mCamera.stopPreview(); 
    mCamera.release(); 
    mCamera = null; 
   } catch (Exception e) { 
    Log.e(TAG, e.getMessage()); 
   } 
  } 
 } 
 private Camera.Size getBestPreviewSize(int width, int height, 
           Camera.Parameters parameters) { 
  Camera.Size result = null; 
  for (Camera.Size size : parameters.getSupportedPreviewSizes()) { 
   if (size.width <= width && size.height <= height) { 
    if (result == null) { 
     result = size; 
    } else { 
     int resultArea = result.width * result.height; 
     int newArea = size.width * size.height; 
     if (newArea > resultArea) { 
      result = size; 
     } 
    } 
   } 
  } 
  return result; 
 } 
 @Override 
 public void onClick(View v) { 
  switch (v.getId()) { 
   case R.id.start: 
    if (!mIsTimerRunning) { 
     mIsTimerRunning = true; 
     mHandler.post(timerRunnable); 
    } 
    break; 
  } 
 } 
 private Runnable timerRunnable = new Runnable() { 
  @Override 
  public void run() { 
   if (mCurrentTimer > 0) { 
    mTvCountDown.setText(mCurrentTimer + ""); 
    mCurrentTimer--; 
    mHandler.postDelayed(timerRunnable, 1000); 
   } else { 
    mTvCountDown.setText(""); 
    mCamera.takePicture(null, null, null, MainActivity.this); 
    playSound(); 
    mIsTimerRunning = false; 
    mCurrentTimer = 10; 
   } 
  } 
 }; 
 @Override 
 public void onPictureTaken(byte[] data, Camera camera) { 
  try { 
   FileOutputStream fos = new FileOutputStream(new File 
     (Environment.getExternalStorageDirectory() + File.separator + 
       System.currentTimeMillis() + ".png")); 
   //旋转角度,保证保存的图片方向是对的 
   Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); 
   Matrix matrix = new Matrix(); 
   matrix.setRotate(90); 
   bitmap = Bitmap.createBitmap(bitmap, 0, 0, 
     bitmap.getWidth(), bitmap.getHeight(), matrix, true); 
   bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos); 
   fos.flush(); 
   fos.close(); 
  } catch (FileNotFoundException e) { 
   e.printStackTrace(); 
  } catch (IOException e) { 
   e.printStackTrace(); 
  } 
  mCamera.startPreview(); 
 } 
  
 public void playSound() { 
  MediaPlayer mediaPlayer = null; 
  AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); 
  int volume = audioManager.getStreamVolume( AudioManager.STREAM_NOTIFICATION); 
  if (volume != 0) { 
   if (mediaPlayer == null) 
    mediaPlayer = MediaPlayer.create(this, 
      Uri.parse("file:///system/media/audio/ui/camera_click.ogg")); 
   if (mediaPlayer != null) { 
    mediaPlayer.start(); 
   } 
  } 
 } 
} 

有两点需要注意:对于Camera来说,默认是横屏的,所以预览的时候和图片保存的时候都是横屏的,需要调整角度。

设置相机预览方法:


//设置相机预览方向
mCamera.setDisplayOrientation(90);

保存图片的时候调整角度:

效果图如下:


您可能感兴趣的文章:android 7自定义相机预览及拍照功能Android调用系统照相机拍照与摄像的方法Android如何调用系统相机拍照Android编程实现调用相册、相机及拍照后直接裁剪的方法Android自定义组件获取本地图片和相机拍照图片Android使用系统自带的相机实现一键拍照功能Android 系统相机拍照后相片无法在相册中显示解决办法Android 实现调用系统照相机拍照和录像的功能Android 调用系统照相机拍照和录像Android实现从本地图库/相机拍照后裁剪图片并设置头像Android自定义照相机倒计时拍照Android启动相机拍照并返回图片Android打开系统相机并拍照的2种显示方法


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯