Android移动开发-调用摄像头进行拍照的实现

2023-11-10

现在Android智能手机的像素都会提供照相的功能,大部分的手机的摄像头的像素都在1000万以上的像素,有的甚至会更高。它们大多都会支持光学变焦、曝光以及快门等等。

下面的程序Demo实例示范了使用Camera v2来进行拍照,当用户按下拍照键时,该应用会自动对焦,当对焦成功时拍下照片。

  • layout/activity_main.xml界面布局代码如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.fukaimei.camerav2test">

    <!-- 授予该程序使用摄像头的权限 -->
    <uses-permission android:name="android.permission.CAMERA" />

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

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

</manifest>

上面的程序的界面提供了一个自定义TextureView来显示预览取景,十分简单。该自定义TextureView类的代码如下:

  • AutoFitTextureView.java逻辑代码如下:
package com.fukaimei.camerav2test;

import android.content.Context;
import android.util.AttributeSet;
import android.view.TextureView;

/**
 * Created by FuKaimei on 2017/9/29.
 */

public class AutoFitTextureView extends TextureView {

    private int mRatioWidth = 0;
    private int mRatioHeight = 0;

    public AutoFitTextureView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setAspectRatio(int width, int height) {
        mRatioWidth = width;
        mRatioHeight = height;
        requestLayout();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        if (0 == mRatioWidth || 0 == mRatioHeight) {
            setMeasuredDimension(width, height);
        } else {
            if (width < height * mRatioWidth / mRatioHeight) {
                setMeasuredDimension(width, width * mRatioHeight / mRatioWidth);
            } else {
                setMeasuredDimension(height * mRatioWidth / mRatioHeight, height);
            }
        }
    }
}

接来了的MainActivity.java程序将会使用CameraManager来打开CameraDevice,并通过CameraDevice创建CameraCaptureSession,然后即可通过CameraCaptureSession进行预览或拍照了。

  • MainActivity.java逻辑代码如下:
package com.fukaimei.camerav2test;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.Image;
import android.media.ImageReader;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
import android.util.Size;
import android.util.SparseIntArray;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.widget.Toast;

