【问题标题】:Take a picture in iOS without UIImagePicker and without preview it在没有 UIImagePicker 且没有预览的情况下在 iOS 中拍照
【发布时间】:2012-12-20 13:02:30
【问题描述】:

您知道在 iOS 中拍照并将其保存到相机胶卷的任何方式/方法吗?只需按一下按钮而不显示任何预览?

我已经知道如何显示相机视图,但它显示图像的预览,用户需要单击拍照按钮才能拍照。

简而言之:用户点击按钮,照片被拍摄,没有预览也没有仔细检查来拍摄/保存照片。

我已经找到UIIMagePickerControllerhttp://developer.apple.com/library/ios/documentation/uikit/reference/UIImagePickerController_Class/UIImagePickerController/UIImagePickerController.html#//apple_ref/occ/instm/UIImagePickerController/takePicturetakePicture方法

【问题讨论】:

  • 您能否发布一些代码,以便读者可以看到您是如何尝试实现此功能的?
  • indieambitions.com/code-snippits/… 是一个关于如何使用 AVFoundation 和 Core Image 保存图像的教程。仅使用 UIImagePickerController 无法完成您尝试做的事情。
  • 我只希望当单击 X 按钮时,必须拍摄照片并将其保存到相机胶卷,如下所示:- (IBAction)demoBtn:(id)sender { NSLog(@"Take Picture") ; }
  • 我已经在这里写了答案stackoverflow.com/a/62947941/2941150

标签: objective-c ios photo


【解决方案1】:

showsCameraControls-属性设置为NO

    poc = [[UIImagePickerController alloc] init];
    [poc setTitle:@"Take a photo."];
    [poc setDelegate:self];
    [poc setSourceType:UIImagePickerControllerSourceTypeCamera];
    poc.showsCameraControls = NO;

您还必须将自己的控件添加为poc.view 顶部的自定义视图。但这很简单,您可以通过这种方式添加自己的 UI 样式。

您通常会在imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo: 中接收图像数据

要拍照,请致电

[poc takePicture];

来自您的自定义按钮。

希望,这对你有用。

【讨论】:

  • 谢谢,这是我要找的。​​span>
  • 您好,您对在不打开相机控件的情况下拍摄视频有任何想法吗?谢谢
【解决方案2】:

假设您想要一个傻瓜式方法,您可以创建一个 AVSession 并调用 UIImageWriteToSavedPhotosAlbum 方法。 这是进入该确切过程的链接:http://www.musicalgeometry.com/?p=1297

还值得注意的是,您的用户需要授予应用访问他们的相机胶卷的权限,否则您可能会在保存图像时遇到问题。

