自定义相主要通过 GLSurfaceView视图和Camera相机进行实现 。由于GLSurfaceView进行视图的渲染 Camera进行拍照即回调处理
首先添加需要的权限 否则会报打不开相机服务的异常 需要添加动态权限的自己加一下

首先自定义相机view

public class CameraPreview extends GLSurfaceView implements GLSurfaceView.Renderer, SurfaceTexture.OnFrameAvailableListener {public String vss ="attribute vec2 vPosition;\n" +"attribute vec2 vTexCoord;\n" +"varying vec2 texCoord;\n" +"void main() {\n" +"  texCoord = vTexCoord;\n" +"  gl_Position = vec4 ( vPosition.y, vPosition.x, 0.0, 1.0 );\n" +"}";private final String fss_front ="#extension GL_OES_EGL_image_external : require\n" +"precision mediump float;\n" +"uniform samplerExternalOES sTexture;\n" +"varying vec2 texCoord;\n" +"void main() {\n" +"  gl_FragColor = texture2D(sTexture,texCoord);\n" +"}";private final String fss_back ="#extension GL_OES_EGL_image_external : require\n" +"precision mediump float;\n" +"uniform samplerExternalOES sTexture;\n" +"varying vec2 texCoord;\n" +"void main() {\n" +"  vec2 newText = vec2(1.0-texCoord.x, texCoord.y);\n" +"  gl_FragColor = texture2D(sTexture,newText);\n" +"}";private static String LOG_TAG = CameraPreview.class.getName();private List<Camera.Size> mSupportedPreviewSizes;private int[] mTextureId;private int[] fbo = new int[]{0};private SurfaceTexture mSurfaceTexture;private Camera mCamera;private FloatBuffer pVertex;private FloatBuffer pTexCoord;private ByteBuffer pixelBuffer;private MediaRecorder mMediarecorder;private File mOutputFile;public Boolean isPreviewing = false;private int nCameraFrontBack; //0: front  1:backprivate int hProgram;private int bufferWidth = 1040;private int bufferHeight = 1848;private int mWindowWidth = 1040;private int mWindowHeight = 1848;private static float mPreviewRatio = 640 / 480.0f;public static final int CameraFront = 0;public static final int CameraBack = 1;private OnTakePicCallBack mOnTakePicCallBack;private OnDrawFrameCallback mOnDrawFrameCallback;public interface OnDrawFrameCallback {void call(byte[] rgba, int w, int h);}public interface OnTakePicCallBack {void onPictureTaken(byte[] data);}public CameraPreview(Context context) {super(context);initView();}public CameraPreview(Context context, AttributeSet attrs) {super(context, attrs);TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.youtuattrs);nCameraFrontBack = typedArray.getInteger(R.styleable.youtuattrs_cameraPosition, 0);initView();}private void initView() {Log.d(LOG_TAG, "initView");float[] vtmp = {1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f};float[] ttmp = {1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f};pVertex = ByteBuffer.allocateDirect(8 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();pVertex.put(vtmp);pVertex.position(0);pTexCoord = ByteBuffer.allocateDirect(8 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();pTexCoord.put(ttmp);pTexCoord.position(0);pixelBuffer = ByteBuffer.allocateDirect(bufferWidth * bufferHeight * 4).order(ByteOrder.nativeOrder());setEGLContextClientVersion(2);setEGLConfigChooser(8, 8, 8, 8, 0, 0);// fixed:setRenderer(this);setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);getHolder().setFormat(PixelFormat.RGBA_8888);if (nCameraFrontBack == CameraFront) {openFrontCamera();} else {openBackCamera();}Camera.Size size = mCamera.getParameters().getPreviewSize();mPreviewRatio = (float) size.width / size.height;}@Overridepublic void onResume() {Log.d(LOG_TAG, "onResume");}@Overridepublic void onPause() {Log.d(LOG_TAG, "onPause");}public void setOnTakePicCallBack(OnTakePicCallBack callBack) {mOnTakePicCallBack = callBack;}@Overridepublic void onFrameAvailable(SurfaceTexture surfaceTexture) {requestRender();}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {super.surfaceDestroyed(holder);}@Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config) {}@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) {if (mSurfaceTexture != null) {mSurfaceTexture.setOnFrameAvailableListener(null);mSurfaceTexture.release();mSurfaceTexture = null;}if (hProgram != 0) {GLES20.glDeleteProgram(hProgram);hProgram = 0;}initTex();mSurfaceTexture = new SurfaceTexture(mTextureId[0]);mSurfaceTexture.setOnFrameAvailableListener(this);try {mCamera.stopPreview();mCamera.setPreviewTexture(mSurfaceTexture);} catch (Exception e) {e.printStackTrace();}if (nCameraFrontBack == CameraFront) {hProgram = loadShader(vss, fss_front);} else {hProgram = loadShader(vss, fss_back);}mWindowWidth = width;mWindowHeight = height;initCamera();}public void takePicture() {//initCamera();//实现相机的参数初始化
//        mCamera.startPreview();if (mCamera != null && isPreviewing) {//对焦是个坑 感觉不加的好
//            mCamera.autoFocus(new Camera.AutoFocusCallback() {
//                @Override
//                public void onAutoFocus(boolean b, Camera camera) {
//                    if (b) {mCamera.takePicture(null, null, mJpegPictureCallback);isPreviewing = false;
//                        mCamera.cancelAutoFocus();//只有加上了这一句,才会自动对焦。
//                    }
//                }
//            });}}private void openFrontCamera() {Camera.CameraInfo cameraInfo = new Camera.CameraInfo();int cameraCount = Camera.getNumberOfCameras();for (int camIdx = 0; camIdx < cameraCount; camIdx++) {Camera.getCameraInfo(camIdx, cameraInfo);Log.i("摄像头", camIdx + "...." + cameraInfo.facing + "..." + cameraInfo.orientation);if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {mCamera = Camera.open(camIdx);return;}}mCamera = Camera.open();}private void openBackCamera() {Camera.CameraInfo cameraInfo = new Camera.CameraInfo();int cameraCount = Camera.getNumberOfCameras();for (int camIdx = 0; camIdx < cameraCount; camIdx++) {Camera.getCameraInfo(camIdx, cameraInfo);if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {mCamera = Camera.open(camIdx);return;}}mCamera = Camera.open();}private void initTex() {mTextureId = new int[2];GLES20.glGenTextures(2, mTextureId, 0);GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureId[0]);GLES20.glActiveTexture(GLES20.GL_TEXTURE0);GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureId[1]);GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA,bufferWidth, bufferHeight, 0, GLES20.GL_RGBA,GLES20.GL_UNSIGNED_BYTE, null);GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);GLES20.glGenFramebuffers(1, fbo, 0);GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fbo[0]);GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER,GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D,mTextureId[1], 0);}private void deleteTex() {if (mTextureId[0] != 0) {GLES20.glDeleteTextures(2, mTextureId, 0);mTextureId[0] = 0;mTextureId[1] = 0;}if (fbo[0] != 0) {GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fbo[0]);GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER,GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, 0, 0);GLES20.glDeleteFramebuffers(1, fbo, 0);fbo[0] = 0;}}private void initCamera() {try {//配置如下:Camera.Parameters parameters = mCamera.getParameters();// 获取相机参数集//            if (parameters.getSupportedPreviewSizes() != null && parameters.getSupportedPreviewSizes().size() > 0) {
//                //预览像素
//                parameters.setPreviewSize(parameters.getSupportedPreviewSizes().get(0).width, parameters.getSupportedPreviewSizes().get(0).height);
//            }if (parameters.getSupportedPictureSizes() != null && parameters.getSupportedPictureSizes().size() > 0) {//拍照图片的大小  100kparameters.setPictureSize(parameters.getSupportedPictureSizes().get(parameters.getSupportedPictureSizes().size() / 4).width, parameters.getSupportedPictureSizes().get(parameters.getSupportedPictureSizes().size() / 4).height);//拍照图片的大小  200k
//                parameters.setPictureSize(parameters.getSupportedPictureSizes().get(parameters.getSupportedPictureSizes().size() / 2).width, parameters.getSupportedPictureSizes().get(parameters.getSupportedPictureSizes().size() / 2).height);}parameters.setPictureFormat(ImageFormat.JPEG);mCamera.setParameters(parameters);//开启预览效果mCamera.startPreview();//启动浏览isPreviewing = true;} catch (Exception e) {Log.d(LOG_TAG, "Error starting camera preview: " + e.getMessage());}}private void releaseMediaRecorder() {if (mMediarecorder != null) {// clear recorder configurationmMediarecorder.reset();// release the recorder objectmMediarecorder.release();mMediarecorder = null;// Lock camera for later use i.e taking it back from MediaRecorder.// MediaRecorder doesn't need it anymore and we will release it if the activity pauses.if (mCamera != null) {mCamera.lock();}}}@Overridepublic void onDrawFrame(GL10 gl) {GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);if (null != mSurfaceTexture) {mSurfaceTexture.updateTexImage();}GLES20.glUseProgram(hProgram);int ph = GLES20.glGetAttribLocation(hProgram, "vPosition");int tch = GLES20.glGetAttribLocation(hProgram, "vTexCoord");int th = GLES20.glGetUniformLocation(hProgram, "sTexture");GLES20.glActiveTexture(GLES20.GL_TEXTURE0);GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureId[0]);GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);GLES20.glUniform1i(th, 0);GLES20.glVertexAttribPointer(ph, 2, GLES20.GL_FLOAT, false, 4 * 2, pVertex);GLES20.glVertexAttribPointer(tch, 2, GLES20.GL_FLOAT, false, 4 * 2, pTexCoord);GLES20.glEnableVertexAttribArray(ph);GLES20.glEnableVertexAttribArray(tch);{GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fbo[0]);GLES20.glViewport(0, 0, bufferWidth, bufferHeight);GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);GLES20.glReadPixels(0, 0, bufferWidth, bufferHeight, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, pixelBuffer);if (mOnDrawFrameCallback != null) {mOnDrawFrameCallback.call(pixelBuffer.array(), bufferWidth, bufferHeight);}}GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);{double aspectHeight = mWindowHeight;double aspectWidth = mWindowHeight / mPreviewRatio;if (mWindowWidth > aspectWidth) {aspectWidth = mWindowWidth;aspectHeight = mWindowWidth * mPreviewRatio;}// glViewport(0, 0, width_, height_);GLES20.glViewport((int) -(aspectWidth - mWindowWidth) / 2,(int) -(aspectHeight - mWindowHeight) / 2, (int) aspectWidth,(int) aspectHeight);}
//        GLES20.glViewport(0, 0, mWindowWidth, mWindowHeight);GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);GLES20.glDisableVertexAttribArray(ph);GLES20.glDisableVertexAttribArray(tch);}private static int loadShader(String vss, String fss) {int vshader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);GLES20.glShaderSource(vshader, vss);GLES20.glCompileShader(vshader);int[] compiled = new int[1];GLES20.glGetShaderiv(vshader, GLES20.GL_COMPILE_STATUS, compiled, 0);if (compiled[0] == 0) {Log.e("Shader", "Could not compile vshader");Log.v("Shader", "Could not compile vshader:" + GLES20.glGetShaderInfoLog(vshader));GLES20.glDeleteShader(vshader);vshader = 0;}int fshader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);GLES20.glShaderSource(fshader, fss);GLES20.glCompileShader(fshader);GLES20.glGetShaderiv(fshader, GLES20.GL_COMPILE_STATUS, compiled, 0);if (compiled[0] == 0) {Log.e("Shader", "Could not compile fshader");Log.v("Shader", "Could not compile fshader:" + GLES20.glGetShaderInfoLog(fshader));GLES20.glDeleteShader(fshader);fshader = 0;}int program = GLES20.glCreateProgram();GLES20.glAttachShader(program, vshader);GLES20.glAttachShader(program, fshader);GLES20.glLinkProgram(program);return program;}PictureCallback mJpegPictureCallback = new PictureCallback() {public void onPictureTaken(byte[] data, Camera camera) {Log.i(LOG_TAG, "myJpegCallback:onPictureTaken...");mCamera.stopPreview();
//            isPreviewing = false;if (mOnTakePicCallBack != null) {mOnTakePicCallBack.onPictureTaken(data);}mCamera.startPreview();isPreviewing = true;}};private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {final double ASPECT_TOLERANCE = 0.1;double targetRatio = (double) h / w;if (sizes == null)return null;Camera.Size optimalSize = null;double minDiff = Double.MAX_VALUE;int targetHeight = h;for (Camera.Size size : sizes) {double ratio = (double) size.height / size.width;if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)continue;if (Math.abs(size.height - targetHeight) < minDiff) {optimalSize = size;minDiff = Math.abs(size.height - targetHeight);}}if (optimalSize == null) {minDiff = Double.MAX_VALUE;for (Camera.Size size : sizes) {if (Math.abs(size.height - targetHeight) < minDiff) {optimalSize = size;minDiff = Math.abs(size.height - targetHeight);}}}return optimalSize;}ShutterCallback mShutterCallback = new ShutterCallback() {public void onShutter() {Log.i(LOG_TAG, "myShutterCallback:onShutter...");}};public File startRecordVideo() {mMediarecorder = new MediaRecorder();// 创建mediarecorder对象mCamera.unlock();mMediarecorder.setCamera(mCamera);// 设置录制视频源为Camera(相机)mMediarecorder.setAudioSource(MediaRecorder.AudioSource.MIC);mMediarecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);// 设置录制完成后视频的封装格式THREE_GPP为3gp.MPEG_4为mp4mMediarecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);// 设置录制的视频编码h263 h264
//        mMediarecorder.setVideoFrameRate(15);CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_TIME_LAPSE_480P);mMediarecorder.setVideoSize(profile.videoFrameWidth, profile.videoFrameHeight);//        mediarecorder.setVideoEncodingBitRate(4000000);mMediarecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);mMediarecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);// 设置视频录制的分辨率。必须放在设置编码和格式的后面,否则报错////        // 设置录制的视频帧率。必须放在设置编码和格式的后面,否则报错//        mediarecorder.setVideoFrameRate(30);mMediarecorder.setOrientationHint(270);// 设置视频文件输出的路径mOutputFile = getOutputMediaFile();if (mOutputFile == null) {return null;}mMediarecorder.setOutputFile(mOutputFile.getPath());try {// 准备录制mMediarecorder.prepare();// 开始录制mMediarecorder.start();} catch (IllegalStateException e) {releaseMediaRecorder();e.printStackTrace();} catch (IOException e) {releaseMediaRecorder();e.printStackTrace();}return mOutputFile;}private File getOutputMediaFile() {// To be safe, you should check that the SDCard is mounted// using Environment.getExternalStorageState() before doing this.if (!Environment.getExternalStorageState().equalsIgnoreCase(Environment.MEDIA_MOUNTED)) {return null;}File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "youtu");// This location works best if you want the created images to be shared// between applications and persist after your app has been uninstalled.// Create the storage directory if it does not existif (!mediaStorageDir.exists()) {if (!mediaStorageDir.mkdirs()) {Log.d("CameraSample", "failed to create directory");return null;}}// Create a media file nameString timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());File mediaFile = new File(mediaStorageDir.getPath() + File.separator +"VID_" + timeStamp + ".mp4");return mediaFile;}public void stopRecordCamera() {releaseMediaRecorder();}public void setCameraFrontBack(int n) {nCameraFrontBack = n;}public void releaseRes() {releaseMediaRecorder();isPreviewing = false;if (mCamera != null) {mCamera.stopPreview();mCamera.release();mCamera = null;}queueEvent(new Runnable() {@Overridepublic void run() {if (mSurfaceTexture != null) {mSurfaceTexture.setOnFrameAvailableListener(null);mSurfaceTexture.release();mSurfaceTexture = null;}if (hProgram != 0) {GLES20.glDeleteProgram(hProgram);hProgram = 0;}deleteTex();}});}public void setOnDrawFrameCallback(OnDrawFrameCallback callback) {mOnDrawFrameCallback = callback;}
}

