打通網絡協議的任督二脈系列——音視頻篇之Camera2

2020-12-17 囧神的技術之旅

從5.0開始(API Level 21),可以完全控制Android設備相機的新api Camera2(android.hardware.Camera2)被引入了進來。在以前的Camera api(android.hardware.Camera)中,對相機的手動控制需要更改系統才能實現,而且api也不友好。不過老的Camera API在5.0上已經過時,在未來的app開發中推薦的是Camera2 API。

1Camera2介紹

在Camera類中我們多是使用這個類的對象去調用方法,而Camera2則是使用多個類去設置,功能更加強大。

Camera2架構:

Google採用了pipeline(管道)的概念,將Camera Device相機設備和Android Device安卓設備連接起來, Android Device通過管道發送CaptureRequest拍照請求給Camera Device,Camera Device通過管道返回CameraMetadata數據給Android Device,這一切建立在一個叫作CameraCaptureSession的會話中。

基本上我們需要使用的就是這些類啦。其中CameraManager是所有相機設備(CameraDevice)的管理者,要枚舉,查詢和打開可用的相機設備,就獲取CameraManager實例。

單個CameraDevices提供一組靜態屬性信息,描述硬體設備以及設備的可用設置和輸出參數。該信息通過CameraCharacteristics對象提供,可通過getCameraCharacteristics(String)獲得。

CameraCharacteristics是CameraDevice的屬性描述類,在CameraCharacteristics中可以進行相機設備功能的詳細設定(當然了,首先你得確定你的相機設備支持這些功能才行)。

要從相機設備捕獲或流式傳輸圖像,應用程式必須首先使用createCaptureSession(List,CameraCaptureSession.StateCallback,Handler)與相機設備一起使用一組輸出Surfaces創建攝像機捕獲會話。每個Surface必須預先配置適當的大小和格式(如果適用)以匹配相機設備可用的大小和格式。目標Surface可以從各種類獲得。

CameraCaptureSession:這是一個非常重要的API,當程序需要預覽、拍照時,都需要先通過該類的實例創建Session。而且不管預覽還是拍照,也都是由該對象的方法進行控制的,其中控制預覽的方法為setRepeatingRequest();控制拍照的方法為capture()。

通常,相機預覽圖像將發送到SurfaceView或TextureView(通過其SurfaceTexture)。

然後,應用程式需要構建一個CaptureRequest,它定義了相機設備捕獲單個映像所需的所有捕獲參數。該請求還列出了哪些配置的輸出表面應該用作此捕獲的目標。 CameraDevice具有用於為給定用例創建請求構建器的工廠方法,針對應用程式正在運行的Android設備進行了優化。

CameraRequest和CameraRequest.Builder:當程序調用setRepeatingRequest()方法進行預覽時,或調用capture()方法進行拍照時,都需要傳入CameraRequest參數。CameraRequest代表了一次捕獲請求,用於描述捕獲圖片的各種參數設置,比如對焦模式、曝光模式……總之,程序需要對照片所做的各種控制,都通過CameraRequest參數進行設置。CameraRequest.Builder則負責生成CameraRequest對象。

一旦請求被建立,它可以交給主動捕獲會話進行單次捕獲或無休止地重複使用。處理請求後,相機設備將產生一個TotalCaptureResult對象,該對象包含有關拍攝時相機設備狀態的信息以及使用的最終設置。如果需要捨入或解決矛盾的參數,這些請求可能會有所不同。相機設備還會將圖像數據幀發送到請求中包括的每個輸出表面。這些相對於輸出CaptureResult是異步產生的,有時候稍後會產生。類圖中有著三個重要的callback,其中CameraCaptureSession.CaptureCallback將處理預覽和拍照圖片的工作,需要重點對待。

這兩幅對Camera2接口使用的流程介紹我們綜合起來看會有更深的理解。

1.可以看出調用openCamera方法後會回調CameraDevice.StateCallback這個方法,在該方法裡重寫onOpened函數。

