刚開始学习Android,因为之前比較熟悉OpenCV,于是就想先在Android上执行OpenCV试试

===================================================================================

1.环境配置

  • JDK
  • Eclipse
  • ADT
  • CDT
  • Android SDK
  • Android NDK
  • cygwin
  • OpenCV for Android 2.4.9

这部分网上非常多。我就不再赘述了,能够參考:http://blog.csdn.net/pwh0996/article/details/8957764

2.开发准备

两点注意

  • 新版安装SDK文件一開始有两个XML文件,activity_main.xml和fragment_main.xml:不习惯的能够这样处理:
  1. 删除fragment_main.xml整个文件
  2. 对activity_main.xml,删除里面的内容。然后切换到Graphy Layout,放入一个LinearLayout就能够
  3. 对MainActivity.java。能够删除部分的内容,再把MainActivity extends ActionBarActivity 改为MainActivity extends Activity
  4. (关于activity_main.xml与fragment_main.xml的问题參看:http://bbs.csdn.net/topics/390740123)
  • 引入OpenCV库
            Package Explorer中选择项目,单击右键在弹出菜单中选择Properties,然后在弹出的Properties窗体中左側选择Android。然后点击右下方的Addbutton,选择OpenCV Library 2.4.9并点击OK。操作完毕后,会将OpenCV类库加入到GrayProcess的Android Dependencies中
3.编敲代码
目的是实现通过OpenCV for Android实现摄像头採集图像的处理。并通过SurfaceView显示在手机屏幕上
OpenCV的Android库将Android自身的相机相关的库进行了封装。用起来十分方便

  • CameraBridgeViewBase .enableView()
  • SurfaceView is available
    • CameraBridgeViewBase  .setVisibility(SurfaceView.Visiable)
    • CameraBridgeViewBase  .setCvCameraViewListener(this)
就能够使用回调函数
  • onCameraViewStarted
  • onCameraViewStopped

图像处理写在
  • public Mat onCameraFrame(CvCameraViewFrame inputFrame)

Java文件:

public class MainActivity extends Activity implements CvCameraViewListener2 {
private static final String TAG = "OCVSample::Activity"; private CameraBridgeViewBase mOpenCvCameraView;
private boolean mIsJavaCamera = true;
private MenuItem mItemSwitchCamera = null;
private Mat mRgba;
private Button mBtn = null;
private boolean isProcess = false; //建立连接
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i(TAG, "OpenCV loaded successfully");
mOpenCvCameraView.enableView();
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
}; //构造函数
public MainActivity() {
Log.i(TAG, "Instantiated new " + this.getClass());
} /** Called when the activity is first created. */
//onCreate函数
@Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "called onCreate");
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); setContentView(R.layout.activity_main); //
if (mIsJavaCamera)
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.tutorial1_activity_java_surface_view);
else
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.tutorial1_activity_native_surface_view); mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE); mOpenCvCameraView.setCvCameraViewListener(this); mBtn = (Button) findViewById(R.id.buttonGray);
mBtn.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
isProcess = !isProcess;
}
});
} @Override
public void onPause()
{
super.onPause();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
} @Override
public void onResume()
{
super.onResume();
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_9, this, mLoaderCallback);
} public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
Log.i(TAG, "called onCreateOptionsMenu");
mItemSwitchCamera = menu.add("Toggle Native/Java camera");
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
String toastMesage = new String();
Log.i(TAG, "called onOptionsItemSelected; selected item: " + item); if (item == mItemSwitchCamera) {
mOpenCvCameraView.setVisibility(SurfaceView.GONE);
mIsJavaCamera = !mIsJavaCamera; if (mIsJavaCamera) {
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.tutorial1_activity_java_surface_view);
toastMesage = "Java Camera";
} else {
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.tutorial1_activity_native_surface_view);
toastMesage = "Native Camera";
} mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
mOpenCvCameraView.setCvCameraViewListener(this);
mOpenCvCameraView.enableView();
Toast toast = Toast.makeText(this, toastMesage, Toast.LENGTH_LONG);
toast.show();
} return true;
} public void onCameraViewStarted(int width, int height) {
mRgba = new Mat(height, width, CvType.CV_8UC4); } public void onCameraViewStopped() {
mRgba.release();
} public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
if(isProcess)
Imgproc.cvtColor(inputFrame.gray(), mRgba, Imgproc.COLOR_GRAY2RGBA, 4);
else
mRgba = inputFrame.rgba();
return mRgba;
}
}