自定义view需要的attr参数文件

<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"><declare-styleable name="youtuattrs"><attr name="cameraPosition"><flag name="front" value="0" /><flag name="back" value="1" /></attr></declare-styleable>
</resources>

以上为所有准备工作 下面开始调用

引入xml布局文件

<com.example.eyemhealth.face.CameraPreviewandroid:id="@+id/camPreview"android:layout_width="@dimen/dp_131"android:layout_height="@dimen/dp_130"android:layout_marginBottom="@dimen/dp_70"android:layout_alignParentBottom="true"android:layout_marginLeft="@dimen/dp_264"app:cameraPosition="front"/>

通过布局找到文件不多说了 直接看操作代码

拍照

mCamPreview.takePicture();**//拍照回调**
mCamPreview.setOnTakePicCallBack(new CameraPreview.OnTakePicCallBack() {@Overridepublic void onPictureTaken(byte[] data) {//将字节数组转成图片 并旋转Bitmap bitmap1 = rotateBitmap(-90, BitmapFactory.decodeByteArray(data, 0, data.length));ByteArrayOutputStream baos = new ByteArrayOutputStream();bitmap1.compress(Bitmap.CompressFormat.JPEG, 100, baos);byte[] bits = baos.toByteArray();encode = Base64.encode(bits);  }
});

自定义原生相机+拍照+GLSurfaceView+Camera相关推荐

  1. h5 调用ios原生相机拍照上传照片

    1.html中的点击按钮和回调显示标签---------------直接上代码 <!DOCTYPE html> <html lang="en"> <h ...

  2. FileReader()读取文件,h5调用原生相机拍照,FormData()上传服务器

    公司最近在做一个h5嵌入原生的项目,其中有一个需求是在没有和原生交互的前提下,调用调用手机相机进行拍照,然后将照片上传后端. 之前没接触过类似的需求,然后就感觉要调用移动端的硬件设备很是高大上:现在项 ...

  3. Android 调用系统原生相机拍照并储存到指定位置

    Android 6.0(API 23以下,不包括23)以下,无动态授权模块, 权限: <uses-permission android:name="android.permission ...

  4. Android下 调用原生相机拍照摄像

    1 http://www.cnblogs.com/franksunny/archive/2011/11/17/2252926.html 2 http://www.cnblogs.com/vir56k/ ...

  5. php微信照相机,用微信拍照时怎么打开原生相机?(Android)| 有轻功

    在日常的微信聊天中,我们经常会给朋友分享即兴拍摄的照片.出于方便,很多时候我们会直接用微信来拍照,但用微信自带的相机拍出来的照片,效果其实并不理想. 上为手机原生相机拍摄,下为微信相机拍摄 特别是在光 ...

  6. iOS-自定义相机拍照获取指定区域图片

    功能并不难,之所以被难住是因为把问题想复杂了,记录一下. 自定义的相机拍照使用AVCaptureSession,获取指定区域图片使用图片裁切功能,重点在于不能直接使用AVCaptureSession获 ...

  7. Unity iOS 获取相册图片, 调用原生相机, 截屏并保存到相册

    原文链接 该Demo实现如下功能 1.从相册_照片 获取图片, 并贴在Image上 2.从相册_时刻 获取照片, 并贴在Image上 3.打开原生相机,拍照并把照片贴在Image上 4.截屏并保存到相 ...

  8. android自定义相机拍照

     Android中开发相机的两种方式: Android系统提供了两种使用手机相机资源实现拍摄功能的方法,一种是直接通过Intent调用系统相机组件,这种方法快速方便,适用于直接获得照片的场景,如上传相 ...

  9. 自定义Camera系列之:GLSurfaceView + Camera

    一.前言 假如你要使用 OpenGL ES 来渲染相机的话,使用 GLSurfaceView 将是一个很常用的选择. 这里介绍 GLSurfaceView + Camera 的组合.虽然从 Andro ...

最新文章

  1. php可以定义数组的常量吗
  2. java中volatile_Java中Volatile关键字详解
  3. 模拟电路技术之基础知识(六)
  4. 【解决方案】本次安装Visual Studio 所用的安装程序不完整
  5. Python的Crypto模块使用:自动输入Shell中的密码
  6. 防范sql注入式攻击(Java字符串校验,高可用性)
  7. css 计算属性的应用_如何使用一点CSS Grid魔术设计计算器应用
  8. 谷歌浏览器32位安装包_谷歌浏览器发布紧急安全更新修复Blink内核中的任意代码执行漏洞...
  9. 存储过程不可以封装_【小知识】功率半导体器件之10功率器件的封装可靠性
  10. 不使用资源文件动态创建对话框的做法
  11. 「02」《机器学习经·天工开物篇》
  12. 在Sqlite中通过Replace来实现插入和更新
  13. 图书管理系统的分析与设计
  14. 织梦dedecms怎么改模板
  15. 大学计算机基础总结与复习
  16. 带电检测必要性_GIS的概念和定期局部放电检测的重要性
  17. arduino SIM868发送post请求到服务器,解决只能成功发送一次的问题
  18. 灵巧好用的手机便签软件
  19. Ubuntu18.08安装到移动硬盘(UFEI引导)
  20. websocket传输速率_STM32 websocket,TCP和UDP的传输速率

热门文章

  1. LabVIEW编程LabVIEW开发雷尼绍光栅尺Renishaw DX10表例程与相关资料
  2. 桂林航天工业学院计算机实验报告,桂林航天工业学院电子工程系程控交换实验报告详解.doc...
  3. Typecho的使用
  4. crawler(1)
  5. python手机app自动_python+appium 自动化1--启动手机京东app
  6. Unity游戏开发之排行榜(采用PlayerPrefs存储)
  7. 上市公司高新技术资质认定匹配数据(2000-2021年)
  8. matlab imshow 去掉白边
  9. npm、yarn、pnpm的区别
  10. 智慧井盖-城市窨井盖监测设备