android相机预览拍照功能实现
代码目录结构
LAUNCHER activity:CameraActivity :
onCreate()方法中创建Camera工具类CameraHelper的实例并初始化:
mCameraHelper = new CameraHelper(mActivity, textureView, btnImagePreview);
重写onClick方法监听拍照点击事件:
mCameraHelper.takePicture();
CameraHelper类中实现相机的预览与拍照,流程如下:
大致流程如下:
- 用CameraManager的openCamera(String cameraId, CameraDevice.StateCallback callback, Handler handler)方法打开指定摄像头。该方法的第一个参数代表要打开的摄像头ID;第二个参数用于监听摄像头的状态;第三个参数代表执行callback的Handler,如果程序希望直接在当前线程中执行callback,则可将handler参数设为null。
- 当摄像头被打开之后会回调接口mStateCallback.onOpened,程序即可获取CameraDevice —— 即根据摄像头ID获取了指定摄像头设备,然后调用CameraDevice的createCaptureSession(List outputs, CameraCaptureSession. StateCallback callback,Handler handler)方法来创建CameraCaptureSession。该方法的第一个参数是一个List集合,封装了所有需要从该摄像头获取图片的Surface,第二个参数用于监听CameraCaptureSession的创建过程;第三个参数代表执行callback的Handler,如果程序希望直接在当前线程中执行callback,则可将handler参数设为null。
- 不管预览还是拍照,程序都调用CameraDevice的createCaptureRequest(int templateType)方法创建CaptureRequest.Builder,该方法支持TEMPLATE_PREVIEW(预览)、TEMPLATE_RECORD(拍摄视频)、TEMPLATE_STILL_CAPTURE(拍照)等参数。
- 通过第3步所调用方法返回的CaptureRequest.Builder设置拍照的各种参数,比如对焦模式、曝光模式等。
- 调用CaptureRequest.Builder的build()方法即可得到CaptureRequest对象,接下来程序可通过CameraCaptureSession的setRepeatingRequest()方法开始预览,或调用capture()方法拍照。
相机的预览与拍照流程我们基本了解了。
- 调用CaptureRequest.Builder的build()方法即可得到CaptureRequest对象,接下来程序可通过CameraCaptureSession的setRepeatingRequest()方法开始预览,或调用capture()方法拍照。
- 预览时,是将mSurfaceHolder.getSurface()作为目标,使用setRepeatingRequest()方法,
显示拍照结果时,是将mImageReader.getSurface()作为目标,使用capture()方法
- 预览时,是将mSurfaceHolder.getSurface()作为目标,使用setRepeatingRequest()方法,
layout布局如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/relativeLayout"android:orientation="vertical"android:background="#000"><ImageViewandroid:id="@+id/imageView"android:layout_width="match_parent"android:layout_height="112dp"android:background="@color/black"/><LinearLayoutandroid:id="@+id/linearLayout"android:layout_width="match_parent"android:layout_height="208dp"android:layout_alignParentBottom="true"android:orientation="vertical"><com.bilibili.camera2.view.SideBarandroid:id="@+id/sideBar"android:layout_width="300dp"android:layout_height="60dp"android:visibility="gone"android:layout_marginTop="10dp"android:layout_gravity="center_horizontal"/><com.bilibili.camera2.view.HorizontalSelectedViewandroid:id="@+id/selectedView"android:layout_width="match_parent"android:layout_marginTop="10dp"android:layout_height="60dp"android:layout_gravity="center_horizontal"app:HorizontalSelectedViewSeeSize="5"android:visibility="visible"app:HorizontalSelectedViewSelectedTextColor="@color/white"app:HorizontalSelectedViewSelectedTextSize="40"app:HorizontalSelectedViewTextColor="@color/gray"app:HorizontalSelectedViewTextSize="30" /><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><!-- 拍照按钮 --><ImageButtonandroid:id="@+id/btnTakePicture"android:layout_width="80dp"android:layout_height="80dp"android:layout_centerHorizontal="true"android:background="@drawable/ic_camera_main_btn_01_auto"android:layout_gravity="center"tools:ignore="ContentDescription" /><ImageViewandroid:id="@+id/faceBackCameraChange"android:layout_width="70dp"android:layout_height="70dp"android:layout_marginStart="280dp"android:layout_centerVertical="true"android:background="@drawable/ic_camera_main_btn_02_switch"android:clickable="true"tools:ignore="ContentDescription" /></RelativeLayout></LinearLayout><LinearLayoutandroid:id="@+id/linearLayoutBottom"android:layout_width="match_parent"android:layout_height="48dp"android:background="@color/black"android:layout_alignParentBottom="true"android:orientation="horizontal" /></RelativeLayout>
CameraHelper主要逻辑代码如下:
class CameraHelper {private final Activity mActivity;private final TextureView mTextureView;private static final String TAG = "CameraHelper";private static final int PREVIEW_WIDTH = 1080; //预览的宽度private static final int PREVIEW_HEIGHT = 2340; //预览的高度private static final int SAVE_WIDTH = 1080; //保存图片的宽度private static final int SAVE_HEIGHT = 23400; //保存图片的高度private static final int PREVIEW_FIRST_GET_IMAGE = 0;private CameraManager mCameraManager;private ImageReader mImageReader;private CameraDevice mCameraDevice;private CameraCaptureSession mCameraCaptureSession;private CircleImageView imageButton;private String mCameraId = "0";private CameraCharacteristics mCameraCharacteristics;private int mCameraSensorOrientation = 0; //摄像头方向private int mCameraFacing = CameraCharacteristics.LENS_FACING_BACK; //默认使用后置摄像头//private int mDisplayRotation = mActivity.getWindowManager().getDefaultDisplay().getRotation(); //手机方向private boolean canTakePicture = true; //是否可以拍照private boolean canExchangeCamera = false; //是否可以切换摄像头private Handler mCameraHandler;private HandlerThread handlerThread = new HandlerThread("CameraThread");private Size mPreviewSize = new Size(PREVIEW_WIDTH, PREVIEW_HEIGHT); //预览大小private Size mSavePicSize = new Size(SAVE_WIDTH, SAVE_HEIGHT); //保存图片大小private CoordinateTransformer mTransformer;private int i = 0;public CameraHelper(Activity mActivity, TextureView mTextureView, CircleImageView imageButton) {this.mActivity = mActivity;this.mTextureView = mTextureView;this.imageButton = imageButton;init();}private void init() {handlerThread.start();mCameraHandler = new Handler(Looper.myLooper());mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {@Overridepublic void onSurfaceTextureAvailable(@NonNull SurfaceTexture surface, int width, int height) {initCameraInfo();}@Overridepublic boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) {releaseCamera();return true;}@Overridepublic void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surface, int width, int height) {}@Overridepublic void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {}});}public CameraDevice getCameraDevice(){Log.d(TAG, "getCameraDevice: mCameraDevice : " + mCameraDevice);return mCameraDevice;}public void releaseCamera() {if (mCameraCaptureSession != null) {mCameraCaptureSession.close();mCameraCaptureSession = null;}if (mCameraDevice != null){mCameraDevice.close();mCameraDevice = null;}if (mImageReader != null){mImageReader.close();mImageReader = null;}canExchangeCamera = false;}public void releaseThread() {handlerThread.quitSafely();mCameraHandler = null;}/*** 拍照*/public void takePicture(){Log.i(TAG, "takePicture: 进行拍照 1");if (mCameraDevice == null || !canTakePicture || ! mTextureView.isAvailable()) {Log.d(TAG, "takePicture: 进行拍照 error 退出");return;}try {CaptureRequest.Builder captureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);captureBuilder.addTarget(mImageReader.getSurface());captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);captureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, mCameraSensorOrientation);mCameraCaptureSession.capture(captureBuilder.build(),null, mCameraHandler);Thread.sleep(200);Log.i(TAG, "takePicture: picture capture finish");} catch (CameraAccessException | InterruptedException e) {e.printStackTrace();}}/*** 切换摄像头*/public void exchangeCamera(){if (mCameraDevice == null || !canExchangeCamera || !mTextureView.isAvailable()) return;mCameraFacing = (mCameraFacing == CameraCharacteristics.LENS_FACING_FRONT)? CameraCharacteristics.LENS_FACING_BACK : CameraCharacteristics.LENS_FACING_FRONT;mPreviewSize = new Size(PREVIEW_WIDTH, PREVIEW_HEIGHT); //重置预览大小releaseCamera();initCameraInfo();}/*** 初始化*/@SuppressLint("ShowToast")private void initCameraInfo() {try {mCameraManager = (CameraManager) mActivity.getSystemService(Context.CAMERA_SERVICE);String[] cameraIdList = mCameraManager.getCameraIdList();if (cameraIdList == null) {Toast.makeText(mActivity, "没有相机可用", Toast.LENGTH_SHORT);return;}for (String id : cameraIdList) {CameraCharacteristics cameraCharacteristics = mCameraManager.getCameraCharacteristics(id);//+Type add focusRectF mPreviewRect = new RectF(0,0,1080, 1440);mTransformer = new CoordinateTransformer(cameraCharacteristics, mPreviewRect);Rect mFocusRect = new Rect();RectF rectF = mTransformer.toCameraSpace(mPreviewRect);mFocusRect.left = Math.round(rectF.left);mFocusRect.top = Math.round(rectF.top);mFocusRect.right = Math.round(rectF.right);mFocusRect.bottom = Math.round(rectF.bottom);//MeteringRectangle meteringRectangle = new MeteringRectangle(mFocusRect,1000);//-Type add focusInteger facing = cameraCharacteristics.get(CameraCharacteristics.LENS_FACING);if (facing == mCameraFacing) {mCameraId = id;mCameraCharacteristics = cameraCharacteristics;}Log.i(TAG, "initCameraInfo: 设备中的摄像头: " + id);}Integer supportLevel = mCameraCharacteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);if (supportLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {Toast.makeText(mActivity, "相机硬件不支持新特性", Toast.LENGTH_SHORT);}//获取摄像头方向mCameraSensorOrientation = mCameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);//获取StreamConfigurationMap,它是管理摄像头支持的所有输出格式和尺寸StreamConfigurationMap configurationMap = mCameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);Size[] savePicSizes = configurationMap.getOutputSizes(ImageFormat.JPEG); //保存照片尺寸if (savePicSizes == null) {Log.d(TAG, "initCameraInfo: savePicSizes为空");return;}Size[] previewSizes = configurationMap.getOutputSizes(SurfaceTexture.class); //预览尺寸if (previewSizes == null) {Log.d(TAG, "initCameraInfo: previewSizes为空");return;}int mDisplayRotation = mActivity.getWindowManager().getDefaultDisplay().getRotation(); //手机方向boolean exchange = exchangeWidthAndHeight(mDisplayRotation, mCameraSensorOrientation);if (exchange) {mSavePicSize = getBestSize(mSavePicSize.getHeight(),mSavePicSize.getWidth(),mSavePicSize.getHeight(),mSavePicSize.getWidth(),Arrays.asList(savePicSizes));} else {mSavePicSize = getBestSize(mSavePicSize.getWidth(),mSavePicSize.getHeight(),mSavePicSize.getWidth(),mSavePicSize.getHeight(),Arrays.asList(savePicSizes));}if (exchange) {mPreviewSize = getBestSize(mPreviewSize.getHeight(),mPreviewSize.getWidth(),mTextureView.getHeight(),mTextureView.getWidth(),Arrays.asList(previewSizes));} else {mPreviewSize = getBestSize(mPreviewSize.getWidth(),mPreviewSize.getHeight(),mTextureView.getWidth(),mTextureView.getHeight(),Arrays.asList(previewSizes));}mPreviewSize = new Size(1080,1440);if (mTextureView.getSurfaceTexture() == null){Log.i(TAG, "initCameraInfo: mTextureView.getSurfaceTexture() 执行了*******************");SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();surfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());mTextureView.setSurfaceTexture(surfaceTexture);}Log.d(TAG, "预览最优尺寸: " + mPreviewSize.getWidth() + " " + mPreviewSize.getHeight() +"比例 " + mPreviewSize.getWidth() / mPreviewSize.getHeight());Log.d(TAG, "保存图片最优尺寸: " + mSavePicSize.getWidth() + " " + mSavePicSize.getHeight() +"比例 " + mSavePicSize.getWidth() / mSavePicSize.getHeight());mImageReader = ImageReader.newInstance(mSavePicSize.getWidth(), mSavePicSize.getHeight(), ImageFormat.JPEG, 1);mImageReader.setOnImageAvailableListener(onImageAvailableListener, mCameraHandler);Log.d(TAG, "initCameraInfo: mTextureView-----------5");openCamera();} catch (CameraAccessException e) {e.printStackTrace();}}/*** 打开相机*/private void openCamera() {if (ActivityCompat.checkSelfPermission(mActivity, 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.Log.d(TAG, "initCameraInfo: mTextureView-----------没有相机权限");List<String> permissionList = new ArrayList<>();permissionList.add(Manifest.permission.READ_EXTERNAL_STORAGE);permissionList.add(Manifest.permission.CAMERA);permissionList.add(Manifest.permission.CALL_PHONE);permissionList.add(Manifest.permission.MODIFY_AUDIO_SETTINGS);permissionList.add(Manifest.permission.ACCESS_BACKGROUND_LOCATION);permissionList.add(Manifest.permission.READ_PHONE_STATE);permissionList.add(Manifest.permission.INTERNET);permissionList.add(Manifest.permission.VIBRATE);permissionList.add(Manifest.permission.ACCESS_WIFI_STATE);ActivityCompat.requestPermissions(mActivity, permissionList.toArray(new String[permissionList.size()]),1002);}else {try {Log.d(TAG, "initCameraInfo: mTextureView-----------6准备打开相机");mCameraManager.openCamera(mCameraId, mStateCallback, mCameraHandler);Log.d(TAG, "openCamera: 打开相机");} catch (CameraAccessException e) {e.printStackTrace();}}}private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {@Overridepublic void onOpened(@NonNull CameraDevice camera) {Log.i(TAG, "onOpened: ");mCameraDevice = camera;createCaptureSession(mCameraDevice);}@Overridepublic void onDisconnected(@NonNull CameraDevice camera) {Log.i(TAG, "onDisconnected: ");}@Overridepublic void onError(@NonNull CameraDevice camera, int error) {Log.i(TAG, "onError: ");Toast.makeText(mActivity, "打开相机失败!error: " + error, Toast.LENGTH_SHORT);}};private void createCaptureSession(CameraDevice cameraDevice){try {Log.d(TAG, "createCaptureSession的CameraDevice :" + cameraDevice);CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);@SuppressLint("Recycle")Surface surface = new Surface(mTextureView.getSurfaceTexture());builder.addTarget(surface);builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);builder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);List<Surface> list = new ArrayList<>();list.add(surface);list.add(mImageReader.getSurface());cameraDevice.createCaptureSession(list, new CameraCaptureSession.StateCallback() {@Overridepublic void onConfigured(@NonNull CameraCaptureSession session) {mCameraCaptureSession = session;try {session.setRepeatingRequest(builder.build(), mCaptureCallback, mCameraHandler );} catch (CameraAccessException e) {e.printStackTrace();}}@Overridepublic void onConfigureFailed(@NonNull CameraCaptureSession session) {Log.d(TAG, "onConfigureFailed: 开启预览会话失败");}}, mCameraHandler);} catch (CameraAccessException e) {e.printStackTrace();}}private CameraCaptureSession.CaptureCallback mCaptureCallback = new CameraCaptureSession.CaptureCallback() {@Overridepublic void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {super.onCaptureCompleted(session, request, result);canExchangeCamera = true;canTakePicture = true;}@SuppressLint("ShowToast")@Overridepublic void onCaptureFailed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureFailure failure) {super.onCaptureFailed(session, request, failure);Log.d(TAG, "onCaptureFailed");Toast.makeText(mActivity,"开启预览失败",Toast.LENGTH_SHORT);}};private final ImageReader.OnImageAvailableListener onImageAvailableListener = reader -> {Image image = reader.acquireLatestImage();ByteBuffer byteBuffer = image.getPlanes()[0].getBuffer();byte[] bytesArray = new byte[byteBuffer.remaining()];byteBuffer.get(bytesArray);image.close();String localPicturePath = BitmapUtils.savePicture(bytesArray, "Camera");if (localPicturePath.equals("")){Log.d(TAG, "没有获取到最后一张图片的路径!!!!!: " + localPicturePath);imageButton.setImageResource(PREVIEW_FIRST_GET_IMAGE);}else {Bitmap bitmap = BitmapFactory.decodeFile(localPicturePath);int width = bitmap.getWidth();int height = bitmap.getHeight();float w = (float) 256 / width;//float h = (float) 256 / height;Matrix matrix = new Matrix();matrix.postScale(w, w);Bitmap newBitmap1 = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);Matrix matrix1 = new Matrix();matrix1.setRotate(90f);Bitmap resultBitmap = Bitmap.createBitmap(newBitmap1, 0, 0, newBitmap1.getWidth(), newBitmap1.getHeight(), matrix1, true);imageButton.setImageBitmap(resultBitmap);Log.d(TAG, "onImageAvailable: ------------------------------------------------------------图片保存");}};private class CompareSizeByArea implements Comparator<Size> {@Overridepublic int compare(Size size1, Size size2) {return (int) Math.signum( size1.getWidth() * size1.getHeight() - size2.getWidth() * size2.getHeight());}}/*** 根据提供的屏幕方向 [displayRotation] 和相机方向 [sensorOrientation] 返回是否需要交换宽高*/private boolean exchangeWidthAndHeight(int displayRotation, int sensorOrientation){boolean exchange = false;switch (displayRotation){case Surface.ROTATION_0:case Surface.ROTATION_180:if (sensorOrientation == 90 || sensorOrientation == 270){exchange = true;}break;case Surface.ROTATION_90:case Surface.ROTATION_270:if (sensorOrientation == 0 || sensorOrientation == 180){exchange = true;}break;}Log.i(TAG, "屏幕方向: " + displayRotation);Log.i(TAG, "相机方向: " + sensorOrientation);return exchange;}
}
TION_180:
if (sensorOrientation == 90 || sensorOrientation == 270){
exchange = true;
}
break;
case Surface.ROTATION_90:
case Surface.ROTATION_270:if (sensorOrientation == 0 || sensorOrientation == 180){exchange = true;}break;}Log.i(TAG, "屏幕方向: " + displayRotation);Log.i(TAG, "相机方向: " + sensorOrientation);return exchange;
}
}
android相机预览拍照功能实现相关推荐
- android拍照功能无预览,Android快速实现无预览拍照功能
本文实例为大家分享了Android实现无预览拍照功能的具体代码,供大家参考,具体内容如下 实现思路: 把预览的SurfaceView的宽高设置为肉眼看不出的值,例如0.1dp,其他的就是自定义相机的标 ...
- android 预览和拍照成像方向不一致,Android相机预览方向深入探究
原标题:Android相机预览方向深入探究 今日快讯 9月7日,北京市交通委召集各区管理部门和15家共享自行车企业负责人,听取共享自行车投放和管理的意见建议,研究决定并下发通知,暂停在本市新增投放共享 ...
- android 圆形相机预览拍照_Android多种方式实现相机圆形预览
最终效果图如下: 一.为预览控件设置圆角 public RoundTextureView(Context context, AttributeSet attrs) { super(context, a ...
- android 圆形相机预览拍照_Android多种方式实现相机圆形预览的示例代码
效果图如下: 一.为预览控件设置圆角 public RoundTextureView(Context context, AttributeSet attrs) { super(context, att ...
- Android相机预览设置适配及显示方式
Android相机的部分工作原理. 预览流程 相机预览是Android Camera最常用的功能之一,它是很多功能重要的输入,例如扫码.AR等. 一般而言,相机预览的整体流程,可以通过下图表示: 其中 ...
- Android相机预览方向
以前对Camera了解的不是太深入,最近有需求把人脸识别 集成到项目,必然会与Camera打交道,遇到一些坑,与大家分享一下. 一.预览方向 Camera.CameraInfo info = ne ...
- Android相机预览页面被压缩和拉伸问题
最近公司要求在原有的项目中添加一个扫码登录的功能,在调试好相机之后,发现相机返回到Surfaceview页面上的预览图片,与我们现实中物品的比例并不相同,在一块正方形的Surfaceview中,预览界 ...
- 2022-07-21 Android 相机预览数据转Bitmap优化
背景 在Android开发中我们有时候会需要拿到相机预览数据转成bitmap自己做处理. 常用方式 在Android API中提供了 一套转换方式: private Bitmap convertBit ...
- Android 相机方向传感,Nexus 5x反向横向传感器修复在Android相机预览...
我是Android开发中的新手,所以如果我的问题很简单,我会提前道歉.在我的应用程序的一部分,我需要我的后置摄像头的实时预览,所以我创建了一个自定义类,扩展SurfaceView并实现SurfaceH ...
最新文章
- 腾讯云答治茜:云计算为独角兽和传统企业提供了哪些沃土?
- 极速理解设计模式系列:9.工厂方法模式(Factory Method Pattern)
- Python 元组遍历排序操作方法
- POJ 1061 青蛙的约会(扩展欧几里得)
- App设计灵感之十二组精美的智能家居App设计案例
- ubuntu20.04安裝迅雷
- Android中常用的一些方法总结的工具类
- asp listview 单元格文字颜色_如何替换CAD表格中特定区域单元格中的文字?
- CVE-2015-1635-HTTP.SYS远程执行代码漏洞(ms15-034)
- 腾讯Techo Park开发者大会召开在即,全球200多位专家共话云计算
- managed code和unmanaged code混合debug
- 刨根问底--struts-default.xml
- vex编程语言是基于c语言,vex机器人编程软件 vex机器人大赛
- MyEclipse自定义JSP模板
- [预警]WebSOC多漏洞插件检测 预防勒索病毒“Satan”新变种
- outlook正在使用outlook数据文件(.ost)旧的副本,请退出outlook,删除此文件,然后重启outlook。
- 无人驾驶——激光雷达篇
- ArcGIS Server manger管理页面无法打开问题解决
- 医学图像处理与深度学习入门
- 一篇文章从0搞定计算机网络,面试小case
热门文章
- ICC布局规划---1
- Don‘t Stop Pretraining: Adapt Language Models to Domains and Tasks
- 在Ubuntu下载Python3.6.2并建立软连接
- 【微信小程序学习】搜索音乐页面代码实现
- win10右键菜单没有新建Excel选项的解决方法
- 【论文笔记】Predictive control of aerial swarms in cluttered environments
- Codeforces 821B Okabe and Banana Trees 题解
- 根轨迹图、Bode图、Nyquist图的Matlab仿真
- 怎么在cmd窗口产生个随机数
- Paper:《BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding用于语言理解的深度双向Tr