Manifest文件:
需增加相机使用权限
<uses-permission android:name="android.permission.CAMERA"/> 
注意:一般Android摄像头採集的图像方向不正确
在纯Android的开发环境中,一般採用
mCamera.setDisplayOrientation(90);

在OpenCV
for Android的开发中,在Manifest文件里增加:

android:screenOrientation="landscape"
android:configChanges="keyboardHidden|orientation"

完整的Manifest文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.camera03"
android:versionCode="1"
android:versionName="1.0" > <supports-screens android:resizeable="true"
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:anyDensity="true" />
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.CAMERA"/> <application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
<activity
android:name="com.example.camera03.MainActivity"
android:label="@string/app_name"
android:screenOrientation="landscape"
android:configChanges="keyboardHidden|orientation">
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application> </manifest>

layout文件
activity_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:opencv="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" > <org.opencv.android.JavaCameraView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="gone"
android:id="@+id/tutorial1_activity_java_surface_view"
opencv:show_fps="true"
opencv:camera_id="any" /> <org.opencv.android.NativeCameraView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="gone"
android:id="@+id/tutorial1_activity_native_surface_view"
opencv:show_fps="true"
opencv:camera_id="any" /> <RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" > <Button
android:id="@+id/buttonGray"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="@string/buttonGray" /> </RelativeLayout> </FrameLayout>


原图:

灰度图:


Java程序2:
分别完毕了
  1. 原图
  2. 灰度图
  3. Canny边缘检測
  4. Hist 直方图计算
  5. Sobel 边缘检測
  6. SEPIA(色调变换)为每个数组元素运行一个矩阵变换
  7. ZOOM 放大镜
  8. PIXELIZE 像素化
  9. POSTERIZE 多色调分色印
package com.example.camera03;