import java.io.File;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class MainActivity extends Activity implements View.OnClickListener {

    private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
    private static final String TAG = "MainActivity";

    static {
        ORIENTATIONS.append(Surface.ROTATION_0, 90);
        ORIENTATIONS.append(Surface.ROTATION_90, 0);
        ORIENTATIONS.append(Surface.ROTATION_180, 270);
        ORIENTATIONS.append(Surface.ROTATION_270, 180);
    }

    private AutoFitTextureView textureView;
    // 摄像头ID(通常0代表后置摄像头,1代表前置摄像头)
    private String mCameraId = "0";
    // 定义代表摄像头的成员变量
    private CameraDevice cameraDevice;
    // 预览尺寸
    private Size previewSize;
    private CaptureRequest.Builder previewRequestBuilder;
    // 定义用于预览照片的捕获请求
    private CaptureRequest previewRequest;
    // 定义CameraCaptureSession成员变量
    private CameraCaptureSession captureSession;
    private ImageReader imageReader;
    private final TextureView.SurfaceTextureListener mSurfaceTextureListener
            = new TextureView.SurfaceTextureListener() {
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture texture
                , int width, int height) {
            // 当TextureView可用时,打开摄像头
            openCamera(width, height);
        }

        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture texture
                , int width, int height) {
        }

        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {
            return true;
        }

        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture texture) {
        }
    };
    private final CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
        //  摄像头被打开时激发该方法
        @Override
        public void onOpened(CameraDevice cameraDevice) {
            MainActivity.this.cameraDevice = cameraDevice;
            // 开始预览
            createCameraPreviewSession();  // ②
        }

        // 摄像头断开连接时激发该方法
        @Override
        public void onDisconnected(CameraDevice cameraDevice) {
            cameraDevice.close();
            MainActivity.this.cameraDevice = null;
        }

        // 打开摄像头出现错误时激发该方法
        @Override
        public void onError(CameraDevice cameraDevice, int error) {
            cameraDevice.close();
            MainActivity.this.cameraDevice = null;
            MainActivity.this.finish();
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textureView = (AutoFitTextureView) findViewById(R.id.texture);
        // 为该组件设置监听器
        textureView.setSurfaceTextureListener(mSurfaceTextureListener);
        findViewById(R.id.capture).setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        captureStillPicture();
    }

    private void captureStillPicture() {
        try {
            if (cameraDevice == null) {
                return;
            }
            // 创建作为拍照的CaptureRequest.Builder
            final CaptureRequest.Builder captureRequestBuilder =
                    cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
            // 将imageReader的surface作为CaptureRequest.Builder的目标
            captureRequestBuilder.addTarget(imageReader.getSurface());
            // 设置自动对焦模式
            captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                    CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
            // 设置自动曝光模式
            captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                    CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
            // 获取设备方向
            int rotation = getWindowManager().getDefaultDisplay().getRotation();
            // 根据设备方向计算设置照片的方向
            captureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION
                    , ORIENTATIONS.get(rotation));
            // 停止连续取景
            captureSession.stopRepeating();
            // 捕获静态图像
            captureSession.capture(captureRequestBuilder.build()
                    , new CameraCaptureSession.CaptureCallback()  // ⑤
                    {
                        // 拍照完成时激发该方法
                        @Override
                        public void onCaptureCompleted(CameraCaptureSession session
                                , CaptureRequest request, TotalCaptureResult result) {
                            try {
                                // 重设自动对焦模式
                                previewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
                                        CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
                                // 设置自动曝光模式
                                previewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                                        CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
                                // 打开连续取景模式
                                captureSession.setRepeatingRequest(previewRequest, null,
                                        null);
                            } catch (CameraAccessException e) {
                                e.printStackTrace();
                            }
                        }
                    }, null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    // 打开摄像头
    private void openCamera(int width, int height) {
        setUpCameraOutputs(width, height);
        CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        try {
            // 打开摄像头
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                // TODO: Consider calling
                //    ActivityCompat#requestPermissions
                // here to request the missing permissions, and then overriding
                //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                //                                          int[] grantResults)
                // to handle the case where the user grants the permission. See the documentation
                // for ActivityCompat#requestPermissions for more details.
                return;
            }
            manager.openCamera(mCameraId, stateCallback, null); // ①
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    private void createCameraPreviewSession() {
        try {
            SurfaceTexture texture = textureView.getSurfaceTexture();
            texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
            Surface surface = new Surface(texture);
            // 创建作为预览的CaptureRequest.Builder
            previewRequestBuilder = cameraDevice
                    .createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            // 将textureView的surface作为CaptureRequest.Builder的目标
            previewRequestBuilder.addTarget(new Surface(texture));
            // 创建CameraCaptureSession,该对象负责管理处理预览请求和拍照请求
            cameraDevice.createCaptureSession(Arrays.asList(surface
                    , imageReader.getSurface()), new CameraCaptureSession.StateCallback() // ③
                    {
                        @Override
                        public void onConfigured(CameraCaptureSession cameraCaptureSession) {
                            // 如果摄像头为null,直接结束方法
                            if (null == cameraDevice) {
                                return;
                            }

                            // 当摄像头已经准备好时,开始显示预览
                            captureSession = cameraCaptureSession;
                            try {
                                // 设置自动对焦模式
                                previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                                        CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
                                // 设置自动曝光模式
                                previewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                                        CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
                                // 开始显示相机预览
                                previewRequest = previewRequestBuilder.build();
                                // 设置预览时连续捕获图像数据
                                captureSession.setRepeatingRequest(previewRequest,
                                        null, null);  // ④
                            } catch (CameraAccessException e) {
                                e.printStackTrace();
                            }
                        }

                        @Override
                        public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
                            Toast.makeText(MainActivity.this, "配置失败!"
                                    , Toast.LENGTH_SHORT).show();
                        }
                    }, null
            );
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    private void setUpCameraOutputs(int width, int height) {
        CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        try {
            // 获取指定摄像头的特性
            CameraCharacteristics characteristics
                    = manager.getCameraCharacteristics(mCameraId);
            // 获取摄像头支持的配置属性
            StreamConfigurationMap map = characteristics.get(
                    CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);

            // 获取摄像头支持的最大尺寸
            Size largest = Collections.max(
                    Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)),
                    new CompareSizesByArea());
            // 创建一个ImageReader对象,用于获取摄像头的图像数据
            imageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(),
                    ImageFormat.JPEG, 2);
            imageReader.setOnImageAvailableListener(
                    new ImageReader.OnImageAvailableListener() {
                        // 当照片数据可用时激发该方法
                        @Override
                        public void onImageAvailable(ImageReader reader) {
                            // 获取捕获的照片数据
                            Image image = reader.acquireNextImage();
                            ByteBuffer buffer = image.getPlanes()[0].getBuffer();
                            byte[] bytes = new byte[buffer.remaining()];
                            // 使用IO流将照片写入指定文件
                            File file = new File(getExternalFilesDir(null), "pic.jpg");
                            buffer.get(bytes);
                            try (
                                    FileOutputStream output = new FileOutputStream(file)) {
                                output.write(bytes);
                                Toast.makeText(MainActivity.this, "保存: " + file, Toast.LENGTH_LONG).show();
                            } catch (Exception e) {
                                e.printStackTrace();
                            } finally {
                                image.close();
                            }
                        }
                    }, null);

            // 获取最佳的预览尺寸
            previewSize = chooseOptimalSize(map.getOutputSizes(
                    SurfaceTexture.class), width, height, largest);
            // 根据选中的预览尺寸来调整预览组件(TextureView的)的长宽比
            int orientation = getResources().getConfiguration().orientation;
            if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
                textureView.setAspectRatio(
                        previewSize.getWidth(), previewSize.getHeight());
            } else {
                textureView.setAspectRatio(
                        previewSize.getHeight(), previewSize.getWidth());
            }
        } catch (CameraAccessException e) {
            e.printStackTrace();
        } catch (NullPointerException e) {
            Log.d(TAG, "出现错误");
        }
    }

    private static Size chooseOptimalSize(Size[] choices
            , int width, int height, Size aspectRatio) {
        // 收集摄像头支持的打过预览Surface的分辨率
        List<Size> bigEnough = new ArrayList<>();
        int w = aspectRatio.getWidth();
        int h = aspectRatio.getHeight();
        for (Size option : choices) {
            if (option.getHeight() == option.getWidth() * h / w &&
                    option.getWidth() >= width && option.getHeight() >= height) {
                bigEnough.add(option);
            }
        }
        // 如果找到多个预览尺寸,获取其中面积最小的。
        if (bigEnough.size() > 0) {
            return Collections.min(bigEnough, new CompareSizesByArea());
        } else {
            System.out.println("找不到合适的预览尺寸!!!");
            return choices[0];
        }
    }

    // 为Size定义一个比较器Comparator
    static class CompareSizesByArea implements Comparator<Size> {
        @Override
        public int compare(Size lhs, Size rhs) {
            // 强转为long保证不会发生溢出
            return Long.signum((long) lhs.getWidth() * lhs.getHeight() -
                    (long) rhs.getWidth() * rhs.getHeight());
        }
    }
}