2.在onOpened方法中調用createCaptureSession,該方法又回調CameraCaptureSession.StateCallback方法。

3.在CameraCaptureSession.StateCallback中重寫onConfigured方法,設置setRepeatingRequest方法(也就是開啟預覽)。

4.setRepeatingRequest又會回調 CameraCaptureSession.CaptureCallback方法。

5.重寫CameraCaptureSession.CaptureCallback中的onCaptureCompleted方法,result就是未經過處理的元數據了。

順便提一下CameraCaptureSession.CaptureCallback中的onCaptureProgressed方法很明顯是在Capture過程中的,也就是在onCaptureCompleted之前,所以,在這之前想對圖像幹什麼就看你的了,像美顏等操作就可以在這個方法中實現了。

可以看出Camera2相機使用的邏輯還是比較簡單的,其實就是3個Callback函數的回調,先說一下:setRepeatingRequest和capture方法其實都是向相機設備發送獲取圖像的請求,但是capture就獲取那麼一次,而setRepeatingRequest就是不停的獲取圖像數據,所以呢,使用capture就想拍照一樣,圖像就停在那裡了,但是setRepeatingRequest一直在發送和獲取,所以需要連拍的時候就調用它,然後在onCaptureCompleted中保存圖像就行了。(注意了,圖像的預覽也是用的setRepeatingRequest,只是你不處理數據就行了)。

通過上面對Camera2的API的分析,我們可以知道控制拍照的大致步驟為:

調用CameraManager的openCamera(String cameraId, CameraDevice.StateCallback callback, Handler handler)方法打開指定攝像頭。該方法的第一個參數代表要打開的攝像頭ID;第二個參數用於監聽攝像頭的狀態;第三個參數代表執行callback的Handler,如果程序希望直接在當前線程中執行callback,則可將handler參數設為null。

當攝像頭被打開之後,程序即可獲取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()方法拍照。

2、自定義相機

經過上面的說明,相信大家對Camera2的接口已經有了一定的了解,不是很清楚不要緊,實踐出真知,我們就開始上代碼啦。

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent">

<TextureView

android:id="@+id/textureView"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignParentStart="true"

android:layout_alignParentTop="true" />

<FrameLayout

android:id="@+id/control"

android:layout_width="match_parent"

android:layout_height="112dp"

android:layout_alignParentBottom="true"

android:layout_alignParentStart="true" //true

android:background="@color/control_background">

<Button

android:id="@+id/picture"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:text="@string/picture" />

</FrameLayout>

</RelativeLayout>

既然只是示例,我們的布局就簡單一些就好,就下來我們先為TextureView設置好它的回調:

@Override

public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {

setupCamera();

openCamera();

}

@Override //1

public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {

} // 3

@Override //2

public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {

return false;

} //4

@Override //3

public void onSurfaceTextureUpdated(SurfaceTexture surface) {

} //12

我們這個案例主要是為了介紹如何用Camera2實現拍照,所以關於尺寸大小適配的處理就不多做了,所以我們就在onSurfaceTextureSizeChanged()中設置並打開Camera。

private void setupCamera() {

//獲取攝像頭的管理者CameraManager

CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);

try {

//遍歷所有攝像頭

for (String id : manager.getCameraIdList()) {

CameraCharacteristics characteristics = manager.getCameraCharacteristics(id);

//默認打開後置攝像頭

if (characteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT)

continue;

//獲取StreamConfigurationMap,它是管理攝像頭支持的所有輸出格式和尺寸

StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);

// 對於靜態圖像捕獲,我們使用最大的可用尺寸。

mPreviewSize = Collections.max(

Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)),

new Comparator<Size>() {

@Override

public int compare(Size lhs, Size rhs) {

return Long.signum(lhs.getWidth() * lhs.getHeight()

- rhs.getHeight() * rhs.getWidth());

}

});

mCameraId = id;

break;

}

} catch (CameraAccessException e) {

e.printStackTrace();

}

} // 1

