android 之 Camera

由于我刚入职现在的这家公司的时候,他们对涉及到图片的比较多,所以打算写一系列图片的文章,首先就从制造图片的地方开始写起–Camera

如果你的app里面只是需要拍一张照片,只需要调用系统的照相机就可以满足你的需求了

通过ACTION_IMAGE_CAPTURE调用系统的照相机

intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);

然后在通过startActivityForResult方法跳转

onActivityResult:

Bundle extras = data.getExtras();
Bitmap bitmap = (Bitmap) extras.get("data");
showImage.setImageBitmap(bitmap);

一般的情况下这样就满足了你的需求,也不需要增加权限,但是这里需要注意的是通过data获得的是一张缩略图,如果想获得一张原图,就需要指定图片的保存地址

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

intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);     
      
intent.putExtra(MediaStore.EXTRA_OUTPUT,uri);

同样使用startActivityForResult方法跳转

onActivityResult:

FileInputStream fileInputStream = null;
Bitmap output;
try {
     int degree = PhotoUtil.readPictureDegree(path);
     fileInputStream = new FileInputStream(new File(path));
     output = BitmapFactory.decodeStream(fileInputStream);                   
    showImage.setImageBitmap(PhotoUtil.rotaingImageView(degree,output));
} catch (FileNotFoundException e) {
     e.printStackTrace();
}finally {
     if (fileInputStream != null){
     try {
          fileInputStream.close();
         } catch (IOException e) {
               e.printStackTrace();
         }
     }
}

其实拿到这个需要一下两句话就能拿到这个bitmap

fileInputStream = new FileInputStream(new File(path));
output = BitmapFactory.decodeStream(fileInputStream);

但是保存在本地的图片,直接这样取得的照片旋转了90度,其中图片的旋转角度是记录在exif中的,所以为了把图片旋转过来,索性直接利用exif去取角度

