参考:

打开相册和相机的ZLPhotoBrowser:https://github.com/longitachi/ZLPhotoBrowser

QBImagePicker:https://github.com/questbeat/QBImagePicker

图片裁剪

VPImageCropperhttps://github.com/windshg/VPImageCropper

TZLocationManager:https://www.jianshu.com/p/8d4a2d4543ae

===注意:打开相机,点击选择完照片后,会调用控制器的代理方法:-(void)viewwillAppear{}

************************系统相机封装成分类***************

使用:
/**//相机获取权限,打开系统相册,调用该系统相机拍照或者录像使用:
[self CameraGetAuthory:2 isOpenAlbum:YES];//调用系统相册
[self CameraGetAuthory:0 isOpenAlbum:NO];//调用系统相机拍照和录像
[self CameraGetAuthory:1 isOpenAlbum:NO];//调用系统相机拍照
[self CameraGetAuthory:2 isOpenAlbum:NO];//调用系统相机录像*******#import <UIKit/UIKit.h>NS_ASSUME_NONNULL_BEGIN@interface UIViewController (CameraGetAuthory)<UIImagePickerControllerDelegate,UINavigationControllerDelegate>/**parama1:0表示照相和录像,1表示照相,2表示录像param2:YES表示打开相册,NO表示打开相机*/
-(void)CameraGetAuthory:(NSInteger )index isOpenAlbum:(BOOL)isOpenAlbum;
;
@endNS_ASSUME_NONNULL_END**********//#import "UIViewController+CameraGetAuthory.h"
#import <AVFoundation/AVFoundation.h>
#import <MobileCoreServices/MobileCoreServices.h>
@implementation UIViewController (CameraGetAuthory)
-(void)CameraGetAuthory:(NSInteger )index isOpenAlbum:(BOOL)isOpenAlbum{AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];//获取摄像头if (device) {AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];//判断用户是否有权限访问相机if (status == AVAuthorizationStatusNotDetermined) {//请求权限[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {if (granted) {dispatch_async(dispatch_get_main_queue(), ^{});//                    [self useCameraGetImageOrVideo:@"image"];// 用户第一次同意了访问相机权限if(!isOpenAlbum){[self useCameraGetImageOrVideo:index];//index---0照相和录像,1照相,2录像}else{[self openSystemAlbum];//打开系统相册}} else {// 用户第一次拒绝了访问相机权限}}];} else if (status == AVAuthorizationStatusAuthorized) { // 用户允许当前应用访问相机if(!isOpenAlbum){[self useCameraGetImageOrVideo:index];//index---0照相和录像,1照相,2录像}else{[self openSystemAlbum];//打开系统相册}} else if (status == AVAuthorizationStatusDenied) { // 用户拒绝当前应用访问相机UIAlertController *alertC = [UIAlertController alertControllerWithTitle:@"⚠️ 警告" message:@"请去-> [设置 - 隐私 - 相机 - SGQRCodeExample] 打开访问开关" preferredStyle:(UIAlertControllerStyleAlert)];UIAlertAction *alertA = [UIAlertAction actionWithTitle:@"确定" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {}];[alertC addAction:alertA];//            [self presentViewController:alertC animated:YES completion:nil];} else if (status == AVAuthorizationStatusRestricted) {NSLog(@"因为系统原因, 无法访问相册");}} else {UIAlertController *alertC = [UIAlertController alertControllerWithTitle:@"温馨提示" message:@"未检测到您的摄像头" preferredStyle:(UIAlertControllerStyleAlert)];UIAlertAction *alertA = [UIAlertAction actionWithTitle:@"确定" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {}];[alertC addAction:alertA];[self presentViewController:alertC animated:YES completion:nil];}
}
//打开系统的相册
-(void)openSystemAlbum{
//获取方式1:通过相册(呈现全部相册,以文件夹形式展示),UIImagePickerControllerSourceTypePhotoLibrary//获取方式2,通过相机,UIImagePickerControllerSourceTypeCamera只能拍照//获取方法3,通过相册(呈现全部图片,打开文件夹展示文件夹里面的内容)UIImagePickerControllerSourceTypeSavedPhotosAlbumUIImagePickerController*PickerImage = [[UIImagePickerController alloc]init];PickerImage.sourceType =UIImagePickerControllerSourceTypePhotoLibrary;//如果只是从相册中取图片或者视频,sourceType只能设置成UIImagePickerControllerSourceTypeSavedPhotosAlbum(展示出来的是具体图片或视频,如果只设置mediatype为视频,只有moments文件夹的内容能展示出来)或UIImagePickerControllerSourceTypePhotoLibrary(展示出来的是文件夹,有好几个文件夹moemnt,camera roll,videos,my photo stream)//PickerImage.mediaTypes=@[(NSString *)kUTTypeImage];//如果不设置mediaTypes,则默认是kUTTypeImage类型PickerImage.mediaTypes=@[(NSString *)kUTTypeMovie];//设置仅仅打开视频PickerImage.mediaTypes= [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypePhotoLibrary];//设置打开所有的媒体类型,返回一个mediaType数组
//允许编辑,即放大裁剪PickerImage.allowsEditing =YES;//自代理
PickerImage.delegate =self;//页面跳转[self presentViewController:PickerImage animated:YES completion:nil];}
//用相机拍照或者录像
-(void)useCameraGetImageOrVideo:(NSInteger )index{
UIImagePickerController*PickerImage = [[UIImagePickerController alloc]init];/*获取方式:通过相机如果是打开相机拍照或者录像,sourceType只能设置成UIImagePickerControllerSourceTypeCamera*/PickerImage.sourceType =UIImagePickerControllerSourceTypeCamera;PickerImage.allowsEditing =YES;
PickerImage.delegate =self;
/*设置所支持的类型,设置只能拍照,或则只能录像,或者两者都可以(有选择的设置)
如果不设置mediatupes,默认情况下此数组只包含kUTTypeImage,表示拍照如果要录像,必须设置为kUTTypeVideo(视频不带声音)或kUTTypeMovie(视频带声音)*/NSString *requiredMediaType = (NSString *)kUTTypeImage;//拍照NSString *requiredMediaType1 = (NSString *)kUTTypeMovie;//录像NSArray*arrMediaTypes=[NSArray arrayWithObjects:requiredMediaType,requiredMediaType1,nil];if(index==0){//照相和录像arrMediaTypes=[NSArray arrayWithObjects:requiredMediaType,requiredMediaType1,nil];//设置录制视频的质量[PickerImage setVideoQuality:UIImagePickerControllerQualityTypeHigh];//设置最长摄像时间[PickerImage setVideoMaximumDuration:10.f];}else if(index==1){//照相arrMediaTypes=[NSArray arrayWithObjects:requiredMediaType,nil];}else if(index==2){//录像arrMediaTypes=[NSArray arrayWithObjects:requiredMediaType1,nil];/*设置摄像头捕捉模式,在这里设置了报错,(但是在自定义相机面时是有作用的,设置UIImagePickerControllerCameraCaptureModeVideo表示录像,UIImagePickerControllerCameraCaptureModePhoto表示拍照),但是MediaTypes必须设置*/
//         PickerImage.cameraCaptureMode=UIImagePickerControllerCameraCaptureModeVideo;//设置录制视频的质量[PickerImage setVideoQuality:UIImagePickerControllerQualityTypeHigh];//设置最长摄像时间[PickerImage setVideoMaximumDuration:10.f];}[PickerImage setMediaTypes:arrMediaTypes];//设置媒体类型[self presentViewController:PickerImage animated:YES completion:nil];
}
- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString*,id> *)info
{if([info[UIImagePickerControllerMediaType] isEqualToString:(NSString *)kUTTypeImage]) {//拍照,或者选择相册走这里
//获取编辑后的图片
UIImage*Editedimage = info[UIImagePickerControllerEditedImage];//发通知,吧数据传给view,然后刷新collectionview[[NSNotificationCenter defaultCenter]postNotificationName:@"CmaraImage" object:nil userInfo:@{@"images":@[Editedimage]}];
//压缩图片
CGSize newSize=CGSizeMake(90, 90);UIGraphicsBeginImageContext(newSize);[Editedimage drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];UIImage*newImage =UIGraphicsGetImageFromCurrentImageContext();//从图形上下文获取新的图片UIGraphicsEndImageContext();//获得原图
//   UIImage *Originalimage = info[UIImagePickerControllerOriginalImage];
//将照片保存到相册
// SEL是一个异步回调(参数是固定的否者会报错),不需要的话可以写nil,
UIImageWriteToSavedPhotosAlbum(Editedimage,self,@selector(imageSavedToPhotosAlbum:didFinishSavingWithError:contextInfo:),nil);
//        UIImageWriteToSavedPhotosAlbum(Editedimage, nil, nil, nil);}else if([info[UIImagePickerControllerMediaType] isEqualToString:(NSString *)kUTTypeMovie]){//录像// movie的路径
NSURL*url = info[UIImagePickerControllerMediaURL];// movie是否可以保存到相册
BOOL canbesaved =UIVideoAtPathIsCompatibleWithSavedPhotosAlbum([url path]);if (canbesaved) {//将movie保存到相
UISaveVideoAtPathToSavedPhotosAlbum(url.path,self,@selector(videoSavedToPhotosAlbum:didFinishSavingWithError:contextInfo:),nil);}else{
NSLog(@"录像不能保存到相册");}
}else{
NSLog(@"%@",info[UIImagePickerControllerMediaType]);}[self dismissViewControllerAnimated:YES completion:nil];}- (void)image:(UIImage*)image didFinishSavingWithError:(NSError*)error contextInfo:(void *)contextInfo {NSLog(@"111");}
#pragma mark - 异步回调//保存照片到系统相册- (void)imageSavedToPhotosAlbum:(UIImage*)image didFinishSavingWithError:(NSError*)error contextInfo:(void *)contextInfo
{
if(!error) {NSLog(@"图片保存成功");}else{NSLog(@"图片保存不成功,error:%@",error);}}//保存录像到系统界面- (void)videoSavedToPhotosAlbum:(NSString*)videoPath didFinishSavingWithError:(NSError*)error contextInfo:(void *)contextInfo
{if(!error) {NSLog(@"视频保存成功");}else{NSLog(@"视频保存不成功,error:%@",error);}
}@end