【讨论】:

    【解决方案3】:

    您需要根据您的尺寸设计自己的自定义预览,按下捕获按钮并调用buttonPressed 方法并做您想做的事情

    (void)buttonPressed:(UIButton *)sender {
    
        NSLog(@" Capture Clicked");
    
        [self.imagePicker takePicture];
    
        //[NSTimer scheduledTimerWithTimeInterval:3.0f target:self
                                      selector:@selector(timerFired:) userInfo:nil repeats:NO];
    }
    

    【讨论】:

      【解决方案4】:

      以下代码将在不显示预览屏幕的情况下拍照。当我尝试使用 UIImagePickerController 接受的答案时,预览屏幕显示,然后自动消失。使用下面的代码,用户点击“拍照”按钮,设备拍照时对 UI 进行零更改(在我的应用程序中,我在拍照按钮旁边添加了一个绿色复选标记)。下面的代码来自苹果https://developer.apple.com/LIBRARY/IOS/samplecode/AVCam/Introduction/Intro.html,注释掉了“额外功能”(与拍摄静态照片无关)。感谢 incmiko 在您的回答 iOS take photo from camera without modalViewController 中建议此代码。

      更新代码,2015 年 3 月 26 日:

      触发快照:

      [self snapStillImage:sender];
      

      在 .h 文件中:

      #import <AVFoundation/AVFoundation.h>
      #import <AssetsLibrary/AssetsLibrary.h>
      
      
      // include code below in header file, after #import and before @interface
      // avfoundation copy paste code
      static void * CapturingStillImageContext = &CapturingStillImageContext;
      static void * RecordingContext = &RecordingContext;
      static void * SessionRunningAndDeviceAuthorizedContext = &SessionRunningAndDeviceAuthorizedContext;
      
      // avfoundation, include code below after @interface
      // avf - Session management.
      @property (nonatomic) dispatch_queue_t sessionQueue; // Communicate with the session and other session objects on this queue.
      @property (nonatomic) AVCaptureSession *session;
      @property (nonatomic) AVCaptureDeviceInput *videoDeviceInput;
      @property (nonatomic) AVCaptureMovieFileOutput *movieFileOutput;
      @property (nonatomic) AVCaptureStillImageOutput *stillImageOutput;
      
      // avf - Utilities.
      @property (nonatomic) UIBackgroundTaskIdentifier backgroundRecordingID;
      @property (nonatomic, getter = isDeviceAuthorized) BOOL deviceAuthorized;
      @property (nonatomic, readonly, getter = isSessionRunningAndDeviceAuthorized) BOOL sessionRunningAndDeviceAuthorized;
      @property (nonatomic) BOOL lockInterfaceRotation;
      @property (nonatomic) id runtimeErrorHandlingObserver;
      

      在 .m 文件中:

      #pragma mark - AV Foundation
      - (BOOL)isSessionRunningAndDeviceAuthorized
      {
          return [[self session] isRunning] && [self isDeviceAuthorized];
      }
      
      + (NSSet *)keyPathsForValuesAffectingSessionRunningAndDeviceAuthorized
      {
          return [NSSet setWithObjects:@"session.running", @"deviceAuthorized", nil];
      }
      
      // call following method from viewDidLoad
      - (void)CreateAVCaptureSession
      {
          // Create the AVCaptureSession
          AVCaptureSession *session = [[AVCaptureSession alloc] init];
          [self setSession:session];
      
          // Check for device authorization
          [self checkDeviceAuthorizationStatus];
      
          // In general it is not safe to mutate an AVCaptureSession or any of its inputs, outputs, or connections from multiple threads at the same time.
          // Why not do all of this on the main queue?
          // -[AVCaptureSession startRunning] is a blocking call which can take a long time. We dispatch session setup to the sessionQueue so that the main queue isn't blocked (which keeps the UI responsive).
      
          dispatch_queue_t sessionQueue = dispatch_queue_create("session queue", DISPATCH_QUEUE_SERIAL);
          [self setSessionQueue:sessionQueue];
      
          dispatch_async(sessionQueue, ^{
              [self setBackgroundRecordingID:UIBackgroundTaskInvalid];
      
              NSError *error = nil;
      
              AVCaptureDevice *videoDevice = [ViewController deviceWithMediaType:AVMediaTypeVideo preferringPosition:AVCaptureDevicePositionFront];
              AVCaptureDeviceInput *videoDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
      
              if (error)
              {
                  NSLog(@"%@", error);
              }
      
              if ([session canAddInput:videoDeviceInput])
              {
                  [session addInput:videoDeviceInput];
                  [self setVideoDeviceInput:videoDeviceInput];
      
                  dispatch_async(dispatch_get_main_queue(), ^{
                      // Why are we dispatching this to the main queue?
                      // Because AVCaptureVideoPreviewLayer is the backing layer for AVCamPreviewView and UIView can only be manipulated on main thread.
                      // Note: As an exception to the above rule, it is not necessary to serialize video orientation changes on the AVCaptureVideoPreviewLayer’s connection with other session manipulation.
                  });
              }
      
              /*      AVCaptureDevice *audioDevice = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio] firstObject];
               AVCaptureDeviceInput *audioDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:&error];
      
               if (error)
               {
               NSLog(@"%@", error);
               }
      
               if ([session canAddInput:audioDeviceInput])
               {
               [session addInput:audioDeviceInput];
               }
               */
              AVCaptureMovieFileOutput *movieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
              if ([session canAddOutput:movieFileOutput])
              {
                  [session addOutput:movieFileOutput];
                  AVCaptureConnection *connection = [movieFileOutput connectionWithMediaType:AVMediaTypeVideo];
                  if ([connection isVideoStabilizationSupported])
                      [connection setEnablesVideoStabilizationWhenAvailable:YES];
                  [self setMovieFileOutput:movieFileOutput];
              }
      
              AVCaptureStillImageOutput *stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
              if ([session canAddOutput:stillImageOutput])
              {
                  [stillImageOutput setOutputSettings:@{AVVideoCodecKey : AVVideoCodecJPEG}];
                  [session addOutput:stillImageOutput];
                  [self setStillImageOutput:stillImageOutput];
              }
          });
      }
      
      // call method below from viewWilAppear
      - (void)AVFoundationStartSession
      {
      
          dispatch_async([self sessionQueue], ^{
              [self addObserver:self forKeyPath:@"sessionRunningAndDeviceAuthorized" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) context:SessionRunningAndDeviceAuthorizedContext];
              [self addObserver:self forKeyPath:@"stillImageOutput.capturingStillImage" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) context:CapturingStillImageContext];
              [self addObserver:self forKeyPath:@"movieFileOutput.recording" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) context:RecordingContext];
              [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(subjectAreaDidChange:) name:AVCaptureDeviceSubjectAreaDidChangeNotification object:[[self videoDeviceInput] device]];
      
              __weak ViewController *weakSelf = self;
              [self setRuntimeErrorHandlingObserver:[[NSNotificationCenter defaultCenter] addObserverForName:AVCaptureSessionRuntimeErrorNotification object:[self session] queue:nil usingBlock:^(NSNotification *note) {
                  ViewController *strongSelf = weakSelf;
                  dispatch_async([strongSelf sessionQueue], ^{
                      // Manually restarting the session since it must have been stopped due to an error.
                      [[strongSelf session] startRunning];
                  });
              }]];
              [[self session] startRunning];
          });
      }
      
      // call method below from viewDidDisappear
      - (void)AVFoundationStopSession
      {
          dispatch_async([self sessionQueue], ^{
              [[self session] stopRunning];
      
              [[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceSubjectAreaDidChangeNotification object:[[self videoDeviceInput] device]];
              [[NSNotificationCenter defaultCenter] removeObserver:[self runtimeErrorHandlingObserver]];
      
              [self removeObserver:self forKeyPath:@"sessionRunningAndDeviceAuthorized" context:SessionRunningAndDeviceAuthorizedContext];
              [self removeObserver:self forKeyPath:@"stillImageOutput.capturingStillImage" context:CapturingStillImageContext];
              [self removeObserver:self forKeyPath:@"movieFileOutput.recording" context:RecordingContext];
          });
      }
      
      - (BOOL)prefersStatusBarHidden
      {
          return YES;
      }
      
      
      - (BOOL)shouldAutorotate
      {
          // Disable autorotation of the interface when recording is in progress.
          return ![self lockInterfaceRotation];
      }
      
      - (NSUInteger)supportedInterfaceOrientations
      {
          return UIInterfaceOrientationMaskAll;
      }
      
      - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
      {
          //  [[(AVCaptureVideoPreviewLayer *)[[self previewView] layer] connection] setVideoOrientation:(AVCaptureVideoOrientation)toInterfaceOrientation];
      }
      
      - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
      {
          if (context == CapturingStillImageContext)
          {
              BOOL isCapturingStillImage = [change[NSKeyValueChangeNewKey] boolValue];
      
              if (isCapturingStillImage)
              {
                  [self runStillImageCaptureAnimation];
              }
          }
          else if (context == RecordingContext)
          {
              BOOL isRecording = [change[NSKeyValueChangeNewKey] boolValue];
      
              dispatch_async(dispatch_get_main_queue(), ^{
                  if (isRecording)
                  {
                      //              [[self cameraButton] setEnabled:NO];
                      //              [[self recordButton] setTitle:NSLocalizedString(@"Stop", @"Recording button stop title") forState:UIControlStateNormal];
                      //              [[self recordButton] setEnabled:YES];
                  }
                  else
                  {
                      //              [[self cameraButton] setEnabled:YES];
                      //              [[self recordButton] setTitle:NSLocalizedString(@"Record", @"Recording button record title") forState:UIControlStateNormal];
                      //              [[self recordButton] setEnabled:YES];
                  }
              });
          }
          else if (context == SessionRunningAndDeviceAuthorizedContext)
          {
              BOOL isRunning = [change[NSKeyValueChangeNewKey] boolValue];
      
              dispatch_async(dispatch_get_main_queue(), ^{
                  if (isRunning)
                  {
                      //              [[self cameraButton] setEnabled:YES];
                      //              [[self recordButton] setEnabled:YES];
                      //              [[self stillButton] setEnabled:YES];
                  }
                  else
                  {
                      //              [[self cameraButton] setEnabled:NO];
                      //              [[self recordButton] setEnabled:NO];
                      //              [[self stillButton] setEnabled:NO];
                  }
              });
          }
          else
          {
              [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
          }
      }
      
      #pragma mark Actions
      
      - (IBAction)toggleMovieRecording:(id)sender
      {
          //  [[self recordButton] setEnabled:NO];
      
          dispatch_async([self sessionQueue], ^{
              if (![[self movieFileOutput] isRecording])
              {
                  [self setLockInterfaceRotation:YES];
      
                  if ([[UIDevice currentDevice] isMultitaskingSupported])
                  {
                      // Setup background task. This is needed because the captureOutput:didFinishRecordingToOutputFileAtURL: callback is not received until AVCam returns to the foreground unless you request background execution time. This also ensures that there will be time to write the file to the assets library when AVCam is backgrounded. To conclude this background execution, -endBackgroundTask is called in -recorder:recordingDidFinishToOutputFileURL:error: after the recorded file has been saved.
                      [self setBackgroundRecordingID:[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil]];
                  }
      
                  // Update the orientation on the movie file output video connection before starting recording.
                  //          [[[self movieFileOutput] connectionWithMediaType:AVMediaTypeVideo] setVideoOrientation:[[(AVCaptureVideoPreviewLayer *)[[self previewView] layer] connection] videoOrientation]];
      
                  // Turning OFF flash for video recording
                  [ViewController setFlashMode:AVCaptureFlashModeOff forDevice:[[self videoDeviceInput] device]];
      
                  // Start recording to a temporary file.
                  NSString *outputFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[@"movie" stringByAppendingPathExtension:@"mov"]];
                  [[self movieFileOutput] startRecordingToOutputFileURL:[NSURL fileURLWithPath:outputFilePath] recordingDelegate:self];
              }
              else
              {
                  [[self movieFileOutput] stopRecording];
              }
          });
      }
      
      - (IBAction)changeCamera:(id)sender
      {
          //  [[self cameraButton] setEnabled:NO];
          //  [[self recordButton] setEnabled:NO];
          //  [[self stillButton] setEnabled:NO];
      
          dispatch_async([self sessionQueue], ^{
              AVCaptureDevice *currentVideoDevice = [[self videoDeviceInput] device];
              AVCaptureDevicePosition preferredPosition = AVCaptureDevicePositionUnspecified;
              AVCaptureDevicePosition currentPosition = [currentVideoDevice position];
      
              switch (currentPosition)
              {
                  case AVCaptureDevicePositionUnspecified:
                      preferredPosition = AVCaptureDevicePositionBack;
                      break;
                  case AVCaptureDevicePositionBack:
                      preferredPosition = AVCaptureDevicePositionFront;
                      break;
                  case AVCaptureDevicePositionFront:
                      preferredPosition = AVCaptureDevicePositionBack;
                      break;
              }
      
              AVCaptureDevice *videoDevice = [ViewController deviceWithMediaType:AVMediaTypeVideo preferringPosition:preferredPosition];
              AVCaptureDeviceInput *videoDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:nil];
      
              [[self session] beginConfiguration];
      
              [[self session] removeInput:[self videoDeviceInput]];
              if ([[self session] canAddInput:videoDeviceInput])
              {
                  [[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceSubjectAreaDidChangeNotification object:currentVideoDevice];
      
                  [ViewController setFlashMode:AVCaptureFlashModeAuto forDevice:videoDevice];
                  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(subjectAreaDidChange:) name:AVCaptureDeviceSubjectAreaDidChangeNotification object:videoDevice];
      
                  [[self session] addInput:videoDeviceInput];
                  [self setVideoDeviceInput:videoDeviceInput];
              }
              else
              {
                  [[self session] addInput:[self videoDeviceInput]];
              }
      
              [[self session] commitConfiguration];
      
              dispatch_async(dispatch_get_main_queue(), ^{
                  //          [[self cameraButton] setEnabled:YES];
                  //          [[self recordButton] setEnabled:YES];
                  //          [[self stillButton] setEnabled:YES];
              });
          });
      }
      
      - (IBAction)snapStillImage:(id)sender
      {
          dispatch_async([self sessionQueue], ^{
              // Update the orientation on the still image output video connection before capturing.
              //      [[[self stillImageOutput] connectionWithMediaType:AVMediaTypeVideo] setVideoOrientation:[[(AVCaptureVideoPreviewLayer *)[[self previewView] layer] connection] videoOrientation]];
      
              // Flash set to Auto for Still Capture
              [ViewController setFlashMode:AVCaptureFlashModeAuto forDevice:[[self videoDeviceInput] device]];
      
              // Capture a still image.
              [[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:[[self stillImageOutput] connectionWithMediaType:AVMediaTypeVideo] completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
      
                  if (imageDataSampleBuffer)
                  {
                      NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
                      UIImage *image = [[UIImage alloc] initWithData:imageData];
      
                      // do someting good with saved image
                      [self saveImageToParse:image];
      
                  }
              }];
          });
      }
      
      - (IBAction)focusAndExposeTap:(UIGestureRecognizer *)gestureRecognizer
      {
          //  CGPoint devicePoint = [(AVCaptureVideoPreviewLayer *)[[self previewView] layer] captureDevicePointOfInterestForPoint:[gestureRecognizer locationInView:[gestureRecognizer view]]];
          //  [self focusWithMode:AVCaptureFocusModeAutoFocus exposeWithMode:AVCaptureExposureModeAutoExpose atDevicePoint:devicePoint monitorSubjectAreaChange:YES];
      }
      
      - (void)subjectAreaDidChange:(NSNotification *)notification
      {
          CGPoint devicePoint = CGPointMake(.5, .5);
          [self focusWithMode:AVCaptureFocusModeContinuousAutoFocus exposeWithMode:AVCaptureExposureModeContinuousAutoExposure atDevicePoint:devicePoint monitorSubjectAreaChange:NO];
      }
      
      #pragma mark File Output Delegate
      
      - (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error
      {
          if (error)
              NSLog(@"%@", error);
      
          [self setLockInterfaceRotation:NO];
      
          // Note the backgroundRecordingID for use in the ALAssetsLibrary completion handler to end the background task associated with this recording. This allows a new recording to be started, associated with a new UIBackgroundTaskIdentifier, once the movie file output's -isRecording is back to NO — which happens sometime after this method returns.
          UIBackgroundTaskIdentifier backgroundRecordingID = [self backgroundRecordingID];
          [self setBackgroundRecordingID:UIBackgroundTaskInvalid];
      
          [[[ALAssetsLibrary alloc] init] writeVideoAtPathToSavedPhotosAlbum:outputFileURL completionBlock:^(NSURL *assetURL, NSError *error) {
              if (error)
                  NSLog(@"%@", error);
      
              [[NSFileManager defaultManager] removeItemAtURL:outputFileURL error:nil];
      
              if (backgroundRecordingID != UIBackgroundTaskInvalid)
                  [[UIApplication sharedApplication] endBackgroundTask:backgroundRecordingID];
          }];
      }
      
      #pragma mark Device Configuration
      
      - (void)focusWithMode:(AVCaptureFocusMode)focusMode exposeWithMode:(AVCaptureExposureMode)exposureMode atDevicePoint:(CGPoint)point monitorSubjectAreaChange:(BOOL)monitorSubjectAreaChange
      {
          dispatch_async([self sessionQueue], ^{
              AVCaptureDevice *device = [[self videoDeviceInput] device];
              NSError *error = nil;
              if ([device lockForConfiguration:&error])
              {
                  if ([device isFocusPointOfInterestSupported] && [device isFocusModeSupported:focusMode])
                  {
                      [device setFocusMode:focusMode];
                      [device setFocusPointOfInterest:point];
                  }
                  if ([device isExposurePointOfInterestSupported] && [device isExposureModeSupported:exposureMode])
                  {
                      [device setExposureMode:exposureMode];
                      [device setExposurePointOfInterest:point];
                  }
                  [device setSubjectAreaChangeMonitoringEnabled:monitorSubjectAreaChange];
                  [device unlockForConfiguration];
              }
              else
              {
                  NSLog(@"%@", error);
              }
          });
      }
      
      + (void)setFlashMode:(AVCaptureFlashMode)flashMode forDevice:(AVCaptureDevice *)device
      {
          if ([device hasFlash] && [device isFlashModeSupported:flashMode])
          {
              NSError *error = nil;
              if ([device lockForConfiguration:&error])
              {
                  [device setFlashMode:flashMode];
                  [device unlockForConfiguration];
              }
              else
              {
                  NSLog(@"%@", error);
              }
          }
      }
      
      + (AVCaptureDevice *)deviceWithMediaType:(NSString *)mediaType preferringPosition:(AVCaptureDevicePosition)position
      {
          NSArray *devices = [AVCaptureDevice devicesWithMediaType:mediaType];
          AVCaptureDevice *captureDevice = [devices firstObject];
      
          for (AVCaptureDevice *device in devices)
          {
              if ([device position] == position)
              {
                  captureDevice = device;
                  break;
              }
          }
      
          return captureDevice;
      }
      
      #pragma mark UI
      
      - (void)runStillImageCaptureAnimation
      {
          /*
           dispatch_async(dispatch_get_main_queue(), ^{
           [[[self previewView] layer] setOpacity:0.0];
           [UIView animateWithDuration:.25 animations:^{
           [[[self previewView] layer] setOpacity:1.0];
           }];
           });
           */
      }
      
      - (void)checkDeviceAuthorizationStatus
      {
          NSString *mediaType = AVMediaTypeVideo;
      
          [AVCaptureDevice requestAccessForMediaType:mediaType completionHandler:^(BOOL granted) {
              if (granted)
              {
                  //Granted access to mediaType
                  [self setDeviceAuthorized:YES];
              }
              else
              {
                  //Not granted access to mediaType
                  dispatch_async(dispatch_get_main_queue(), ^{
                      [[[UIAlertView alloc] initWithTitle:@"AVCam!"
                                                  message:@"AVCam doesn't have permission to use Camera, please change privacy settings"
                                                 delegate:self
                                        cancelButtonTitle:@"OK"
                                        otherButtonTitles:nil] show];
                      [self setDeviceAuthorized:NO];
                  });
              }
          }];
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-08
        • 1970-01-01
        相关资源
        最近更新 更多