import java.util.Arrays;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfFloat;
import org.opencv.core.MatOfInt;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2; import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.Toast; public class MainActivity extends Activity implements CvCameraViewListener2 {
private static final String TAG = "OCVSample::Activity"; private CameraBridgeViewBase mOpenCvCameraView;
private boolean mIsJavaCamera = true;
private MenuItem mItemSwitchCamera = null;
private Mat mRgba;
private Mat mGray;
private Mat mTmp; private Size mSize0;
private Mat mIntermediateMat;
private MatOfInt mChannels[];
private MatOfInt mHistSize;
private int mHistSizeNum = 25;
private Mat mMat0;
private float[] mBuff;
private MatOfFloat mRanges;
private Point mP1;
private Point mP2;
private Scalar mColorsRGB[];
private Scalar mColorsHue[];
private Scalar mWhilte;
private Mat mSepiaKernel;
private Button mBtn = null;
private int mProcessMethod = 0; private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i(TAG, "OpenCV loaded successfully");
mOpenCvCameraView.enableView();
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
}; public MainActivity() {
Log.i(TAG, "Instantiated new " + this.getClass());
} /** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "called onCreate");
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); setContentView(R.layout.activity_main); if (mIsJavaCamera)
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.tutorial1_activity_java_surface_view);
else
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.tutorial1_activity_native_surface_view); mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE); mOpenCvCameraView.setCvCameraViewListener(this); mBtn = (Button) findViewById(R.id.buttonGray);
mBtn.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
mProcessMethod++;
if(mProcessMethod>8) mProcessMethod=0;
}
});
} @Override
public void onPause()
{
super.onPause();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
} @Override
public void onResume()
{
super.onResume();
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_9, this, mLoaderCallback);
} public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
Log.i(TAG, "called onCreateOptionsMenu");
mItemSwitchCamera = menu.add("Toggle Native/Java camera");
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
String toastMesage = new String();
Log.i(TAG, "called onOptionsItemSelected; selected item: " + item); if (item == mItemSwitchCamera) {
mOpenCvCameraView.setVisibility(SurfaceView.GONE);
mIsJavaCamera = !mIsJavaCamera; if (mIsJavaCamera) {
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.tutorial1_activity_java_surface_view);
toastMesage = "Java Camera";
} else {
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.tutorial1_activity_native_surface_view);
toastMesage = "Native Camera";
} mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
mOpenCvCameraView.setCvCameraViewListener(this);
mOpenCvCameraView.enableView();
Toast toast = Toast.makeText(this, toastMesage, Toast.LENGTH_LONG);
toast.show();
} return true;
} public void onCameraViewStarted(int width, int height) {
mRgba = new Mat(height, width, CvType.CV_8UC4);
mGray = new Mat(height, width, CvType.CV_8UC1);
mTmp = new Mat(height, width, CvType.CV_8UC4); mIntermediateMat = new Mat();
mSize0 = new Size();
mChannels = new MatOfInt[] { new MatOfInt(0), new MatOfInt(1), new MatOfInt(2) };
mBuff = new float[mHistSizeNum];
mHistSize = new MatOfInt(mHistSizeNum);
mRanges = new MatOfFloat(0f, 256f);
mMat0 = new Mat();
mColorsRGB = new Scalar[] { new Scalar(200, 0, 0, 255), new Scalar(0, 200, 0, 255), new Scalar(0, 0, 200, 255) };
mColorsHue = new Scalar[] {
new Scalar(255, 0, 0, 255), new Scalar(255, 60, 0, 255), new Scalar(255, 120, 0, 255), new Scalar(255, 180, 0, 255), new Scalar(255, 240, 0, 255),
new Scalar(215, 213, 0, 255), new Scalar(150, 255, 0, 255), new Scalar(85, 255, 0, 255), new Scalar(20, 255, 0, 255), new Scalar(0, 255, 30, 255),
new Scalar(0, 255, 85, 255), new Scalar(0, 255, 150, 255), new Scalar(0, 255, 215, 255), new Scalar(0, 234, 255, 255), new Scalar(0, 170, 255, 255),
new Scalar(0, 120, 255, 255), new Scalar(0, 60, 255, 255), new Scalar(0, 0, 255, 255), new Scalar(64, 0, 255, 255), new Scalar(120, 0, 255, 255),
new Scalar(180, 0, 255, 255), new Scalar(255, 0, 255, 255), new Scalar(255, 0, 215, 255), new Scalar(255, 0, 85, 255), new Scalar(255, 0, 0, 255)
};
mWhilte = Scalar.all(255);
mP1 = new Point();
mP2 = new Point(); // Fill sepia kernel
mSepiaKernel = new Mat(4, 4, CvType.CV_32F);
mSepiaKernel.put(0, 0, /* R */0.189f, 0.769f, 0.393f, 0f);
mSepiaKernel.put(1, 0, /* G */0.168f, 0.686f, 0.349f, 0f);
mSepiaKernel.put(2, 0, /* B */0.131f, 0.534f, 0.272f, 0f);
mSepiaKernel.put(3, 0, /* A */0.000f, 0.000f, 0.000f, 1f);
} public void onCameraViewStopped() {
mRgba.release();
mGray.release();
mTmp.release();
} public Mat onCameraFrame(CvCameraViewFrame inputFrame) { mRgba = inputFrame.rgba();
Size sizeRgba = mRgba.size();
int rows = (int) sizeRgba.height;
int cols = (int) sizeRgba.width;
Mat rgbaInnerWindow; int left = cols / 8;
int top = rows / 8; int width = cols * 3 / 4;
int height = rows * 3 / 4;
//灰度图
if(mProcessMethod==1)
Imgproc.cvtColor(inputFrame.gray(), mRgba, Imgproc.COLOR_GRAY2RGBA, 4);
//Canny边缘检測
else if(mProcessMethod==2)
{
mRgba = inputFrame.rgba();
Imgproc.Canny(inputFrame.gray(), mTmp, 80, 100);
Imgproc.cvtColor(mTmp, mRgba, Imgproc.COLOR_GRAY2RGBA, 4);
}
//Hist
else if(mProcessMethod==3)
{
Mat hist = new Mat();
int thikness = (int) (sizeRgba.width / (mHistSizeNum + 10) / 5);
if(thikness > 5) thikness = 5;
int offset = (int) ((sizeRgba.width - (5*mHistSizeNum + 4*10)*thikness)/2); // RGB
for(int c=0; c<3; c++) {
Imgproc.calcHist(Arrays.asList(mRgba), mChannels[c], mMat0, hist, mHistSize, mRanges);
Core.normalize(hist, hist, sizeRgba.height/2, 0, Core.NORM_INF);
hist.get(0, 0, mBuff);
for(int h=0; h<mHistSizeNum; h++) {
mP1.x = mP2.x = offset + (c * (mHistSizeNum + 10) + h) * thikness;
mP1.y = sizeRgba.height-1;
mP2.y = mP1.y - 2 - (int)mBuff[h];
Core.line(mRgba, mP1, mP2, mColorsRGB[c], thikness);
}
}
// Value and Hue
Imgproc.cvtColor(mRgba, mTmp, Imgproc.COLOR_RGB2HSV_FULL);
// Value
Imgproc.calcHist(Arrays.asList(mTmp), mChannels[2], mMat0, hist, mHistSize, mRanges);
Core.normalize(hist, hist, sizeRgba.height/2, 0, Core.NORM_INF);
hist.get(0, 0, mBuff);
for(int h=0; h<mHistSizeNum; h++) {
mP1.x = mP2.x = offset + (3 * (mHistSizeNum + 10) + h) * thikness;
mP1.y = sizeRgba.height-1;
mP2.y = mP1.y - 2 - (int)mBuff[h];
Core.line(mRgba, mP1, mP2, mWhilte, thikness);
}
}
//inner Window Sobel
else if(mProcessMethod==4)
{
Mat gray = inputFrame.gray();
Mat grayInnerWindow = gray.submat(top, top + height, left, left + width);
rgbaInnerWindow = mRgba.submat(top, top + height, left, left + width);
Imgproc.Sobel(grayInnerWindow, mIntermediateMat, CvType.CV_8U, 1, 1);
Core.convertScaleAbs(mIntermediateMat, mIntermediateMat, 10, 0);
Imgproc.cvtColor(mIntermediateMat, rgbaInnerWindow, Imgproc.COLOR_GRAY2BGRA, 4);
grayInnerWindow.release();
rgbaInnerWindow.release();
}
//SEPIA
else if(mProcessMethod==5)
{
rgbaInnerWindow = mRgba.submat(top, top + height, left, left + width);
Core.transform(rgbaInnerWindow, rgbaInnerWindow, mSepiaKernel);
rgbaInnerWindow.release();
}
//ZOOM
else if(mProcessMethod==6)
{
Mat zoomCorner = mRgba.submat(0, rows / 2 - rows / 10, 0, cols / 2 - cols / 10);
Mat mZoomWindow = mRgba.submat(rows / 2 - 9 * rows / 100, rows / 2 + 9 * rows / 100, cols / 2 - 9 * cols / 100, cols / 2 + 9 * cols / 100);
Imgproc.resize(mZoomWindow, zoomCorner, zoomCorner.size());
Size wsize = mZoomWindow.size();
Core.rectangle(mZoomWindow, new Point(1, 1), new Point(wsize.width - 2, wsize.height - 2), new Scalar(255, 0, 0, 255), 2);
zoomCorner.release();
mZoomWindow.release();
}
//PIXELIZE
else if(mProcessMethod==7)
{
rgbaInnerWindow = mRgba.submat(top, top + height, left, left + width);
Imgproc.resize(rgbaInnerWindow, mIntermediateMat, mSize0, 0.1, 0.1, Imgproc.INTER_NEAREST);
Imgproc.resize(mIntermediateMat, rgbaInnerWindow, rgbaInnerWindow.size(), 0., 0., Imgproc.INTER_NEAREST);
rgbaInnerWindow.release();
}
//POSTERIZE
else if(mProcessMethod==8)
{
rgbaInnerWindow = mRgba.submat(top, top + height, left, left + width);
Imgproc.Canny(rgbaInnerWindow, mIntermediateMat, 80, 90);
rgbaInnerWindow.setTo(new Scalar(0, 0, 0, 255), mIntermediateMat);
Core.convertScaleAbs(rgbaInnerWindow, mIntermediateMat, 1./16, 0);
Core.convertScaleAbs(mIntermediateMat, rgbaInnerWindow, 16, 0);
rgbaInnerWindow.release();
}
else
mRgba = inputFrame.rgba();
return mRgba;
}
}
  • 原图
  • 灰度图
  • watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveWFuZ3RyZWVz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" width="400" height="240" alt="">

  • Canny边缘检測
  • Hist 直方图计算
  • Sobel 边缘检測
  • SEPIA(色调变换)为每个数组元素运行一个矩阵变换
  • ZOOM 放大镜
  • PIXELIZE 像素化
  • POSTERIZE 多色调分色印