*************************相册多选框架TZImagePickerController**************
github地址:https://github.com/banchichen/TZImagePickerController

/**TZImagePickerController相册多选框架(照片和和视频)可以单独使用,直接把这个分类导入即可使用:在选择完照片后挥发通知在外部接受通知[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(selectImagesNoti:) name:@"selectImage" object:nil];//通过TZImage选择照片的通知
-(void)selectImagesNoti:(NSNotification *)noti{NSDictionary *dict=noti.userInfo;if([[dict allKeys]containsObject:@"images"]){NSArray *images=dict[@"images"];}}*/#import <UIKit/UIKit.h>
#import "TZImagePickerController.h"
NS_ASSUME_NONNULL_BEGIN@interface UIViewController (TZIMagePickvc)<TZImagePickerControllerDelegate>
//@property(nonatomic,copy)void (^selectImageBlcok)(NSArray *images);
- (void)showPhotoPickerWithTag:(NSInteger) tag;
@endNS_ASSUME_NONNULL_END***********#import "UIViewController+TZIMagePickvc.h"
#import <objc/message.h>
// 属性名称
static const char * key = "name";//必须用char *,用NSString会报错
@implementation UIViewController (TZIMagePickvc)
- (void)showPhotoPickerWithTag:(NSInteger) tag {NSInteger maxCount = 9;//一次做多上传多少张TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:maxCount columnNumber:4 delegate:self];[imagePickerVc setSortAscendingByModificationDate:NO];imagePickerVc.allowTakePicture = YES; // 在内部显示拍照按钮imagePickerVc.naviBgColor = [UIColor whiteColor];imagePickerVc.naviTitleColor = [UIColor blackColor];imagePickerVc.barItemTextColor = [UIColor orangeColor];imagePickerVc.oKButtonTitleColorNormal = [UIColor orangeColor];imagePickerVc.oKButtonTitleColorDisabled = [UIColor lightGrayColor];imagePickerVc.statusBarStyle = UIStatusBarStyleDefault;// imagePickerVc.photoDefImageName = @"";imagePickerVc.photoSelImage = [UIImage imageNamed:@"comm_btn_checkmark"];imagePickerVc.photoNumberIconImage = [UIImage imageNamed:@""];imagePickerVc.photoOriginDefImage = [UIImage imageNamed:@""];imagePickerVc.photoOriginSelImage = [UIImage imageNamed:@""];// imagePickerVc.takePictureImageName = @"";imagePickerVc.allowPickingVideo = NO;imagePickerVc.allowPickingImage = YES;imagePickerVc.allowPickingOriginalPhoto = YES;imagePickerVc.allowPickingGif = NO;imagePickerVc.allowPickingMultipleVideo = NO; // 是否可以多选视频imagePickerVc.view.tag = tag;[self presentViewController:imagePickerVc animated:YES completion:nil];}
//选择录像
- (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingVideo:(UIImage *)coverImage sourceAssets:(id)asset{//    __weak typeof(self) weakSelf = self;PHAsset *ast = (PHAsset *)asset;PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];options.version = PHImageRequestOptionsVersionCurrent;options.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;PHImageManager *manager = [PHImageManager defaultManager];[manager requestAVAssetForVideo:ast options:options resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {AVURLAsset *urlAsset = (AVURLAsset *)asset;NSURL *url = urlAsset.URL;}];}
//选择图片后调用的代理
- (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingPhotos:(NSArray<UIImage *> *)photos sourceAssets:(NSArray *)assets isSelectOriginalPhoto:(BOOL)isSelectOriginalPhoto{for (UIImage * image in photos) {NSLog(@"000%lu",(unsigned long)photos.count);}//发通知,吧数据传给view,然后刷新collectionview[[NSNotificationCenter defaultCenter]postNotificationName:@"selectImage" object:nil userInfo:@{@"images":photos}];
}
//选择gif
- (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingGifImage:(UIImage *)animatedImage sourceAssets:(id)asset{}
///**
// 动态添加block
// */
//-(void)setSelectImageBlcok:(void (^)(NSArray * _Nonnull))selectImageBlcok{
//     objc_setAssociatedObject(self,key, selectImageBlcok, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
//}
//
//-(void (^)(NSArray * _Nonnull))selectImageBlcok{
//     return objc_getAssociatedObject(self, key);
//}
@end
//选择相册
-(void)selectxiangce{QMWNWEAKSELF;TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:9 delegate:self];imagePickerVc.allowPickingImage=YES;imagePickerVc.allowPickingVideo=NO;imagePickerVc.allowTakePicture=YES;[imagePickerVc setDidFinishPickingPhotosHandle:^(NSArray<UIImage *> *photos, NSArray *assets, BOOL isSelectOriginalPhoto) {[weakSelf.imageArr addObjectsFromArray:photos];weakSelf.headerview.imageArr=weakSelf.imageArr;if(weakSelf.imageArr.count>0){SLog(@"--tupian%@",weakSelf.imageArr[0]);}
//                [weakSelf requestkeyWIthimageorattach:@"1"];//图片PHImageRequestOptions *options=[[PHImageRequestOptions alloc]init];options.version=PHImageRequestOptionsVersionCurrent;options.deliveryMode=PHImageRequestOptionsDeliveryModeFastFormat;PHImageManager *manager = [PHImageManager defaultManager];
//                if (@available(iOS 13, *)) {
//                    [manager requestImageDataAndOrientationForAsset:assets[0] options:options resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, CGImagePropertyOrientation orientation, NSDictionary * _Nullable info) {
//
//                    }];
//                } else {
//                    [manager requestImageForAsset:assets[0] targetSize:CGSizeMake(WIDTH, HEIGHT) contentMode:PHImageContentModeDefault options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
//                        SLog(@"tupian---%@",info);
//                    }];
//                }[manager requestImageDataForAsset:assets[0] options:options resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {//获取imagedata数据}];//视频
//                    PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
//                    options.version = PHVideoRequestOptionsVersionCurrent;
//                    options.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;
//                    PHImageManager *manager = [PHImageManager defaultManager];
//                    [manager requestAVAssetForVideo:ast options:options resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
//
//                        AVURLAsset *urlAsset = (AVURLAsset *)asset;
//
//                        NSURL *url = urlAsset.URL;
//
//
//                    }];}];[self presentViewController:imagePickerVc animated:YES completion:nil];}

UIImagePickerController是继承UINavigationController,所以可以push和pop一些viewcontroller进行导航效果。例如,自定义照相机画面的时候可以在拍摄完后push一个viewcontroller用于对照片进行编辑。

相机常用属性:

//来源类型

@property(nonatomic)UIImagePickerControllerSourceType sourceType;

typedef NS_ENUM(NSInteger, UIImagePickerControllerSourceType) {

UIImagePickerControllerSourceTypePhotoLibrary,默认全部相册

UIImagePickerControllerSourceTypeCamera,

UIImagePickerControllerSourceTypeSavedPhotosAlbum

} __TVOS_PROHIBITED;

//@property (nonatomic)NSTimeInterval videoMaximumDuration;//视频最大录制时长,默认10s@property (nonatomic)UIImagePickerControllerQualityType videoQuality;//视频质量typedefNS_ENUM(NSInteger,UIImagePickerControllerQualityType) { UIImagePickerControllerQualityTypeHigh = 0,//高清UIImagePickerControllerQualityTypeMedium,//中等,适合WiFi传输UIImagePickerControllerQualityTypeLow,//低质量,适合蜂窝网传输UIImagePickerControllerQualityType640x480,//640*480UIImagePickerControllerQualityTypeIFrame1280x720,//1280*720UIImagePickerControllerQualityTypeIFrame960x540,//960*540};

@property (nonatomic)BOOL showsCameraControls;/* 是否显示摄像头控制面板,默认为YES */

@property (nonatomic,strong)UIView *cameraOverlayView;/* 摄像头上覆盖的视图 */自定义相机界面(控制面板)

@property (nonatomic)CGAffineTransform cameraViewTransform;/* 摄像头形变 */

@property (nonatomic)UIImagePickerControllerCameraCaptureMode cameraCaptureMode;/* 摄像头捕捉模式 */

typedefNS_ENUM(NSInteger,UIImagePickerControllerCameraCaptureMode) { UIImagePickerControllerCameraCaptureModePhoto,//拍照模式

UIImagePickerControllerCameraCaptureModeVideo//视频录制模式};@property (nonatomic)UIImagePickerControllerCameraDevice cameraDevice;/* 摄像头设备 */typedefNS_ENUM(NSInteger,UIImagePickerControllerCameraDevice) { UIImagePickerControllerCameraDeviceRear,//前置摄像头UIImagePickerControllerCameraDeviceFront//后置摄像头};@property (nonatomic)UIImagePickerControllerCameraFlashMode cameraFlashMode;/* 闪光灯模式 */typedefNS_ENUM(NSInteger,UIImagePickerControllerCameraFlashMode) { UIImagePickerControllerCameraFlashModeOff = -1,//关闭闪光灯UIImagePickerControllerCameraFlashModeAuto = 0,//闪光灯自动,默认UIImagePickerControllerCameraFlashModeOn = 1//打开闪光灯};

//最长录像时间

@property(nonatomic)          NSTimeInterval                        videoMaximumDurationNS_AVAILABLE_IOS(3_1);

//showsCameraControls用于指定拍照时下方的工具栏是否显示,取而代之的是allowEditing,表示拍完照片或者从相册选完照片后,是否跳转到编辑模式对图片裁剪,只有在showsCameraControls为YES时才有效果。

@property(nonatomic)  BOOL  showsCameraControls NS_AVAILABLE_IOS(3_1); //是否显示控制面板
@property(nonatomic)  BOOL  allowsEditing NS_AVAILABLE_IOS(3_1); //允许编辑裁剪
//mediaTypes用于设置相机支持的功能,拍照或者是视频,返回值类型可以是:默认情况下此数组包含kUTTypeImage,表示拍照 如果要录像,必须设置为kUTTypeVideo(视频不带声音)或kUTTypeMovie(视频带声音)mediaTypes用于设置相机支持的功能,拍照或者是视频,返回值类型可以是:默认情况下此数组包含kUTTypeImage,表示拍照 如果要录像,必须设置为kUTTypeVideo(视频不带声音)或kUTTypeMovie(视频带声音)
    /*在此处注意我们要将MobileCoreServices 框架添加到项目中,然后将其导入:#import <MobileCoreServices/MobileCoreServices.h> 。不然后出现错误使用未声明的标识符 'kUTTypeMovie'
@property(nonatomic,copy)      NSArray<NSString *>  *mediaTypes;

类方法:

//是否能获得某个资源类型,有三种:

UIImagePickerControllerSourceTypePhotoLibrary,

UIImagePickerControllerSourceTypeCamera,

UIImagePickerControllerSourceTypeSavedPhotosAlbum

+ (BOOL)isSourceTypeAvailable:(UIImagePickerControllerSourceType)sourceType; // returns YES if source is available (i.e. camera present)

//某种资源类型可获得的所有媒体类型的集合;集合中可以是kUTTypeImage(表示拍照)

kUTTypeVideo(视频不带声音)或kUTTypeMovie(视频带声音)中的一种或几种;

+ (nullableNSArray<NSString *> *)availableMediaTypesForSourceType:(UIImagePickerControllerSourceType)sourceType;// returns array of available media types (i.e. kUTTypeImage)

//是否能获得相机设备:包括前摄像头或后摄像头

+ (BOOL)isCameraDeviceAvailable:(UIImagePickerControllerCameraDevice)cameraDevice                  NS_AVAILABLE_IOS(4_0);// returns YES if camera device is available

//是否支持闪光灯

+ (BOOL)isFlashAvailableForCameraDevice:(UIImagePickerControllerCameraDevice)cameraDevice          NS_AVAILABLE_IOS(4_0);// returns YES if camera device supports flash and torch.

//摄像头可获得的捕捉模式的集合

+ (nullableNSArray<NSNumber *> *)availableCaptureModesForCameraDevice:(UIImagePickerControllerCameraDevice)cameraDeviceNS_AVAILABLE_IOS(4_0);// returns array of NSNumbers (UIImagePickerControllerCameraCaptureMode)

2. 常用对象方法:

- (void)takePicture;//拍照

- (BOOL)startVideoCapture;//开始录制视频

- (void)stopVideoCapture;//停止录制视频

3. 代理方法:

/* 媒体获取完成会调用 */- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info;

/* 取消获取会调用 */- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker;

4. 扩展函数,用于保存到相簿:

/* 保存图片到相簿 */voidUIImageWriteToSavedPhotosAlbum(

UIImage *image,//保存的图片UIImage

id completionTarget,//回调的执行者

SEL completionSelector,//回调方法

void *contextInfo//回调参数信息);

//上面一般保存图片的回调方法为:- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo;

/* 判断是否能保存视频到相簿 */BOOLUIVideoAtPathIsCompatibleWithSavedPhotosAlbum(NSString *videoPath);

/* 保存视频到相簿 */voidUISaveVideoAtPathToSavedPhotosAlbum(

NSString *videoPath, //保存的视频文件路径

id completionTarget, //回调的执行者

SEL completionSelector,//回调方法

void *contextInfo//回调参数信息);

//上面一般保存视频的回调方法为:- (void)video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo;

 

********************

  

******************************

#pragma mark 调用系统相册及拍照功能实现的代理方法并且上传到服务器的数据库

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info

{//从相册获取图片

UIImage * chosenImage = info[UIImagePickerControllerEditedImage];

UIImageView * picImageView = (UIImageView *)[self.viewviewWithTag:500];

picImageView.image = chosenImage;

NSData * imageData =UIImageJPEGRepresentation(chosenImage,0.9);

//将图片上传到服务器

//    --------------------------------------------------------

AFHTTPRequestOperationManager * manager = [[AFHTTPRequestOperationManager alloc]initWithBaseURL:nil];

manager.requestSerializer = [AFHTTPRequestSerializer serializer];

manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/html",@"text/javascript",@"text/json",nil];

NSString * urlString = [NSString stringWithFormat:@"%@appuser/modifyUserIcon",BASE_URL];

NSUserDefaults * userDefaults = [NSUserDefaultsstandardUserDefaults];

NSMutableDictionary * dict = [NSMutableDictionarydictionaryWithCapacity:1];

[dict setObject:[userDefaultsobjectForKey:@"user_id"]forKey:@"user_id"];//链接服务器接口的参数

[manager POST:urlString parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {

//通过post请求上传用户头像图片,name和fileName传的参数需要跟后台协商,看后台要传的参数名

[formData appendPartWithFileData:imageData name:@"img" fileName:@"img.jpg" mimeType:@"image/jpeg"];

} success:^(AFHTTPRequestOperation *operation, id responseObject) {

//解析后台返回的结果,如果不做一下处理,打印结果可能是一些二进制流数据

NSError *error;

NSDictionary * imageDict = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];//从服务器得到的数据是字典

//上传成功后更新数据

self.personModel.adperurl = imageDict[@"adperurl"];//

NSLog(@"上传图片成功0---%@",imageDict);

} failure:^(AFHTTPRequestOperation *operation, NSError *error) {

NSLog(@"上传图片--失败-%@",error);

}];

[picker dismissViewControllerAnimated:YEScompletion:^{

}];

}

///////////////UIImagePickerController实现举例一(最主要的)

#import "ViewController.h"

#import <MobileCoreServices/MobileCoreServices.h>

@interfaceViewController ()<UIImagePickerControllerDelegate,UINavigationControllerDelegate>

@property(nonatomic,strong)UIImagePickerController *pickVC;

@end

@implementation ViewController

- (void)viewDidLoad {

[superviewDidLoad];

}

-(void)touchCancel{

[self.pickVCstopVideoCapture];//停止录像

NSLog(@"cancel");

}

-(void)touchOk{

//    [self.pickVC takePicture];//拍照,capturemodal设置成UIImagePickerControllerCameraCaptureModePhoto时,这个方法才起作用

[self.pickVCstartVideoCapture];//开始录像

NSLog(@"OK");

}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

//初始化UIImagePickerController

UIImagePickerController *PickerImage = [[UIImagePickerControlleralloc]init];

self.pickVC=PickerImage;

//    UIImagePickerController *PickerImage = [[UIImagePickerController alloc]init];

//初始化提示框

UIAlertController *alert = [UIAlertControlleralertControllerWithTitle:nilmessage:nilpreferredStyle:UIAlertControllerStyleActionSheet];

--------------打开相册或者视频-------------//按钮:从相册选择,类型:UIAlertActionStyleDefault

[alert addAction:[UIAlertActionactionWithTitle:@"从相册选择打开图片或打开视频"style:UIAlertActionStyleDefaulthandler:^(UIAlertAction *_Nonnull action) {

//获取方式1:通过相册(呈现全部相册,以文件夹形式展示),UIImagePickerControllerSourceTypePhotoLibrary

//获取方式2,通过相机,UIImagePickerControllerSourceTypeCamera只能拍照

//获取方法3,通过相册(呈现全部图片,打开文件夹展示文件夹里面的内容),UIImagePickerControllerSourceTypeSavedPhotosAlbum

PickerImage.sourceType =

UIImagePickerControllerSourceTypePhotoLibrary;//如果只是从相册中取图片或者视频,sourceType只能设置成UIImagePickerControllerSourceTypeSavedPhotosAlbum(展示出来的是具体图片或视频,如果只设置mediatype为视频,只有moments文件夹的内容能展示出来)或UIImagePickerControllerSourceTypePhotoLibrary(展示出来的是文件夹,有好几个文件夹moemnt,camera roll,videos,my photo stream)

//PickerImage.mediaTypes=@[(NSString *)kUTTypeImage];//如果不设置mediaTypes,则默认是kUTTypeImage类型

//    PickerImage.mediaTypes=@[(NSString *)kUTTypeMovie];//设置仅仅打开视频,需要导入#import <MobileCoreServices/MobileCoreServices.h>才能设置这个类型

PickerImage.mediaTypes=  [UIImagePickerControlleravailableMediaTypesForSourceType:

UIImagePickerControllerSourceTypePhotoLibrary];//设置打开所有的媒体类型,返回一个mediaType数组

//允许编辑,即放大裁剪

PickerImage.allowsEditing =YES;

//自代理

PickerImage.delegate =self;

//页面跳转

[selfpresentViewController:PickerImageanimated:YEScompletion:nil];

}]];

--------------------打开相机------------//按钮:拍照,类型:UIAlertActionStyleDefault

[alert addAction:[UIAlertActionactionWithTitle:@"打开相机拍照后者录像"style:UIAlertActionStyleDefaulthandler:^(UIAlertAction *_Nonnull action){

/**

其实和从相册选择一样,只是获取方式不同,前面是通过相册,而现在,我们要通过相机的方式

*/

//获取方式:通过相机

PickerImage.sourceType =UIImagePickerControllerSourceTypeCamera;//如果是打开相机拍照或者录像,sourceType只能设置成UIImagePickerControllerSourceTypeCamera

PickerImage.allowsEditing =YES;

PickerImage.delegate =self;

//设置所支持的类型,设置只能拍照,或则只能录像,或者两者都可以(有选择的设置)

//如果不设置mediatupes,默认情况下此数组只包含kUTTypeImage,表示拍照

//如果要录像,必须设置为kUTTypeVideo(视频不带声音)或kUTTypeMovie(视频带声音)

NSString *requiredMediaType = (NSString *)kUTTypeImage;

NSString *requiredMediaType1 = (NSString *)kUTTypeMovie;

NSArray *arrMediaTypes=[NSArrayarrayWithObjects:requiredMediaType, requiredMediaType1,nil];

[PickerImage setMediaTypes:arrMediaTypes];//设置媒体类型

PickerImage.cameraCaptureMode=UIImagePickerControllerCameraCaptureModeVideo;//设置摄像头捕捉模式,在这里好象不设置页可以,(但是在自定义相机面时是有作用的,设置UIImagePickerControllerCameraCaptureModeVideo表示录像,UIImagePickerControllerCameraCaptureModePhoto表示拍照),但是MediaTypes必须设置

//设置录制视频的质量

[PickerImage setVideoQuality:UIImagePickerControllerQualityTypeHigh];

//设置最长摄像时间

[PickerImage setVideoMaximumDuration:10.f];

//******************

/---------------------/自定义的相机界面,注意:自定义相机界面的设置必须是在sourcetype设置成了UIImagePickerControllerSourceTypeCamera之后,否则会报错,提示:sourceType must be  UIImagePickerControllerSourceTypeCamera

PickerImage.showsCameraControls =NO;------------吧系统相机按钮隐藏

UIToolbar * tool = [[UIToolbar alloc]initWithFrame:CGRectMake(0,self.view.frame.size.height - 40, self.view.frame.size.width,40)];

tool.barStyle =UIBarStyleBlackTranslucent;

tool.barTintColor = [UIColorgreenColor];

UIBarButtonItem * cancel = [[UIBarButtonItemalloc]initWithTitle:@"取消"style:UIBarButtonItemStylePlain target:selfaction:@selector(touchCancel)];

cancel.width =self.view.frame.size.width/2;

UIBarButtonItem * ok = [[UIBarButtonItemalloc]initWithTitle:@"确定"style:UIBarButtonItemStylePlain target:selfaction:@selector(touchOk)];

ok.width =self.view.frame.size.width/2;

[tool setItems:@[cancel,ok]];

//把自定义的view添加到UIImagePickerController的layView上

PickerImage.cameraOverlayView = tool;------------替换系统的相机按钮

//****************

[selfpresentViewController:PickerImageanimated:YEScompletion:nil];---------------弹出相机页面

}]];

//-----------取消按钮-------按钮:取消,类型:UIAlertActionStyleCancel

[alert addAction:[UIAlertActionactionWithTitle:@"取消"style:UIAlertActionStyleCancelhandler:nil]];

[selfpresentViewController:alertanimated:YEScompletion:nil];------弹出选择按钮

}

/*在此处注意我们要将MobileCoreServices 框架添加到项目中,然后将其导入:#import <MobileCoreServices/MobileCoreServices.h> 。不然后出现错误使用未声明的标识符 'kUTTypeMovie'

//照片视频保存到相册--------------选择完照片或视频后调用的代理方法

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info

{

if ([info[UIImagePickerControllerMediaType] isEqualToString:(NSString *)kUTTypeImage]) {//拍照

//获取编辑后的图片

UIImage*Editedimage = info[UIImagePickerControllerEditedImage];

//压缩图片

CGSize newSize=CGSizeMake(90, 90);

UIGraphicsBeginImageContext(newSize);

[Editedimage drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];

UIImage*newImage =UIGraphicsGetImageFromCurrentImageContext();//从图形上下文获取新的图片

UIGraphicsEndImageContext();

//获得原图

//        UIImage *Originalimage = info[UIImagePickerControllerOriginalImage];

//将照片保存到相册

// SEL是一个异步回调(参数是固定的否者会报错),不需要的话可以写nil,

UIImageWriteToSavedPhotosAlbum(Editedimage,self,@selector(imageSavedToPhotosAlbum:didFinishSavingWithError:contextInfo:),nil);

//        UIImageWriteToSavedPhotosAlbum(Editedimage, nil, nil, nil);

}elseif ([info[UIImagePickerControllerMediaType] isEqualToString:(NSString *)kUTTypeMovie]){//录像

// movie的路径

NSURL*url = info[UIImagePickerControllerMediaURL];

// movie是否可以保存到相册

BOOLcanbesaved =UIVideoAtPathIsCompatibleWithSavedPhotosAlbum([urlpath]);

if (canbesaved) {

//将movie保存到相册

UISaveVideoAtPathToSavedPhotosAlbum(url.path,self,@selector(videoSavedToPhotosAlbum:didFinishSavingWithError:contextInfo:),nil);

}else{

NSLog(@"movie can not be saved to the Camera Roll album");

}

}else{

NSLog(@"%@",info[UIImagePickerControllerMediaType]);

}

[selfdismissViewControllerAnimated:YEScompletion:nil];

}

- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(voidvoid *)contextInfo {

NSLog(@"111");

}

#pragma mark - 异步回调

//保存图到系统相册

- (void)imageSavedToPhotosAlbum:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo

{

if (!error) {

NSLog(@"图片保存成功");

}else{

NSLog(@"图片保存不成功,error:%@",error);

}

}

//保存录像到系统界面

- (void)videoSavedToPhotosAlbum:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(voidvoid *)contextInfo

{

if (!error) {

NSLog(@"视频保存成功");

}else{

NSLog(@"视频保存不成功,error:%@",error);

}

}

//////////////////举例二++++++++++++++++++++++++++++++++

一,//自定义按钮实现打开相册

<UIActionSheetDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate>协议

- (IBAction)pickerImage:(id)sender {

//打开相册或相机

UIImagePickerController *picker = [[UIImagePickerControlleralloc]init];

//设置照片源

//获取方式1:通过相册(呈现全部相册),UIImagePickerControllerSourceTypePhotoLibrary

//获取方式2,通过相机拍摄,UIImagePickerControllerSourceTypeCamera

//获取方法3,通过相册(呈现全部图片),UIImagePickerControllerSourceTypeSavedPhotosAlbum

picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

//参数设置

picker.allowsEditing =YES;//允许编辑

//设置代理

picker.delegate =self;

//弹出控制器

[self.navigationControllerpresentViewController:pickeranimated:YEScompletion:nil];

}

//选中了图片的代理方法

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info

{

NSLog(@"%@",info);

UIImage *image = info[UIImagePickerControllerEditedImage];//获取图片

NSData *imageData =UIImageJPEGRepresentation(image,0.2);//对图像做了压缩,0.2是失真度

//dismiss控制器

[selfdismissViewControllerAnimated:YEScompletion:nil];

}

//取消图片选择控制器的代理方法

-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker

{

[selfdismissViewControllerAnimated:YEScompletion:nil];

}

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

AVFoundation自定义拍照录像:

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

UIActionSheet实现打开图片:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

// 获取cell.tag

UITableViewCell *cell = [tableViewcellForRowAtIndexPath:indexPath];

NSInteger tag = cell.tag;

// 判断

if (tag == 2) {//不做任务操作

WCLog(@"不做任务操作");

return;

}

if(tag == 0){//选择照片

WCLog(@"选择照片");

UIActionSheet *sheet = [[UIActionSheetalloc]initWithTitle:@"请选择"delegate:selfcancelButtonTitle:@"取消"destructiveButtonTitle:@"照相"otherButtonTitles:@"相册",nil];

[sheet showInView:self.view];

}else{//跳到下一个控制器

WCLog(@"跳到下一个控制器");

[selfperformSegueWithIdentifier:@"EditVCardSegue"sender:cell];

}

}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{

//获取编辑个人信息的控制

id destVc = segue.destinationViewController;

if ([destVcisKindOfClass:[WCEditProfileViewControllerclass]]) {

WCEditProfileViewController *editVc = destVc;

editVc.cell = sender;

editVc.delegate =self;

}

}

#pragma mark actionsheet的代理

-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{

if(buttonIndex ==2){//取消

return;

}

UIImagePickerController *imagePicker = [[UIImagePickerControlleralloc]init];

// 设置代理

imagePicker.delegate =self;

// 设置允许编辑

imagePicker.allowsEditing =YES;

if (buttonIndex ==0) {//照相

imagePicker.sourceType =UIImagePickerControllerSourceTypeCamera;

}else{//相册

imagePicker.sourceType =UIImagePickerControllerSourceTypePhotoLibrary;

}

// 显示图片选择器

[selfpresentViewController:imagePickeranimated:YEScompletion:nil];

}

#pragma mark 图片选择器的代理

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{

WCLog(@"%@",info);

// 获取图片 设置图片

UIImage *image = info[UIImagePickerControllerEditedImage];

self.haedView.image = image;

//隐藏当前模态窗口

[selfdismissViewControllerAnimated:YEScompletion:nil];

// 更新到服务器

[selfeditProfileViewControllerDidSave];

}

//选中图片后打印出来的图片信息:

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

二,视频压缩(原理是:以低质量的导出)

- (void)viewDidLoad {

[superviewDidLoad];

//从相册中选择视频出来

UIImagePickerController *picker = [[UIImagePickerControlleralloc]init];

//设置素材的来源

self.picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

self.picker = picker;

/*

UIImagePickerControllerSourceTypePhotoLibrary, 相片库

UIImagePickerControllerSourceTypeCamera, 相机

UIImagePickerControllerSourceTypeSavedPhotosAlbum相册

*/

NSLog(@"%@",[UIImagePickerControlleravailableMediaTypesForSourceType:UIImagePickerControllerSourceTypePhotoLibrary]);

self.picker.delegate =self;

//设置多媒体类型(设置所有类型)  图片 音频视频

self.picker.mediaTypes = [UIImagePickerControlleravailableMediaTypesForSourceType:UIImagePickerControllerSourceTypePhotoLibrary];//设置所有多媒体类型

}

//设置单个多媒体类型,

注意如果是录像必须设置,如果是拍照此步骤可以省略,因为mediaType默认包含kUTTypeImage(注意媒体类型定义在MobileCoreServices.framework中;
<strong>//imagePickerController.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeMovie];</strong>

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info

{

//    NSLog(@"%@",info);

//    UIImage *image =   info[UIImagePickerControllerOriginalImage];

//    self.imageView.image = image;

[self.pickerdismissViewControllerAnimated:YEScompletion:nil];

//获取视频的url

NSURL *url =  info[UIImagePickerControllerMediaURL];

//视频压缩

//8M  200KB应用场景  对像素要求不高但是需要看到视频的场景

// 小视频 网络传输

//压缩原理: 就是以低质量的导出

AVAsset *asset = [AVAssetasset WithURL:url];

//参数1是素材对象 参数2压缩的质量

AVAssetExportSession *session = [[AVAssetExportSessionalloc]initWithAsset:asset presetName:AVAssetExportPresetMediumQuality];

//建议 : AVAssetExportPresetHighestQuality 不压缩 AVAssetExportPresetLowQuality低质量

//AVAssetExportPresetMediumQuality中间

//路径 放在什么地方?

NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES)lastObject]stringByAppendingPathComponent:@"hello.m4v"];

//删除之前存在的文件 如果没有就设么都不做

[[NSFileManagerdefaultManager]removeItemAtPath:patherror:nil];

session.outputURL = [NSURLfileURLWithPath:path];

//文件格式

//    self.session = session;

NSLog(@"%@",session.supportedFileTypes);

session.outputFileType =AVFileTypeQuickTimeMovie;

//    NSLog(@"%@",NSHomeDirectory());

//导出

[session exportAsynchronouslyWithCompletionHandler:^{

NSLog(@"导出完成!!!");

}];

}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

{

[selfpresentViewController:self.pickeranimated:YEScompletion:nil];

}

iOS---系统相册视频(一)之打开照相机拍照或者录像/打开手机的相册或者视频/视频压缩/自定义相机界面/照片或视频保存到相册相关推荐

  1. AS打开照相机拍照保存本地、显示页面

    打开相机 1.权限 6.0之后修改动态获取权限 打开照相机的权限 <uses-permission android:name="android.permission.CAMERA&qu ...

  2. Android基础知识复习之打开照相机拍照并获取照片

    对于我来说,做一件事情: 首先要理清我的思路,我要打开照相机,我能想到的是:在Android中我要打开系统应用,肯定需要一个隐式意图,那就要查询Android照相机的源码,查看并找到意图过滤器的书写方 ...

  3. Android 调用系统照相机拍照和录像

    Android 调用系统照相机拍照和录像 项目的布局相当简单,只有一个Button: <RelativeLayout xmlns:android="http://schemas.and ...

  4. iOS自定义相机界面

    先说说今天遇到的几个愚蠢的问题-- 想pop回原来的页 发现连着pop回两页..最后发现是写了两行self.navigationcontroller pop.... 我真是醉了=  =.. 补充一点: ...

  5. IOS研究院之打开照相机与本地相册选择图片

    如下图所示 在本地相册中选择一张图片后,我们将他拷贝至沙盒当中,在客户端中将它的缩略图放在按钮旁边,这个结构其实和新浪微薄中选择图片后的效果一样.最终点击发送将按钮将图片2进制图片上传服务器. 下面我 ...

  6. android 8.0 iso6,微信8.0.6更新了什么?IOS系统微信8.0.6版本更新详情一览[多图]

    微信8.0.6更新了什么?近日,IOS系统中的微信最新版本8.0.6已经正式更新,很多用户不清楚此次的新版本具体更新了什么,接下来小编就为大家带来IOS系统微信8.0.6版本的更新详情一览吧. 微信8 ...

  7. android手机能用ios吗,安卓手机真的可以刷苹果iOS系统吗?

    最近有很多粉丝来问小智,说是小米手机刷入了IOS系统,又说一加手机刷入了IOS系统,问自己的手机可不可以也刷入IOS系统,其实和小智一样懂的人都知道,那些都是图片刷机大法,就是在iPhone上截图,然 ...

  8. Flutter自定义相机,Flutter相册选择照片

    题记 -- 执剑天涯,从你的点滴积累开始,所及之处,必精益求精. github? 测试源码在这里 百度同步 CSDN 网易云课堂教程 掘金 知乎 Flutter系列文章 头条同步 实际项目开发中,谷歌 ...

  9. mac电脑如何与手机同步复制粘贴_Mac新手教程:如何将照片和视频从 iPhone、iPad传输到Mac电脑上?...

    如何将照片和视频从 iPhone.iPad传输到 Mac电脑上?macdown今天为Mac新手介绍将照片和视频传输到Mac电脑上的方法,希望对您有所帮助. 导入到 Mac电脑方法,请参考下方Mac新手 ...

最新文章

  1. dyld: Library not loaded: @rpath/Alamofire.framework/Alamofire
  2. python3将列表当做堆栈使用
  3. 增量调制原理matlab仿真,增量调制(DM  △M)
  4. mybatis $和#源代码分析
  5. 查看 mysql 状态_查看mysql状态的常用命令
  6. 慎用 JSON.stringify
  7. signature=04e0c5d9acfe5aef92fda679f27fba71,恶意软件分析 URL链接扫描 免费在线病毒分析平台 | 魔盾安全分析...
  8. 项目集锦 | 易基因近期m6A甲基化(MeRIP-seq)研究成果
  9. 对于Ajax在MUI框架中的用运以及单 webview 模式中的下拉刷新功能探究
  10. win7计算机备份,使用Win7自带工具对Win7系统进行备份图文详解
  11. Android垂直方向滚动的跑马灯,带gif
  12. 微场景:移动互联时代的营销革命
  13. 海盗分赃问题-----简化问题,分而治之
  14. 用python做通讯录包括姓名地址qq_我是如何用Python获取整个学校女生电话和QQ?技术撩妹...
  15. Synopsys Sentaurus TCAD系列教程之-- Svisual《一》看图工具
  16. (8)卷积神经网络如何处理一维时间序列数据?
  17. 浅谈大学计算机专业该如何选择方向
  18. QT实现vtk的可视化
  19. css样式实现td显示字体超长显示...鼠标悬浮显示全部
  20. 17.200种鸟类图片分类

热门文章

  1. 蛇呆在树上,整天无所事事_指南:如何在无所事事的盒子上安装OroCRM
  2. java实现获取微信公众服务号消息
  3. TOPOGRAPHIC LASER RANGING AND SCANNING Principles and Processing学习笔记
  4. 解决电脑频繁跳出 已停止工作,出现了一个问题,导致程序停止正常工作,请关闭该程序...
  5. linux权限数字详解
  6. CSS学习中|关于背景图片background
  7. 数据分析:numpy和pandas基础操作详解
  8. [USACO Dec07]超级书架
  9. 机器人布里茨哪个皮肤好看_蒸汽机器人哪款皮肤手感最好?老机器玩家亲自为你指路,一Q一个准!...
  10. 亚马逊云科技Amazon CodePipeline上线