栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 移动开发 > Android

Android自定义照相机的实例

Android 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android自定义照相机的实例

Android自定义照相机实现

近期小巫在学校有一个创新项目,也不是最近,是一个拖了很久的项目,之前一直没有去搞,最近因为要中期检查,搞得我跟小组成员一阵忙活,其实开发一款照相机软件并不太难,下面就是通过自定义的方式来实现手机照相的功能。

创建一个项目:FingerTakePicture

首先来搞一下界面:

 
   
   
   
     
     
    

界面效果(无法把预览给截屏下来滴):

权限设置少不了:

 
 
   
 
   
   
   
   
   
 
     
       
  
 
  
       
     
     
   
 
 

主Activity:

package com.wwj.finger; 
 
import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
 
 
import android.app.Activity; 
import android.content.Intent; 
import android.graphics.PixelFormat; 
import android.hardware.Camera; 
import android.hardware.Camera.PictureCallback; 
import android.os.Bundle; 
import android.os.Environment; 
import android.view.KeyEvent; 
import android.view.MotionEvent; 
import android.view.Surface; 
import android.view.SurfaceHolder; 
import android.view.SurfaceHolder.Callback; 
import android.view.SurfaceView; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.Toast; 
 
 
public class MainActivity extends Activity { 
  private View layout; 
  private Camera camera; 
  private Camera.Parameters parameters = null; 
 
  Bundle bundle = null; // 声明一个Bundle对象,用来存储数据 
 
  @Override 
  public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    // 显示界面 
    setContentView(R.layout.activity_main); 
 
    layout = this.findViewById(R.id.buttonLayout); 
 
    SurfaceView surfaceView = (SurfaceView) this 
 .findViewById(R.id.surfaceView); 
    surfaceView.getHolder() 
 .setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    surfaceView.getHolder().setFixedSize(176, 144); //设置Surface分辨率 
    surfaceView.getHolder().setKeepScreenOn(true);// 屏幕常亮 
    surfaceView.getHolder().addCallback(new SurfaceCallback());//为SurfaceView的句柄添加一个回调函数 
  } 
 
   
  public void btnonclick(View v) { 
    if (camera != null) { 
      switch (v.getId()) { 
      case R.id.takepicture: 
 // 拍照 
 camera.takePicture(null, null, new MyPictureCallback()); 
 break; 
      } 
    } 
  } 
 
   
  public void imageClick(View v) { 
    if (v.getId() == R.id.scalePic) { 
      if (bundle == null) { 
 Toast.makeText(getApplicationContext(), R.string.takephoto, 
     Toast.LENGTH_SHORT).show(); 
      } else { 
 Intent intent = new Intent(this, ShowPicActivity.class); 
 intent.putExtras(bundle); 
 startActivity(intent); 
      } 
    } 
  } 
 
  private final class MyPictureCallback implements PictureCallback { 
 
    @Override 
    public void onPictureTaken(byte[] data, Camera camera) { 
      try { 
 bundle = new Bundle(); 
 bundle.putByteArray("bytes", data); //将图片字节数据保存在bundle当中,实现数据交换 
 saveToSDCard(data); // 保存图片到sd卡中 
 Toast.makeText(getApplicationContext(), R.string.success, 
     Toast.LENGTH_SHORT).show(); 
 camera.startPreview(); // 拍完照后,重新开始预览 
 
      } catch (Exception e) { 
 e.printStackTrace(); 
      } 
    } 
  } 
 
   
  public static void saveToSDCard(byte[] data) throws IOException { 
    Date date = new Date(); 
    SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); // 格式化时间 
    String filename = format.format(date) + ".jpg"; 
    File fileFolder = new File(Environment.getExternalStorageDirectory() 
 + "/finger/"); 
    if (!fileFolder.exists()) { // 如果目录不存在,则创建一个名为"finger"的目录 
      fileFolder.mkdir(); 
    } 
    File jpgFile = new File(fileFolder, filename); 
    FileOutputStream outputStream = new FileOutputStream(jpgFile); // 文件输出流 
    outputStream.write(data); // 写入sd卡中 
    outputStream.close(); // 关闭输出流 
  } 
 
 
  private final class SurfaceCallback implements Callback { 
 
    // 拍照状态变化时调用该方法 
    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, 
 int height) { 
      parameters = camera.getParameters(); // 获取各项参数 
      parameters.setPictureFormat(PixelFormat.JPEG); // 设置图片格式 
      parameters.setPreviewSize(width, height); // 设置预览大小 
      parameters.setPreviewframeRate(5); //设置每秒显示4帧 
      parameters.setPictureSize(width, height); // 设置保存的图片尺寸 
      parameters.setJpegQuality(80); // 设置照片质量 
    } 
 
    // 开始拍照时调用该方法 
    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 
      try { 
 camera = Camera.open(); // 打开摄像头 
 camera.setPreviewDisplay(holder); // 设置用于显示拍照影像的SurfaceHolder对象 
 camera.setDisplayOrientation(getPreviewDegree(MainActivity.this)); 
 camera.startPreview(); // 开始预览 
      } catch (Exception e) { 
 e.printStackTrace(); 
      } 
 
    } 
 
    // 停止拍照时调用该方法 
    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
      if (camera != null) { 
 camera.release(); // 释放照相机 
 camera = null; 
      } 
    } 
  } 
 
   
  @Override 
  public boolean onTouchEvent(MotionEvent event) { 
    switch (event.getAction()) { 
    case MotionEvent.ACTION_DOWN: 
      layout.setVisibility(ViewGroup.VISIBLE); // 设置视图可见 
      break; 
    } 
    return true; 
  } 
 
   
  @Override 
  public boolean onKeyDown(int keyCode, KeyEvent event) { 
    switch (keyCode) { 
    case KeyEvent.KEYCODE_CAMERA: // 按下拍照按钮 
      if (camera != null && event.getRepeatCount() == 0) { 
 // 拍照 
 //注:调用takePicture()方法进行拍照是传入了一个PictureCallback对象——当程序获取了拍照所得的图片数据之后 
 //,PictureCallback对象将会被回调,该对象可以负责对相片进行保存或传入网络 
 camera.takePicture(null, null, new MyPictureCallback()); 
      } 
    } 
    return super.onKeyDown(keyCode, event); 
  } 
 
  // 提供一个静态方法,用于根据手机方向获得相机预览画面旋转的角度 
  public static int getPreviewDegree(Activity activity) { 
    // 获得手机的方向 
    int rotation = activity.getWindowManager().getDefaultDisplay() 
 .getRotation(); 
    int degree = 0; 
    // 根据手机的方向计算相机预览画面应该选择的角度 
    switch (rotation) { 
    case Surface.ROTATION_0: 
      degree = 90; 
      break; 
    case Surface.ROTATION_90: 
      degree = 0; 
      break; 
    case Surface.ROTATION_180: 
      degree = 270; 
      break; 
    case Surface.ROTATION_270: 
      degree = 180; 
      break; 
    } 
    return degree; 
  } 
} 