上面的程序中序号①的代码是用于打开系统摄像头,openCamera()方法的第一个参数代表请求打开的摄像头ID,此处传入的摄像头ID为“0”,这代表打开设备后置摄像头;如果需要打开设备指定摄像头(比如前置摄像头),可以在调用openCamera()方法时传入相应的摄像头ID。

  • 注意:由于该程序需要使用手机的摄像头,因此还需要在清单文件AndroidManifest.xml文件中授权相应的权限:
<!-- 授予该程序使用摄像头的权限 -->
    <uses-permission android:name="android.permission.CAMERA" />
  • Demo程序运行效果界面截图如下:
    这里写图片描述
    ———————— The end ————————

如果您觉得这篇博客写的比较好的话,赞赏一杯咖啡吧~~
在这里插入图片描述


Demo程序源码下载地址

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android移动开发-调用摄像头进行拍照的实现 的相关文章

  • 已发布的 Flutter 应用程序在启动时崩溃

    编辑 此问题的解决方案是将您的 flutter 版本升级到较新的 dev 版本 then 1 7 0 您还可以上传单独的 APK 版本 但我个人不喜欢这个选项 请确保您没有从 flutter github 开发存储库下载 错误的构建 因为那
  • 关闭 Android 中的飞行模式

    如果 num gt 50 我想关闭飞行模式 我实现了这段代码 来自在 Android 中切换飞行模式 https stackoverflow com questions 5533881 toggle airplane mode in and
  • 是否可以使用最新的 APP_PLATFORM,同时仍保持向后兼容性?

    这是我的 Application mk APP ABI armeabi v7a APP PLATFORM android 16 APP OPTIM release APP STL gnustl static APP CPPFLAGS std
  • Android中如何使用洪水填充算法?

    我是Android编程新手 最近尝试编写一个简单的应用程序 仅供练习 在这个中 我想在用户点击时为图像着色 但我不知道如何开始 我读过不同的主题 其中提到使用 洪水填充 算法 我在网上找到了它 但我不知道如何将它放入我的简单应用程序中 我找
  • AppCompat v21 工具栏更改徽标大小

    我正在从以前的操作栏迁移到 appcompat v21 中的新工具栏功能 我仍然想将徽标保留在操作栏 工具栏 的左上角 为此 我在布局中添加了支持工具栏 并为其创建了一个新的工具栏 app theme style NewToolBarSty
  • Android ListView setSelection() 似乎不起作用

    我有一个ListActivity实现onListItemClick 并调用doSomething 类的功能 后者包含l setSelection position where l is the ListView object 现在有一个on
  • Android GCM 服务器的 API 密钥

    我有点困惑我应该为 GCM 服务器使用哪个 API 密钥 在文档中它说使用 android api 密钥 这对我不起作用并且总是给出未经授权的 http developer android com google gcm gs html ht
  • 加快 ImageView 中的缩放功能

    我目前正在处理非常大的图像 7 10mb 由于多种原因无法调整大小或压缩 现在 我们的想法是在自定义 ImageView 中显示它们 使用户能够进行双击缩放 捏合缩放等 我使用这个库来完成这项工作 https github com Mike
  • Ionic Facebook Api 无效密钥哈希

    我无法让我的应用程序允许 Facebook 登录 每次用户尝试登录 Facebook 并使用他们的 FB 验证我的应用程序时 都会出现以下错误 无效的密钥哈希 它们的密钥哈希 xxxxxxxxxx 与任何存储的密钥哈希不匹配 配置您的应用程
  • 使用嵌套的 hashmap 参数发送 volley 请求

    我正在使用 android volley 框架向我的服务器发送 jsonobject 请求 get 请求工作正常 现在我想发送一个带有请求参数的 post 请求 该请求参数是嵌套的 hashmap 我重写 getparams 方法 但它期望
  • 检测 ListView(或 ScrollView)内的滚动位置

    我正在构建一个聊天室应用程序 其中每 X 秒就会轮询一次新事件 每次发生这种情况时 此代码都会使用新数据更新 RoomAdapter ArrayAdapter 的自定义子类 并将其滚动到底部 RoomAdapter adapter Room
  • Android - iphone 风格 tabhost [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • “无法实例化活动”错误

    我的一个 Android 应用程序拥有大约 100 000 个用户 每周大约 10 次 我会通过 Google 的市场工具向我报告以下异常情况 java lang RuntimeException Unable to instantiate
  • 在 Android 布局 xml 文件中使用字符串格式参数 [重复]

    这个问题在这里已经有答案了 我在 String xml 文件中定义了一个使用格式参数的字符串 即
  • Android 中的 Google Places API - 适用于个人用户的 API_KEY

    我已经浏览了与在 Android 应用程序中使用 Places API 相关的 Android 文档和其他博客 到处都建议使用 API KEY 来调用 REST 服务 API KEY 在整个项目 应用程序中都是相同的 每天的请求数限制为 1
  • 在状态栏下方显示DialogFragment内容

    我试图显示高度和宽度均具有 match parent 的 DialogFragment 但碰巧在顶部 DialogFragment 显示在 StatusBar 下方 DialogFragment 正在应用一些默认值来填充底部 右侧 左侧和顶
  • 具有矢量可绘制的 ImageView 的 Resources$NotFoundException

    我遇到了崩溃 Resources NotFoundException用于在活动创建时绘制的矢量 21 日前崩溃 安卓工作室2 1 支持库24 0 0 Gradle插件2 1 0 目标SDK 23 最小SDK 15 buildTools版本
  • Android ADT Eclipse 插件,parseSDKContent 失败

    我刚刚设置了我的第一个 Android 开发环境 其中包括 日食3 5 Mac OS X 10 5 适用于 x86 mac 的 Android SDK ADT Eclipse 插件 0 9 6 我已将 set PATH 设置为我的 SDK
  • putFragment() - 片段 x 当前不在 FragmentManager 中

    上面的标题被问了很多次 但答案似乎与FragmentStatePagerAdapter这与我的问题无关 我正在使用该方法putFragment Bundle String Fragment 直接地 The 安卓文档 http develop
  • 异步更新后更新Android Listview

    我正在将 HTTP 调用从同步调用转换为异步调用 由于连接在后台运行 因此当我最初设置列表适配器时 数据不存在 如何在 HTTP 调用后更新列表适配器 我尝试了一些方法 例如在数据发送回之前不设置适配器并再次设置适配器 但没有任何效果 这是

随机推荐

  • springMVC接收ajaxfileupload提交数据不执行success回调的问题解决

    采用ajaxfileupload插件提交表单 前端js写法如下 ajaxFileUpload url base submit ajaxfileupload do secureuri false fileElementId uploadFil
  • 正版方舟建服务器,搭建ARK服务器

    Loading 参考文章 CentOS 7 x 快速搭建ARK服务器 1 更新系统 yum update y 安装窗口会话工具 可以让你在退出ssh后保留当前运行的服务端 已安装或有其他工具的请跳过 yum install screen 安
  • ❀OSPF协议面试题总结❀

    文章目录 一 简单介绍下ospf 二 ospf的骨干区域有什么用 为什么要划分一个骨干区域 三 ospf的状态机 四 ospf的lsa有几种 五 ospf路由的生成过程 六 介绍ospf的虚链路 一 简单介绍下ospf 开放式最短路径优先协
  • 力扣2594.修车的最少时间

    题目描述 给你一个整数数组 ranks 表示一些机械工的 能力值 ranksi 是第 i 位机械工的能力值 能力值为 r 的机械工可以在 r n2 分钟内修好 n 辆车 同时给你一个整数 cars 表示总共需要修理的汽车数目 请你返回修理所
  • Android ApiDemos示例解析(87):Media->MediaPlayer

    本例介绍了如何使用MediaPlayer类来播放声音或是视频 涉及的Activity有三个 MediaPlayerDemo 主Activity 显示示例列表 MediaPlayerDemo Audio 子Activity 用于播放声音 在L
  • ConcurrentHashMap1.8总结

    Java8 ConcurrentHashMap结构基本上和Java8的HashMap一样 不过保证线程安全性 在JDK8中ConcurrentHashMap的结构 由于引入了红黑树 使得ConcurrentHashMap的实现非常复杂 我们
  • FPGA学习专栏-串口通信(xinlinx)

    FPGA学习专栏 串口通信 本系列文章基于开发板黑金A309 FPGA芯片为Xilinx公司的spartan6 本系列文章记录FPGA学习历程 文章目录 FPGA学习专栏 串口通信 一 串口通信原理 二 硬件设计 三 verilog代码编写
  • react之装饰器报错:This experimental syntax requires enabling one of the following parser plugin(s): “decor

    在学习mobx时 遇到了 This experimental syntax requires enabling one of the following parser plugin s decorators decorators legac
  • STM32F103ZET6【标准库函数开发】------17 DMA实验

    STM32F103ZET6有2个DMA控制器 DMA1有7个通道 DMA2有5个通道 各个通道对应的外设如下
  • Caused by: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed解决方法

    前言 Android Studio 升级到最新版本后 构建项目时 构建失败 出现错误 Caused by org codehaus groovy control MultipleCompilationErrorsException star
  • MySQL的null与not null

    相信很多用了mysql很久的人 对这两个字段属性的概念还不是很清楚 一般会有以下疑问 我字段类型是not null 为什么我可以插入空值 为毛not null的效率比null高 判断字段不为空的时候 到底要 select from tabl
  • IDEA报错:Cannot start compilation: the output path is not specified for module “testSvnKit“.Specify th

    IDEA报错Cannot start compilation the output path is not specified for module testSvnKit Specify the output path in the Pro
  • List分组的两种方式

    java8之前List分组 假设有个student类 有id name score属性 list集合中存放所有学生信息 现在要根据学生姓名进行分组 public Map
  • 精确径向基(matlab工具箱)

    原文地址 精确径向基 matlab工具箱 作者 神经网络之家 作者 梁小h 日期 2015 10 26 09 30 47 0 lt 文档仅供查阅和简单了解 深入了解请关注神经网络之家发布的 神经网络教学视频 gt 精确径向基神经网络在mat
  • HTML详解连载(5)

    HTML详解连载 5 专栏链接 link http t csdn cn xF0H3 下面进行专栏介绍 开始喽 行高 设置多行文本的间距 属性名 属性值 行高的测量方法 行高 垂直居中 技巧 字体族 属性名 属性值 示例 扩展 font 复合
  • 学期总结-2018年上

    从现在开始 我需要养成一个写作的好习惯 之所以培养这个习惯 是因为 我开始发现我的一个重大缺陷 语言表达能力的欠缺 这种能力 在一般生活中并不会有太大的作用 而且很多时候 大部分人都体会不到其所带来的 破坏 这种破坏 会让你的交际陷入阻塞
  • 不能向服务器考文件,如何往云服务器考文件

    如何往云服务器考文件 内容精选 换一换 华为云帮助中心 为用户提供产品简介 价格说明 购买指南 用户指南 API参考 最佳实践 常见问题 视频帮助等技术文档 帮助您快速上手使用华为云服务 无法正常使用Cloud init 弹性云服务器获取M
  • 关于python爬虫逆向RPC的基础使用

    makeRequest function a b c d rpc使用的代码 function 防止重复创建websocket if window flagLX else window weiboLX makeRequest var ws n
  • egg初始化搭建swagger项目

    步骤 安装node 安装你喜欢的编辑器 初始化项目 输入安装 egg 命令 输入安装 egg dev 命令 修改 package json 基本目录结构 需手动创建 输入安装 egg sequelize 命令 数据库选择 配置 sequel
  • Android移动开发-调用摄像头进行拍照的实现

    现在Android智能手机的像素都会提供照相的功能 大部分的手机的摄像头的像素都在1000万以上的像素 有的甚至会更高 它们大多都会支持光学变焦 曝光以及快门等等 下面的程序Demo实例示范了使用Camera v2来进行拍照 当用户按下拍照