我們這裡就啟用後置攝像頭,setupCamera()我們就是設置圖像尺寸並獲得攝像頭ID,方便我們在openCamera()中使用。

private void openCamera() {

//獲取攝像頭的管理者CameraManager 1

CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); // 2

//檢查權限

try { // try 1

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {

return;

}//6666

//打開相機,第一個參數指示打開哪個攝像頭,第二個參數stateCallback為相機的狀態回調接口,第三個參數用來確定Callback在哪個線程執行,為null的話就在當前線程執行

manager.openCamera(mCameraId, stateCallback, null);

} catch (CameraAccessException e) {//1001

e.printStackTrace();//rr

}//8888

} //2

這樣我們算是完成了第一步,按照流程圖接下來就是啟用我們設備的回調開始預覽:

private final CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {

@Override

public void onOpened(CameraDevice camera) {

mCameraDevice = camera;

//開啟預覽

startPreview();

}//9999

@Override //111

public void onDisconnected(CameraDevice camera) {

}//11111

@Override //22222

public void onError(CameraDevice camera, int error) {

}//22222

};

mCameraDevice是我設置的CameraDevice對象,現在給它初始化,我們知道CameraDevice相當於舊的Camera,所以我們就得到了這個攝像頭。

private void startPreview() {

SurfaceTexture mSurfaceTexture = mPreviewView.getSurfaceTexture();

//設置TextureView的緩衝區大小

mSurfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());

//獲取Surface顯示預覽數據

Surface mSurface = new Surface(mSurfaceTexture);

setupImageReader();

//獲取ImageReader的Surface

Surface imageReaderSurface = mImageReader.getSurface();

try {//1111

//創建CaptureRequestBuilder,TEMPLATE_PREVIEW比表示預覽請求

mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);

//設置Surface作為預覽數據的顯示界面

mPreviewBuilder.addTarget(mSurface);

//創建相機捕獲會話,第一個參數是捕獲數據的輸出Surface列表,第二個參數是CameraCaptureSession的狀態回調接口,當它創建好後會回調onConfigured方法,第三個參數用來確定Callback在哪個線程執行,為null的話就在當前線程執行

mCameraDevice.createCaptureSession(Arrays.asList(mSurface, imageReaderSurface), mSessionStateCallback, null);

} catch (CameraAccessException e) {//ww

e.printStackTrace();//gg

}//33333

} //31

這個方法就是我們實現預覽的關鍵,我們設置好了Surface就把它與CaptureRequestBuilder對象關聯,然後就是設置會話開始捕獲畫面。

private CameraCaptureSession.StateCallback mSessionStateCallback = new CameraCaptureSession.StateCallback() {

@Override //3333

public void onConfigured(CameraCaptureSession session) {

try {

//創建捕獲請求

mCaptureRequest = mPreviewBuilder.build();

mPreviewSession = session;

//設置反覆捕獲數據的請求,這樣預覽界面就會一直有數據顯示

mPreviewSession.setRepeatingRequest(mCaptureRequest, mSessionCaptureCallback, mHandler);

} catch (CameraAccessException e) {

e.printStackTrace();

} // 501

}//44444

@Override //4444

public void onConfigureFailed(CameraCaptureSession session) {

}//55555

};//666666

最後的回調CameraCaptureSession.CaptureCallback就給我們設置預覽完成的邏輯處理:

private CameraCaptureSession.CaptureCallback mSessionCaptureCallback = new CameraCaptureSession.CaptureCallback() {

@Override ///555

public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {

super.onCaptureCompleted(session, request, result);

//重啟預覽

restartPreview();

}//66666

};//1212

private void restartPreview() {

try {//2222

//執行setRepeatingRequest方法就行了,注意mCaptureRequest是之前開啟預覽設置的請求

mPreviewSession.setRepeatingRequest(mCaptureRequest, null, mHandler);

} catch (CameraAccessException e) {//ff

e.printStackTrace();//7777

}//77777

} //401