用来显示图片的Activity:

package com.wwj.finger; 
 
 
import android.app.Activity; 
import android.content.Intent; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Matrix; 
import android.os.Bundle; 
import android.widget.ImageView; 
 
public class ShowPicActivity extends Activity { 
  private ImageView ivPic = null; // 显示图片控件 
 
 
   
  @Override 
  protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.showpic); 
    ivPic = (ImageView) findViewById(R.id.ivPic); 
    setImageBitmap(getImageFormBundle()); 
 
  } 
 
 
   
  public void setImageBitmap(byte[] bytes) { 
    Bitmap cameraBitmap = byte2Bitmap(); 
    // 根据拍摄的方向旋转图像(纵向拍摄时要需要将图像选择90度) 
    Matrix matrix = new Matrix(); 
    matrix.setRotate(MainActivity.getPreviewDegree(this)); 
    cameraBitmap = Bitmap 
 .createBitmap(cameraBitmap, 0, 0, cameraBitmap.getWidth(), 
     cameraBitmap.getHeight(), matrix, true); 
    ivPic.setImageBitmap(cameraBitmap); 
  } 
 
   
  public byte[] getImageFormBundle() { 
    Intent intent = getIntent(); 
    Bundle data = intent.getExtras(); 
    byte[] bytes = data.getByteArray("bytes"); 
    return bytes; 
  } 
 
   
  private Bitmap byte2Bitmap() { 
    byte[] data = getImageFormBundle(); 
    // 将byte数组转换成Bitmap对象 
    Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); 
    return bitmap; 
  } 
} 

这是小巫那个创新项目的一小部分,已经完美实现简单的照相机功能了,保存图片不会像有些网友提供的代码给定一个特定的文件名,不能保存多张图片,还特定把一些方法封装了一下,有需要的朋友好好看看吧。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/158392.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号