Android学习——在Android中使用OpenCV的第一个程序的更多相关文章

  1. [置顶] Android学习系列-Android中解析xml(7)

    Android学习系列-Android中解析xml(7) 一,概述 1,一个是DOM,它是生成一个树,有了树以后你搜索.查找都可以做. 2,另一种是基于流的,就是解析器从头到尾解析一遍xml文件.   ...

  2. [Android学习笔记]ListView中含有Button导致无法响应onItemClick回调的解决办法

    转自:http://www.cnblogs.com/eyu8874521/archive/2012/10/17/2727882.html 问题描述: 当ListView的Item中的控件只是一些展示类 ...

  3. Android学习笔记_49_Android中自定义属性(attrs.xml,TypedArray的使用)

    做Android布局是件很享受的事,这得益于他良好的xml方式.使用xml可以快速有效的为软件定义界面.可是有时候我们总感觉官方定义的一些基本组件不够用,自定义组件就不可避免了.那么如何才能做到像官方 ...

  4. 【Android学习】android:layout_weight的用法实例

    对于android:layout_weight的用法,用下面的例子来说明: <LinearLayout xmlns:android="http://schemas.android.co ...

  5. Android——android学习(android目录与AndroidManifest解析)

    res目录:存放android项目的各种资源文件 layout:存放界面布局文件 values:存放各种xml格式的资源文件 strings.xml:字符串资源文件: colors.xml:颜色资源文 ...

  6. Android学习【Android内核编译流程和错误笔记】

    博客:http://blog.csdn.net/muyang_ren Ubuntu14.04 LTS(要求是64位长期支持版LTS) Jdk1.8 内核:android4.0 一:jdk 1.解压jd ...

  7. Android学习路径——Android的四个组成部分activity(一)

    一.什么是Activity? Activity简单的说就是一个接口.我们是Android手机上看到的每个界面就是一个activity. 二.Activity的创建 1.定义一个类继承activity, ...

  8. Android学习十---Android Camera

    Android camera用来拍照和拍摄视频的先看一下最后实现的效果图             最后的效果图 一.准备 在你的应用程序上使用android拍照设备,需要考虑以下几个方面 1. 是否是 ...

  9. Android 学习之--android多线程断点下载

    我们平时都用"迅雷"下载软件,当下载到一半的时候突然断网,下次开启的时候能够从上次下载的地方继续下载,而且下载速度很快,那么这是怎么做到的呢! 其实它的“快”其实就是多线程的下载实 ...