這樣就創建好了,但是要注意的是因為Camera2沒有onPictureTaken()方法,所以我們不能直接獲得圖像數據,這裡我們要用的是ImageReader:

private void setupImageReader() {

//前三個參數分別是需要的尺寸和格式,最後一個參數代表每次最多獲取幾幀數據,本例的2代表ImageReader中最多可以獲取兩幀圖像流

mImageReader = ImageReader.newInstance(mPreviewSize.getWidth(), mPreviewSize.getHeight(), ImageFormat.JPEG, 2);

//監聽ImageReader的事件,當有圖像流數據可用時會回調onImageAvailable方法,它的參數就是預覽幀數據,可以對這幀數據進行處理

mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {

@Override

public void onImageAvailable(ImageReader reader) {

mHandler.post(new ImageSaver(reader.acquireNextImage()));

}//601

}, mHandler);

} // 7

在處理ImageReader我們可以用handler來做:

public class ImageSaver implements Runnable {

private Image mImage;

private File mFile;

public ImageSaver(Image image) {

this.mImage = image;

}//701

@Override //1313

public void run() {

ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();

byte[] bytes = new byte[buffer.remaining()];

buffer.get(bytes);

FileOutputStream output = null;

SimpleDateFormat sdf = new SimpleDateFormat(

"yyyyMMdd_HHmmss",

Locale.US);

String fname = "IMG_" +

sdf.format(new Date())

+ ".jpg";

mFile = new File(getApplication().getExternalFilesDir(null), fname);

try {

output = new FileOutputStream(mFile);

output.write(bytes);

} catch (IOException e) {

e.printStackTrace();

}

finally {

mImage.close();

if (null != output) {

try {

output.close();

} catch (IOException e) {

e.printStackTrace();

}

}//5555

}/1717

}//801

} // 8

這個Run()方法裡做的就是把從Image中獲得的幀數據輸出到指定的文件裡,文件名我們用當前時間來生成。

這樣我們就做好所有的拍照前的設置了,現在只要處理點擊按鈕時進行拍照即可。

private HandlerThread mThreadHandler;

private TextureView mPreviewView;

private Handler mHandler = new Handler();

private CaptureRequest.Builder mPreviewBuilder;

private Button mButton;

private ImageReader mImageReader;

private String mCameraId;

private Size mPreviewSize;

private CameraDevice mCameraDevice;

private CaptureRequest mCaptureRequest;

private CameraCaptureSession mPreviewSession;

private static final SparseIntArray ORIENTATION = new SparseIntArray();

static {

ORIENTATION.append(Surface.ROTATION_0, 90);

ORIENTATION.append(Surface.ROTATION_90, 0);

ORIENTATION.append(Surface.ROTATION_180, 270);

ORIENTATION.append(Surface.ROTATION_270, 180);

} // 9

@Override //4

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_test);

requestCameraPermission();

mThreadHandler = new HandlerThread("CAMERA2");

mThreadHandler.start();

mHandler = new Handler(mThreadHandler.getLooper());

mPreviewView = (TextureView) findViewById(textureView);

mPreviewView.setSurfaceTextureListener(this);

mButton = (Button) findViewById(R.id.picture);

mButton.setOnClickListener(new View.OnClickListener() {

@Override //1414

public void onClick(View v) {

try {//1515

//獲取屏幕方向

int rotation = getWindowManager().getDefaultDisplay().getRotation();

//設置CaptureRequest輸出到mImageReader

//CaptureRequest添加imageReaderSurface,不加的話就會導致ImageReader的onImageAvailable()方法不會回調

mPreviewBuilder.addTarget(mImageReader.getSurface());

//設置拍照方向

mPreviewBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATION.get(rotation));

//聚焦

mPreviewBuilder.set(CaptureRequest.CONTROL_AF_MODE,

CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);

//停止預覽

mPreviewSession.stopRepeating();

//開始拍照,然後回調上面的接口重啟預覽,因為mPreviewBuilder設置ImageReader作為target,所以會自動回調ImageReader的onImageAvailable()方法保存圖片

mPreviewSession.capture(mPreviewBuilder.build(), mSessionCaptureCallback, null);

} catch (CameraAccessException e) {

e.printStackTrace();//1616

}//1818

}//901

});

} //10