/**
     * 读取图片属性:旋转的角度
     * @param path 图片绝对路径
     * @return degree旋转的角度
     */
    public static int readPictureDegree(String path) {
        int degree  = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

然后根据取到的角度旋转bitmap

public static Bitmap rotaingImageView(int angle , Bitmap bitmap) {
        Matrix matrix = new Matrix();
        matrix.postRotate(angle);
        Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        return resizedBitmap;
    }

对于图片的操作后面再说

这样就能实现获得原图,并且能够正向的显示图片,但是很多app不只是拍一张照片而已,所以下面开始介绍自定义Camera

package com.zimo.guo.customcamera.view;

import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.os.Environment;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * Created by zimo on 15/12/27.
 */
public class CameraView extends SurfaceView implements SurfaceHolder.Callback {

    private Camera camera;
    private SurfaceHolder holder;
    private Context context;
    private String picUrl;

    public CameraView(Context context) {
        super(context);
        this.context = context;
        initHolder();
    }

    public CameraView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        initHolder();
    }

    public CameraView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        initHolder();
    }

    private void initHolder() {
        holder = this.getHolder();
        holder.addCallback(this);
    }

    private boolean existCamera(Context context) {
        return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
    }

    /**
     * 初始化相机
     */
    private void initCamera() {
        if (camera == null) {
            camera = Camera.open();
        }
    }

    private void imagePreview(SurfaceHolder holder) {
        try {
            if (camera != null) {
                camera.setPreviewDisplay(holder);
                camera.setDisplayOrientation(90);
                camera.startPreview();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private void setParameters() {
        if (camera != null) {
            Camera.Parameters parameters = camera.getParameters();
            parameters.setPictureFormat(ImageFormat.JPEG);
//            parameters.setRotation(90);
            parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
            camera.setParameters(parameters);
        }
    }

    private void releaseCamera() {
        if (camera != null) {
            camera.setPreviewCallback(null);
            camera.stopPreview();
            camera.release();
            camera = null;
        }
    }

    public void autoFocus(){
        if (camera != null){
            camera.autoFocus(new Camera.AutoFocusCallback() {
                @Override
                public void onAutoFocus(boolean success, Camera camera) {
                    if (success){
                        takePicture();
                    }
                }
            });
        }
    }

    public void takePicture(){
        if (camera != null){
            camera.takePicture(null, null, new Camera.PictureCallback() {
                @Override
                public void onPictureTaken(byte[] data, Camera camera) {
                    if (picUrl == null) {
                        picUrl = Environment.getExternalStorageDirectory() + File.separator + "zimo.jpg";
                    }
                    File file = new File(picUrl);
                    if (file.exists()) {
                        file.delete();
                    }
                    try {
                        FileOutputStream fos = new FileOutputStream(file);
                        fos.write(data);
                        fos.close();
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    imagePreview(holder);
                }
            });
        }

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if (existCamera(context)){
            initCamera();
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        setParameters();
        imagePreview(holder);
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        releaseCamera();
    }

    public void setPicUrl(String picUrl) {
        this.picUrl = picUrl;
    }
}

上面是一个自定义的Camera,继承了SurfaceView

  1. 检查Camera是否存在
  2. 初始化Camera
  3. 设置参数
  4. 预览图片
  5. 拍照
  6. 释放Camera

这就是自定义Camera实现的步骤了,当然还有增加权限

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

只要把CameraView当成自定义控件使用就好

<com.zimo.guo.customcamera.view.CameraView
        android:id="@+id/camera"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

点击拍照按钮直接调用takePicture(),当然也可以自己定义图片地址

cameraView.setPicUrl(path);
cameraView.takePicture();

还可以实现聚焦之后自动拍照

cameraView.autoFocus();


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在风能领域,准确预测风速对于风电场的运行与管理至关重要。Matlab作为一个强大的数学计算和数据分析平台,被广泛应用于风速预测模型的构建。本文将深入探讨基于四种风速——随机风、基本风、阵风和渐变风的组合风速预测技术。 我们来理解这四种风速类型: 1. **随机风**:随机风是指风速呈现出随机性的变化,通常由大气湍流引起。在建模中,通常通过统计方法如高斯分布或Weibull分布来模拟这种不确定性。 2. **基本风**:基本风速是指在无特定扰动条件下的平均风速,它是长期观测结果的平均值,通常用于结构设计和风能评估。 3. **阵风**:阵风是短时间内风速显著增强的现象,对建筑物和风力发电机造成的主要威胁之一。阵风的预测涉及到风的脉动特性分析。 4. **渐变风**:渐变风是指风速随时间和空间逐渐变化的过程,常见于风向转变或地形影响下的风场变化。 在Matlab中,利用这四种风速类型进行组合预测,可以提高预测的准确性。预测模型可能包括以下几个步骤: 1. **数据收集与预处理**:收集历史风速数据,包括随机风、基本风、阵风和渐变风的数据,进行异常值检测、缺失值填充以及数据标准化。 2. **特征工程**:提取风速变化的相关特征,如平均值、标准差、极值、频率分布等,这些特征可能对预测有重要影响。 3. **模型选择**:可以选择多种预测模型,如时间序列分析(ARIMA、状态空间模型等)、机器学习算法(线性回归、决策树、支持向量机、神经网络等)或深度学习模型(LSTM、GRU等)。 4. **模型训练**:利用历史数据训练选定的模型,调整模型参数以优化性能,例如通过交叉验证来避免过拟合。 5. **模型验证与评估**:使用独立的测试集验证模型预测效果,常见的评估指标有均方误差(MSE)、平均绝对误差(MAE)和决定系数(R²)。 6. **组合预测**:结合四种风速的不同模型预测结果,可以采用加权平均、集成学习(如bagging、boosting)等方式,以提升整体预测精度。 7. **实时更新与动态调整**:实际应用中,模型需要不断接收新的风速数据并进行在线更新,以适应风场环境的变化。 通过以上步骤,可以构建一个综合考虑各种风速特性的预测系统,这对于风电场的功率输出预测、风电设备的维护计划以及电网调度都具有重要价值。然而,需要注意的是,每个风场的地理环境、气候条件和设备状况都有所不同,因此模型的建立应根据实际情况进行定制和优
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值