随机推荐

  1. 【C】——pthread_mutex_lock

    函数名 pthread_mutex_lock, pthread_mutex_trylock, pthread_mutex_unlock - lock and unlock a mutex SYNOPS ...

  2. Web API(七):Basic基础认证

    1.WebApi中为什么需要身份认证 我们在使用WebApi的时候,都是通过URL去获取数据.也就是说,任何人只要知道了URL地址,就能随意的访问后台的服务接口,就可以访问或者修改数据库数据了,这样就 ...

  3. v8是怎么实现更快的 await ?深入理解 await 的运行机制

    最近v8团队发表一篇博客Faster async functions and promises, 预计在v7.2版本实现更快的异步函数和promise. 文章内容看起来不是很容易理解,背后的原理比较隐 ...

  4. snapshots On Vmware

    快照使用 编辑 如果你创建了多于一个的虚拟机快照,那么,你将有多个还原点可以用于恢复.当你创建了一个快照,那快照些现在可写的在那个点上就变成了只读的.使用in-file delta技术就能创建新文件记 ...

  5. USB2.0学习笔记连载(四):安装Cypress官网套件

    上一篇博客大概讲了一下USB通用驱动程序的解析.笔者使用Cypress官网给定的资料去完成USB驱动开发.官网资料地址:http://www.cypress.com/?rID=14321 下载如下图的 ...

  6. Ubuntu下Ruby的下载和编译源码安装

    1.Ruby的下载 Ruby可以在Ruby 官网上下载,如果想获取更多的Ruby版本,可以到淘宝镜像网站下载. 2.Ruby的编译源码安装 解压 首先把下载下来的源码压缩包解压到自己指定的目录 编译安 ...

  7. Mybatis表关联一对多

    有了前面几章的基础,对一些简单的应用是可以处理的,但在实际项目中,经常是关联表的查询,比如:最常见到的多对一,一对多等.这些查询是如何处理的呢,这一讲就讲这个问题.前面几篇教程中介绍的都是单表映射的一 ...

  8. Maven Web应用

    创建Web应用程序 要创建一个简单的java web应用程序,我们将使用Maven的原型 - web应用插件.因此,让我们打开命令控制台,进入到C: MVN目录并执行以下命令mvn命令. C:MVN& ...

  9. 7款效果惊人的HTML5/CSS3应用

    今天是周末,我为大家收集7个比较经典的HTML5/CSS3应用,每一个都提供源代码,效果非常惊人. 1.CSS3/jQuery创意盒子动画菜单 作为前端开发者,各种各样的jQuery菜单见过不少,这款 ...

  10. tp5数据输出

    法一:系统配置 'default_return_type'=>'json' 法二:输出设置 namespace app\index\controller; class Index { publi ...