這裡要注意的是給ImageReader的surface的設置必須放在拍照這裡,否則再預覽的時候就會不斷的執行handler,將圖像保存下來。

Camera2還有很多的功能,谷歌在給我們提供強大類的時候也讓我們的學習量增大了,所以大家不要認為基本了解Camera2的工作流程就是掌握了Camera2,只有能將其運用到我們的開發中去才算掌握了,這只是你的第一步而已。

相關焦點

  • 如何打通任督二脈?
    小時候看武俠劇,常常聽到男女主角被打通任督二脈,然後功力大增,本來是個低段位的小弱雞,一下子就可以變成一個可以KO一切壞蛋的武林高手。任督二脈被打通了真的可以這麼厲害嗎?是的!真的可以這麼厲害,真的可以這麼神奇!
  • 打通任督二脈與融會貫通
    這篇文章的原本題目為《學習就是打通任督二脈的過程》,之所以改為現在的名稱,主要因為「學習」二字在網際網路更多的被認為是誤人子弟。當然,對於絕大多數人來說,本質上是不愛學習的。不過,既然是「打通任督二脈」,肯定是有一定好處的。先問一個問題:「你們有沒有感受過,打通任督二脈的感覺呢?」
  • 中醫大家詳解「打通任督二脈」
    甘肅40名醫生「打通任督二脈」引發微博熱議  □記者 劉坤     5月23日,甘肅省衛生廳官網掛出「甘肅省醫務人員練真氣40餘人打通任督二脈」的消息,在微博上引起熱議。  那麼人體存不存在「任督二脈」?南京中醫藥大學第二臨床醫學院副院長張建斌接受採訪時說,任脈和督脈都是古代醫者對人體一定認識的表述。在兩千多年前的春秋戰國時期,任脈和督脈的理論就出現了。在《黃帝內經》中,就有好幾個地方提到了「任督二脈」。確切地說,最初的督脈是人們對脊柱的認識,任脈是對女性懷孕以後一些生理變化的認識,最終逐漸演繹到男性。
  • 微信打通任督二脈
    按照江湖上的說法,這便是打通了原本並不交匯的「任督二脈」,內力源源不斷,全身氣息通暢,形成「周天」之勢,習武則事半功倍。對於上線已9年的微信來說,任督二脈也在逐步打通,一條主脈是內容和社交,另一條主脈是商業化,二者原本交匯不多,但在近期,微信生態原本相對獨立的各個組成部分,都快速建立起連接,朋友圈和視頻號、公眾號和視頻號、視頻號和小商店、朋友圈和搜一搜、視頻號和搜一搜,有的是直接打通,有的是間接打通,這讓整個微信生態正在發生一系列奇妙的化學反應。
  • 【「龜鹿二仙膠」,助你打通任督二脈】
    從十歲開始看武俠小說,老陳就老有「打通任督二脈」使得自己功力增進一個甲子的江湖奇遇夢,然後還不知從哪裡學會一句口訣「提會陰,頂百會,舌尖頂上顎,咽津津一口,即可打通任督二脈…」並熟記於心,每天一有時間便會坐在那裡,按照口訣來吐納,運行幾個周天之後,裝模作樣地輕輕吐一口氣,然後痛苦地呲牙,……坐得時間太長了,腿麻,站不起來了…不過倒是學了一樣本事,即使到現在,老陳也可以輕鬆地「五心朝天」,俗稱「雙盤」
  • 任督二脈是什麼高科技?外國人表示看不懂
    一檔國內電視節目中,一個留學生一臉懵逼的問一位學者嘉賓:什麼是科技的任督二脈?因為學者正侃侃而談,目前全球市場,歐美人普遍在忙著印鈔救市,而中國人在推新基建。我們要打通科技的任督二脈。任督二脈是什麼新科技,外國人表示聽不懂?
  • 「任督二脈」穴位真的存在嗎?打通後對身體有什麼好處!
    在我們的日常生活中,看古裝電視劇的時候,經常會看到一些,功夫高手打通任督二脈之後,就會變得非常厲害。讓他們的功力大增,所以很多人在小時候經常學古裝劇中俠客的樣子盤膝打坐。後來才知道,那只是古裝裡的情節,現實中的人身上,到底有沒有任督二脈呢?那打通任督二脈之後,又有什麼感覺呢?
  • 如何打通英語學習的「任督二脈」?
    文/謝侃大家好,很多同學說,平時看了很多英語(輸入),但是自己就是用不出來(輸出),原因很簡單,沒有打通英語學習的「任督二脈」。自行理解並翻譯:內心強大的人們不會用時間來執拗於過去,也不會希冀局面有所改變。他們了解自己的過往,清楚充中學到了什麼。然而,他們不會重蹈覆轍或留戀過往的美好。相反,他們會活在當下,計劃未來。」2. 分析和總結裡面的好詞好句,做好摘錄和註解。
  • 研究督脈26年專家:中醫無打通任督二脈說法
    任督二脈經絡圖  5月23日,甘肅省衛生廳官網掛出「甘肅省醫務人員練真氣 40餘人打通任督二脈」的消息,引發了一系列爭議。  任督二脈究竟在人體中有什麼作用?究竟「打通任督二脈」一說如何而來,對人體健康又會產生什麼影響?昨天,記者採訪了我國研究督脈26年的針灸科專家,南京中醫藥大學第二臨床醫學院副院長張建斌。
  • 如何打通書法5體的任督二脈?
    田英章和田蘊章被稱為「二田」,其中田英章被譽為歐楷第一,田蘊章被稱為津門第一,但同時二人也飽受爭議,讚揚者有之,批評者也不計其數。誇讚者稱田英章的結構無人能及,楷書結構嚴謹、標準美觀,相比於當今醜書,田英章和田蘊章的書法才是真正的書法,批評者則認為「二田」的書法太過於甜俗,一點也不高雅,把歐體的險絕給寫沒有了,只剩下平正和呆板,是另一種醜書,俗書。
  • 第十一天 第二個習慣 打通數位樞紐的任督二脈
    結果,最多人使用印象筆記,接著是時間管理手帳(紙本),更其次是Omnifocus、滴答清單等,最後則有為知筆記、日事清、有道雲、MLO(MyLifeOrganized)等工具,當然也有人不知道他的時間管理工具為何,也成了一個小組。
  • 任督二脈在現實生活中真的存在嗎?打通後是不是也能飛簷走壁?
    想必大家都聽過「打通任督二脈」吧!它常出現在武俠小說裡,但它也真實存在。任督二脈是中醫理論的一部分,屬於「經脈」中的「奇經」。因具有明確穴位,醫家將其與十二正經脈合稱為「十四經」。經絡系統是人體內溝通表裡內外, 聯繫上下左右, 網絡周身前後, 將五臟六腑, 五官九竅, 四肢百骸, 筋脈肌膚連成一體的組織結構, 同時也是氣化單元,人體氣血的通道。經絡系統包含了經脈和絡脈。由十二經脈,奇經八脈、十二經別、十五絡脈、十二經筋、十二皮部共同組成。
  • 練這個道家功法可讓你快速打通任督二脈,疾病,衰老統統一邊去
    人體的任督二脈,是除了十二條經絡以外、屬於八脈道中的人體「物元」組織結構。物元,也就是指單純使用西式外求法但目前還暫時無法準確定義的物體構造。任督二脈是八脈道中在人體最淺表的兩條經脈,生理功能同樣是能量的傳輸路徑。
  • 企航楊彥濤:打通中小企業的發展期與成長期「任督二脈」
    企業發展分為四大周期,發展期、成長期、成熟期及衰退期,對中小企業而言,發展期到成長期至關重要,是真正適應市場與用戶,企業內部因素與外部因素維度擴大的開端,而大部分中小企業因無法跨越而消失,因此打通發展期與成長期的「任督二脈」成為企業能否發展壯大的第一道門檻,企航管理董事長楊彥濤專註解決中小企業發展難題,成為行業內的「老中醫」。
  • 莊子教你一法打通任督二脈,疏通全身經絡,全是乾貨,受益匪淺
    「緣督以為經」的這個「督」要搞清楚,才能領會莊子這段話的精華所在。這個「督」不是我們今天講的「任督二脈」的「督脈」。「任督二脈」一詞來源於《黃帝內經》。而《黃帝內經》成書於漢朝,比莊子要晚得多。「督」的本意是「總管」、「統領」「正中」「中央」。比如「總督」、「都督」、「巡督」。在三國以前,古代官職帶「督」字的都是中央核心首領。
  • 教你打通任督二脈《龍訣》成長體系一覽
    想打通任督二脈,首先需要一本武林秘籍。熔煉可將不需要的裝備轉化為人物屬性,變廢為寶;培養是通過消耗「秘傳之捲軸」來提高人物屬性;天賦則是使用天書來領悟,給人物增加各種有益的被動狀態。功夫不負有心人,如果你好好研讀武林秘籍,努力通過成長體系中的各種玩法打通任督二脈,就能迅速增加戰力,成為武林高手。到時候,別說超越基友了,領跑全服都不在話下!
  • 貫通任督二脈,給寶寶做這幾個穴位
    山東良醫職業培訓學校:學中醫 到良醫 結緣中醫在良醫金庸老先生推廣了中醫的任督二脈,說的是人體兩條重要的經脈,前後相應,往復循環。打通任督二脈為了提升孩子的免疫力,可以選擇督脈和任脈的一些穴位,起到貫通任督二脈的作用,家長可以嘗試一下。第一步:背部捏脊。捏脊是很重要的保健操作,可以調理脾胃,也可以調理肺衛,既可以刺激穴位經絡,也可以滲透臟腑。沿督脈和膀胱經操作,既可以上捏,也可以下捏,以向上捏為主。
  • 濟南一大媽晨練,網友:這是在打通任督二脈嗎?
    很多人都知道大媽這個稱呼,一般印象是多金、喜歡搶購、跳廣場舞,反正是有錢又有閒的人,生活愜意,但是有些大媽也常常做出一些驚人之舉。近日,濟南一位大媽倒掛在樹上晨練,讓人看了自愧不如,感覺就像在打通任督二脈一樣。
  • 讓網際網路產品打通英語學習「任督二脈」
    這樣才能讓網際網路產品打通英語學習『任督二脈』---完整場景和純正口語。」伴魚少兒英語創始人兼CEO黃河如是說。如何把英語學習覆蓋日常生活應用場景的各個方面,讓孩子們像學母語一樣學習英語,幫助孩子們更加自然地將英語運用到實際生活中,這是英語教育的重要一環。
  • 高鐵新城即將崛起 打通宜興發展「任督二脈」
    原標題:高鐵新城即將崛起 打通宜興發展「任督二脈」   日前,宜興召開高鐵新城城市設計匯報會,市民關注的高鐵新城輪廓初現。位於宜城、丁蜀兩大城區之間的高鐵新城被初步定位為宜興生態旅遊的展示和集散中心,高鐵新城的崛起將把丁蜀和宜城連成一片,和陶都陶瓷城、陽羨、竹海景區等有機整合,形成整體,並與東氿新城商圈、城北商圈並立,環繞市區眾星拱月,奠定區域性商貿中心城市的基礎,打通宜興發展的「任督二脈」。