<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Android Camera2 拍照流程

          共 23749字,需瀏覽 48分鐘

           ·

          2021-08-05 12:18

          和你一起終身學習,這里是程序員Android

          經典好文推薦,通過閱讀本文,您將收獲以下知識點:

          一、Camera 2 介紹
          二、Camera2包架構示意圖
          三、 Camera2 的 主要類:
          四、相機預覽與拍照流程

          一、Camera 2 介紹

          camera2 API 的加入是從AndroidV5.0(21)開始的,因此我們使用Camera2應該是在Android 5.0(含5.0)之后。同時,對于Android6.0我們需要有動態(tài)權限的管理。這兩點應該是使用Camera2使用前的最基本認知。Android 5.0對拍照API進行了全新的設計,新增了全新設計的Camera v2 API,這些API不僅大幅提高了Android系統(tǒng)拍照的功能,還能支持RAW照片輸出,甚至允許程序調整相機的對焦模式、曝光模式、快門等。下面不做過多介紹了,直接開擼了。

          二、Camera2包架構示意圖

          我們先來看看 camera2包架構示意圖(不用一下子理解,只需要有個整體印象):


          image.png

          這里引用了管道的概念將安卓設備和攝像頭之間聯(lián)通起來,系統(tǒng)向攝像頭發(fā)送 Capture 請求,而攝像頭會返回 CameraMetadata。這一切建立在一個叫作 CameraCaptureSession 的會話中。

          三、 Camera2 的 主要類:

          3.1 CameraManager:

          攝像頭管理器。這是一個全新的系統(tǒng)管理器,專門用于檢測系統(tǒng)攝像頭、打開系統(tǒng)攝像頭。另外,調用CameraManager的getCameraCharacteristics(String cameraId)方法即可獲取指定攝像頭的相關特性。

          3.2 CameraCharacteristics:

          攝像頭特性。該對象通過CameraManager來獲取,用于描述特定攝像頭所支持的各種特性。類似與原來的CameraInfo 。

          3.3 CameraDevice:

          代表系統(tǒng)攝像頭。該類的功能類似于早期的Camera類。而每個CameraDevice自己會負責創(chuàng)建CameraCaptureSession 以及建立 CaptureRequest。

          3.4 CameraCaptureSession:

          這是一個非常重要的API,當程序需要預覽、拍照時,都需要先通過該類的實例創(chuàng)建Session。而且不管預覽還是拍照,也都是由該對象的方法進行控制的,其中控制預覽的方法為setRepeatingRequest();控制拍照的方法為capture()。為了監(jiān)聽CameraCaptureSession的創(chuàng)建過程,以及監(jiān)聽CameraCaptureSession的拍照過程,Camera-v2-API為CameraCaptureSession提供了StateCallback、CaptureCallback等內部類。

          3.5 CameraRequest和CameraRequest.Builder:

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

          四、相機預覽與拍照流程

          如果你看不太懂流程圖,沒關系,待會兒我們通過代碼就可以更好的理解了。首先,Google官方推薦的Camera2控制拍照的步驟大致如下。

          4.1 Camera2拍照的步驟

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

          (2)當攝像頭被打開之后會回調接口mStateCallback.onOpened,程序即可獲取CameraDevice —— 即根據攝像頭ID獲取了指定攝像頭設備,然后調用CameraDevice的createCaptureSession(List outputs, CameraCaptureSession. StateCallback callback,Handler handler)方法來創(chuàng)建CameraCaptureSession。該方法的第一個參數是一個List集合,封裝了所有需要從該攝像頭獲取圖片的Surface,第二個參數用于監(jiān)聽CameraCaptureSession的創(chuàng)建過程;第三個參數代表執(zhí)行callback的Handler,如果程序希望直接在當前線程中執(zhí)行callback,則可將handler參數設為null。

          (3)不管預覽還是拍照,程序都調用CameraDevice的createCaptureRequest(int templateType)方法創(chuàng)建CaptureRequest.Builder,該方法支持TEMPLATE_PREVIEW(預覽)、TEMPLATE_RECORD(拍攝視頻)、TEMPLATE_STILL_CAPTURE(拍照)等參數。

          (4)通過第3步所調用方法返回的CaptureRequest.Builder設置拍照的各種參數,比如對焦模式、曝光模式等。

          (5)調用CaptureRequest.Builder的build()方法即可得到CaptureRequest對象,接下來程序可通過CameraCaptureSession的setRepeatingRequest()方法開始預覽,或調用capture()方法拍照。相機的預覽與拍照流程我們基本了解了。

          (6)預覽時,是將mSurfaceHolder.getSurface()作為目標,使用setRepeatingRequest()方法,顯示拍照結果時,是將mImageReader.getSurface()作為目標,使用capture()方法。

          然后這里還有一個大招:Google官方Camera2拍照的demo的地址:點擊跳轉github

          4.2 首先是我們的layout代碼

          首先權限不能忘:

          uses-permission android:name=”android.permission.CAMERA” / 
          uses-feature android:name=”android.hardware.camera” /
          uses-feature android:name=”android.hardware.camera.autofocus” /

          <?xml version="1.0" encoding="utf-8"?>
          <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:orientation="vertical"
          android:layout_width="match_parent"
          android:layout_height="match_parent">


          <TextureView
          android:id="@+id/texture"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:layout_weight="1"/>


          <LinearLayout
          android:orientation="horizontal"
          android:layout_width="match_parent"
          android:layout_height="wrap_content">

          <Button
          android:layout_width="0dp"
          android:layout_height="wrap_content"
          android:layout_weight="1"
          android:id="@+id/cancelButton"
          android:text="取消"
          android:visibility="invisible"/>

          <Button
          android:layout_width="0dp"
          android:layout_height="wrap_content"
          android:layout_weight="1"
          android:id="@+id/captureButton"
          android:text="拍照"
          android:visibility="visible"/>

          <Button
          android:layout_width="0dp"
          android:layout_height="wrap_content"
          android:layout_weight="1"
          android:id="@+id/saveButton"
          android:text="保存"
          android:visibility="invisible"/>

          </LinearLayout>
          </LinearLayout>

          4.3 實現代碼

          public class customCarmeraActivity extends AppCompatActivity {

          private static final int REQUEST_CAMERA_PERMISSION = 1;

          private static final int STATE_PREVIEW = 1;
          private static final int STATE_WAITING_PRECAPTURE = 2;
          private int mState = STATE_PREVIEW;

          private static final SparseIntArray ORIENTATIONS = new SparseIntArray();

          ///為了使照片豎直顯示
          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 CameraManager mCameraManagerm;
          private CameraDevice mCameraDevice;
          private String mCameraId;
          private HandlerThread mBackgroundThread;
          private Handler mBackgroundHandler;

          private TextureView mTextureView;

          private ImageReader mImageReader;
          private File mFile;

          private CaptureRequest.Builder mPreviewBuilder;
          private CaptureRequest mPreviewRequest;
          private CameraCaptureSession mCaptureSession;


          private Semaphore mCameraOpenCloseLock = new Semaphore(1);

          /**
          * Starts a background thread and its {@link Handler}.
          */

          private void startBackgroundThread() {
          mBackgroundThread = new HandlerThread("CameraBackground");
          mBackgroundThread.start();
          mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
          }

          /**
          * Stops the background thread and its {@link Handler}.
          */

          private void stopBackgroundThread() {
          mBackgroundThread.quitSafely();
          try {
          mBackgroundThread.join();
          mBackgroundThread = null;
          mBackgroundHandler = null;
          } catch (InterruptedException e) {
          e.printStackTrace();
          }
          }

          /**
          *
          * @TextureView.SurfaceTextureListener:public static interface
          * @onSurfaceTextureAvailable:Invoked when a TextureView's SurfaceTexture is ready for use.
          * @onSurfaceTextureSizeChanged:Invoked when the SurfaceTexture's buffers size changed.
          * @onSurfaceTextureDestroyed:Invoked when the specified SurfaceTexture is about to be destroyed.
          * @onSurfaceTextureUpdated:Invoked when the specified SurfaceTexture is updated through updateTexImage().
          */

          private final TextureView.SurfaceTextureListener mSurfaceTextureListener = new TextureView.SurfaceTextureListener() {
          @Override
          public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {
          openCamera(width, height);
          }

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

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

          @Override
          public void onSurfaceTextureUpdated(SurfaceTexture texture) {
          }
          };

          /**
          * Shows a {@link Toast} on the UI thread.
          *
          * @param text The message to show
          */

          private void showToast(final String text) {
          runOnUiThread(new Runnable() {
          @Override
          public void run() {
          Toast.makeText(customCarmeraActivity.this, text, Toast.LENGTH_SHORT).show();
          }
          });
          }


          /**
          * Capture a still picture. This method should be called when we get a response in
          * {@link #mCaptureCallback} from both {@link #lockFocus()}.
          */

          private void captureStillPicture() {
          try {
          if (null == mCameraDevice) {
          return;
          }
          // This is the CaptureRequest.Builder that we use to take a picture.
          final CaptureRequest.Builder captureBuilder =
          mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
          captureBuilder.addTarget(mImageReader.getSurface());//拍照時,是將mImageReader.getSurface()作為目標

          // Use the same AE and AF modes as the preview.
          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);
          // Orientation
          int rotation = getWindowManager().getDefaultDisplay().getRotation();
          captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));

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

          @Override
          public void onCaptureCompleted(@NonNull CameraCaptureSession session,
          @NonNull CaptureRequest request,
          @NonNull TotalCaptureResult result) {
          showToast("Saved: " + mFile);

          //Log.d("customCarmeraActivity", mFile.toString());
          unlockFocus();//恢復預覽
          }
          };

          mCaptureSession.stopRepeating();
          mCaptureSession.abortCaptures();
          mCaptureSession.capture(captureBuilder.build(), CaptureCallback, null);
          } catch (CameraAccessException e) {
          e.printStackTrace();
          }
          }


          private CameraCaptureSession.CaptureCallback mCaptureCallback =
          new CameraCaptureSession.CaptureCallback() {
          @Override
          public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
          TotalCaptureResult result) {
          //Log.d("linc","mSessionCaptureCallback, onCaptureCompleted");
          mCaptureSession = session;
          checkState(result);
          }

          @Override
          public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request,
          CaptureResult partialResult) {
          Log.d("linc","mSessionCaptureCallback, onCaptureProgressed");
          mCaptureSession = session;
          checkState(partialResult);
          }

          private void checkState(CaptureResult result) {
          switch (mState) {
          case STATE_PREVIEW:
          // We have nothing to do when the camera preview is working normally.
          break;
          case STATE_WAITING_PRECAPTURE:
          Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
          if (afState == null) {
          captureStillPicture();
          } else if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState || CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState) {
          // CONTROL_AE_STATE can be null on some devices
          Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
          if (aeState == null || aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) {
          //mState = STATE_PICTURE_TAKEN;
          captureStillPicture();
          } else {
          //runPrecaptureSequence();//視頻拍攝
          }
          }
          break;
          }
          }

          };
          private void createCameraPreviewSession() {
          try {
          SurfaceTexture texture = mTextureView.getSurfaceTexture();
          //assert(texture != null);

          // We configure the size of default buffer to be the size of camera preview we want.
          texture.setDefaultBufferSize(mTextureView.getWidth(), mTextureView.getHeight());
          // This is the output Surface we need to start preview.
          Surface surface = new Surface(texture);

          mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
          mPreviewBuilder.addTarget(surface);//預覽時,是將Surface()作為目標
          mState = STATE_PREVIEW;
          mCameraDevice.createCaptureSession(
          Arrays.asList(surface, mImageReader.getSurface()),
          new CameraCaptureSession.StateCallback() {
          @Override
          public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
          // The camera is already closed
          if (null == mCameraDevice) {
          return;
          }
          mCaptureSession = cameraCaptureSession;
          try {
          mPreviewBuilder.set(CaptureRequest.CONTROL_AF_MODE,
          CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
          mPreviewBuilder.set(CaptureRequest.CONTROL_AE_MODE,
          CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
          mPreviewRequest = mPreviewBuilder.build();
          mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback, mBackgroundHandler);
          } catch (CameraAccessException e) {
          e.printStackTrace();
          Log.e("linc","set preview builder failed."+e.getMessage());
          }
          }

          @Override
          public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
          Toast.makeText(customCarmeraActivity.this, "Camera configuration Failed", Toast.LENGTH_SHORT).show();
          }
          },mBackgroundHandler);
          } catch (CameraAccessException e) {
          e.printStackTrace();
          }
          }
          /**
          *
          * @CameraDevice.StateCallback:public static abstract class
          * @onOpened:This method is called when the camera is opened. We start camera preview here.
          * @onDisconnected:The method called when a camera device is no longer available for use.
          * @onError:The method called when a camera device has encountered a serious error.
          */

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

          @Override
          public void onOpened(CameraDevice cameraDevice) {
          mCameraOpenCloseLock.release();
          mCameraDevice = cameraDevice;
          createCameraPreviewSession();
          }

          @Override
          public void onDisconnected(CameraDevice cameraDevice) {
          mCameraOpenCloseLock.release();
          cameraDevice.close();
          mCameraDevice = null;
          }

          @Override
          public void onError(CameraDevice cameraDevice, int error) {
          mCameraOpenCloseLock.release();
          cameraDevice.close();
          mCameraDevice = null;
          }
          };

          private void getCameraId() {
          try {
          //Return the list of currently connected camera devices by identifier, including cameras that may be in use by other camera API clients
          for (String cameraId : mCameraManagerm.getCameraIdList()) {
          //Query the capabilities of a camera device
          CameraCharacteristics characteristics = mCameraManagerm.getCameraCharacteristics(cameraId);
          if (characteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT) {
          continue;
          }
          mCameraId = cameraId;
          return;
          }
          } catch (CameraAccessException e) {
          e.printStackTrace();
          }
          }

          /**
          * Saves a JPEG {@link Image} into the specified {@link File}.
          */

          private static class ImageSaver implements Runnable {

          /**
          * The JPEG image
          */

          private final Image mImage;
          /**
          * The file we save the image into.
          */

          private final File mFile;

          ImageSaver(Image image, File file) {
          mImage = image;
          mFile = file;
          }

          @Override
          public void run() {
          ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
          byte[] bytes = new byte[buffer.remaining()];
          buffer.get(bytes);
          FileOutputStream output = null;
          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();
          }
          }
          }
          }
          }

          private final ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {
          @Override
          public void onImageAvailable(ImageReader reader) {
          //showToast("onImageAvailable: " );
          mBackgroundHandler.post(new ImageSaver(reader.acquireNextImage(), mFile));
          }
          };
          //TODO 執(zhí)行完上面的請求權限后,系統(tǒng)會彈出提示框讓用戶選擇是否允許改權限。選擇的結果可以在回到接口中得知:
          @Override
          public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
          if (requestCode == REQUEST_CAMERA_PERMISSION) {
          if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
          //用戶允許改權限,0表示允許,-1表示拒絕 PERMISSION_GRANTED = 0, PERMISSION_DENIED = -1
          //permission was granted, yay! Do the contacts-related task you need to do.
          //這里進行授權被允許的處理
          } else {
          //permission denied, boo! Disable the functionality that depends on this permission.
          //這里進行權限被拒絕的處理
          }
          } else {
          super.onRequestPermissionsResult(requestCode, permissions, grantResults);
          }
          }
          /**
          * Opens the camera specified by {@link Camera2BasicFragment#mCameraId}.
          */

          private void openCamera(int width, int height) {
          //檢查相機服務的訪問權限
          if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
          //Toast.makeText(this,"Lacking privileges to access camera service, please request permission first",Toast.LENGTH_SHORT).show();
          Log.e("customCarmeraActivity.openCamera","Lacking privileges to access camera service, please request permission first");
          ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);//API21后,向用戶請求相機使用權限,然后執(zhí)行onRequestPermissionsResult回調
          return;
          }

          getCameraId();
          //assert(mCameraId != null);

          mImageReader = ImageReader.newInstance(width, height, ImageFormat.JPEG,/*maxImages*/7);
          mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler);

          try {
          if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
          throw new RuntimeException("Time out waiting to lock camera opening.");
          }
          mCameraManagerm.openCamera(mCameraId, mStateCallback, mBackgroundHandler);
          } catch (CameraAccessException e) {
          e.printStackTrace();
          } catch (InterruptedException e) {
          throw new RuntimeException("Interrupted while trying to lock camera opening.", e);
          }
          }
          /**
          * Closes the current {@link CameraDevice}.
          */

          private void closeCamera() {
          try {
          mCameraOpenCloseLock.acquire();
          if (null != mCaptureSession) {
          mCaptureSession.close();
          mCaptureSession = null;
          }
          if (null != mCameraDevice) {
          mCameraDevice.close();
          mCameraDevice = null;
          }
          if (null != mImageReader) {
          mImageReader.close();
          mImageReader = null;
          }
          } catch (InterruptedException e) {
          throw new RuntimeException("Interrupted while trying to lock camera closing.", e);
          } finally {
          mCameraOpenCloseLock.release();
          }
          }
          /**
          * Unlock the focus. This method should be called when still image capture sequence is
          * finished.
          */

          private void unlockFocus() {
          try {
          // Reset the auto-focus trigger
          mPreviewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
          CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
          mPreviewBuilder.set(CaptureRequest.CONTROL_AE_MODE,
          CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
          /* mCaptureSession.capture(mPreviewBuilder.build(), mCaptureCallback,
          mBackgroundHandler);*/

          // After this, the camera will go back to the normal state of preview.
          mState = STATE_PREVIEW;
          mCaptureSession.setRepeatingRequest(mPreviewBuilder.build(), mCaptureCallback, mBackgroundHandler);
          } catch (CameraAccessException e) {
          e.printStackTrace();
          }
          }


          /**
          * Lock the focus as the first step for a still image capture.
          */

          private void lockFocus() {
          try {
          // This is how to tell the camera to lock focus.
          mPreviewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
          CameraMetadata.CONTROL_AF_TRIGGER_START);
          // Tell #mCaptureCallback to wait for the lock.
          mState = STATE_WAITING_PRECAPTURE;
          mCaptureSession.capture(mPreviewBuilder.build(), mCaptureCallback,
          mBackgroundHandler);
          } catch (CameraAccessException e) {
          e.printStackTrace();
          }
          }

          @Override
          protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.custom_carmera_layout);

          mCameraManagerm = (CameraManager)getSystemService(Context.CAMERA_SERVICE);
          mTextureView = (TextureView)findViewById(R.id.textureview);

          mFile = new File(getExternalFilesDir(null), "pic.jpg");

          Button tackPictureBtn = (Button)findViewById(R.id.takePictureButton);
          tackPictureBtn.setOnClickListener(new View.OnClickListener(){
          @Override
          public void onClick(View view) {
          //Log.i("linc", "take picture");
          lockFocus();
          }
          });
          }

          @Override
          protected void onResume() {
          super.onResume();
          startBackgroundThread();

          if(mTextureView.isAvailable()) {
          openCamera(mTextureView.getWidth(), mTextureView.getHeight());
          } else{
          mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
          }
          }

          @Override
          protected void onPause() {
          super.onPause();
          closeCamera();
          stopBackgroundThread();
          }
          }

          參考鏈接:https://blog.csdn.net/zhangzheng_1986/article/details/78710655

          友情推薦:

          Android 開發(fā)干貨集錦

          至此,本篇已結束。轉載網絡的文章,小編覺得很優(yōu)秀,歡迎點擊閱讀原文,支持原創(chuàng)作者,如有侵權,懇請聯(lián)系小編刪除,歡迎您的建議與指正。同時期待您的關注,感謝您的閱讀,謝謝!

          點個在看,方便您使用時快速查找!

          瀏覽 109
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  操逼视频动漫 | 丝袜足交亚洲 | 成人三级视频久久 | 亚洲欧美色图 | 精品人妻无码在线 |