iOS中-Qutarz2D详解及使用
在iOS中Qutarz2D 详解及使用
(一)初识
介绍
Quartz 2D是二维绘图引擎。
能完成的工作有:
绘制图形 : 线条\三角形\矩形\圆\弧等绘制文字绘制\生成图片(图像)读取\生成PDF截图\裁剪图片自定义UI控件… …
在iOS中最主要的作用是:自定义View
废话不多说了,直接开始学习它吧。
从概念开始
首先,必须清楚 图形上下文 的概念
图形上下文(Graphics Context)是一个CGContentRef类型的数据;可以帮你把你要显示
的图形显示到你指定的目标文件上。图形上下文的分类
Quartz2D提供了以下几种类型的Graphics Contenxt类型:
1.Bitmap Graphics Context
2.PDF Graphics Context
3.Windwo Graphics Context
4.Layer Graphics Contenx
5.Printer Graphics Context
这几种样式的显示样式实例如下图所示:
现在我们直接来使用它吧
为了方便大家看懂我的代码,首先我们学习一下使用的具体步骤:
1.自定义一个View(自定义一个UI控件),用来在上面画图
2.在这个View类的DrawRect方法中画图:
获取与该View相关的上下文
设置图形的路径
将路径添加到上下文(也就是显示出来)
实例展示一:
步骤:
1.自定义一个View
2.在自定义的View的DrawRect方法中画图
//画一个三角形
- (void)drawRect:(CGRect)rect {//获取当前上下文CGContextRef currentContext = UIGraphicsGetCurrentContext();/************************************************///设置路径,开始点CGContextMoveToPoint(currentContext, 10, 10);//添加第二个点CGContextAddLineToPoint(currentContext, 100, 100);//添加第三个点CGContextAddLineToPoint(currentContext, 150, 40);//封闭区域CGContextClosePath(currentContext);/***********************************************///将路径渲染到上下文并画出来CGContextStrokePath(currentContext);
}
其他图形
把上面的/*****/注释的那一段换成其他的图形,就可以展示出其他的图形了。例如:
#####矩形
/*画矩形*/CGContextStrokeRect(context,CGRectMake(100, 120, 10, 10));//画方框CGContextFillRect(context,CGRectMake(120, 120, 10, 10));//填充框//矩形,并填弃颜色CGContextSetLineWidth(context, 2.0);//线的宽度UIColor *aColor = [UIColor blueColor];//blue蓝色CGContextSetFillColorWithColor(context, aColor.CGColor);//填充颜色aColor = [UIColor yellowColor];CGContextSetStrokeColorWithColor(context, aColor.CGColor);//线框颜色CGContextAddRect(context,CGRectMake(140, 120, 60, 30));//画方框CGContextDrawPath(context, kCGPathFillStroke);//绘画路径//矩形,并填弃渐变颜色CAGradientLayer *gradient1 = [CAGradientLayer layer];gradient1.frame = CGRectMake(240, 120, 60, 30);gradient1.colors = [NSArray arrayWithObjects:(id)[UIColor whiteColor].CGColor,(id)[UIColor grayColor].CGColor,(id)[UIColor blackColor].CGColor,(id)[UIColor yellowColor].CGColor,(id)[UIColor blueColor].CGColor,(id)[UIColor redColor].CGColor,(id)[UIColor greenColor].CGColor,(id)[UIColor orangeColor].CGColor,(id)[UIColor brownColor].CGColor,nil];[self.layer insertSublayer:gradient1 atIndex:0];
文字
//文字
CGContextSetRGBFillColor(currentContext, 1, 0, 0, 1.0);
UIFont *font = [UIFont boldSystemFontOfSize:15.0];
[@"画汉字" drawInRect:CGRectMake(10, 10, 50, 100) withFont:font];
画圆
//画圆//填充模式://kCGPathFill填充非零绕数规则,//kCGPathEOFill表示用奇偶规则,//kCGPathStroke路径,//kCGPathFillStroke路径填充,//kCGPathEOFillStroke表示描线,不是填充//画圆函数//void CGContextAddArc(CGContextRef c,CGFloat x, CGFloat y,CGFloat radius,CGFloat startAngle,CGFloat endAngle, int clockwise)// x,y为圆点坐标,radius半径,startAngle为开始的弧度,endAngle为 结束的弧度,clockwise 0为顺时针,1为逆时针。//设置CGContextSetRGBStrokeColor(context,1,1,1,1.0);//画笔线的颜色CGContextSetLineWidth(context, 2.0);//线的宽度//边框圆CGContextAddArc(context, 100, 20, 15, 0, 2*M_PI, 0); //添加一个圆CGContextDrawPath(context, kCGPathStroke); //绘制路径//填充圆,无边框CGContextAddArc(context, 150, 30, 30, 0, 2*M_PI, 0); //添加一个圆CGContextDrawPath(context, kCGPathFill);//绘制填充//画大圆并填充颜色UIColor*aColor = [UIColor colorWithRed:1 green:0.0 blue:0 alpha:1];CGContextSetFillColorWithColor(context, aColor.CGColor);//填充颜色CGContextSetLineWidth(context, 3.0);//线的宽度CGContextAddArc(context, 250, 40, 40, 0, 2*M_PI, 0); //添加一个圆CGContextDrawPath(context, kCGPathFillStroke); //绘制路径加填充
圆弧
//圆弧
CGContextSetRGBStrokeColor(context, 0, 0, 1, 1);//改变画笔颜色
CGContextMoveToPoint(context, 140, 80);//开始坐标p1
//CGContextAddArcToPoint(CGContextRef c, CGFloat x1, CGFloat y1,CGFloat x2, CGFloat y2, CGFloat radius)
//x1,y1跟p1形成一条线,x2,y2跟x1,y1坐标形成一条线,然后将这两条线作为切线,画出圆心求出半径,radius半径,注意, 需要算好半径的长度,
CGContextAddArcToPoint(context, 148, 68, 156, 80, 10);
CGContextStrokePath(context);//绘画路径
椭圆、圆角按钮、图片、贝塞尔曲线
//画椭圆CGContextAddEllipseInRect(context, CGRectMake(160, 180, 20, 8)); //椭圆CGContextDrawPath(context, kCGPathFillStroke);/*画圆角矩形*/float fw = 180;float fh = 280;CGContextMoveToPoint(context, fw, fh-20); // 开始坐标右边开始CGContextAddArcToPoint(context, fw, fh, fw-20, fh, 10); // 右下角角度CGContextAddArcToPoint(context, 120, fh, 120, fh-20, 10); // 左下角角度CGContextAddArcToPoint(context, 120, 250, fw-20, 250, 10); // 左上角CGContextAddArcToPoint(context, fw, 250, fw, fh-20, 10); // 右上角CGContextClosePath(context);CGContextDrawPath(context, kCGPathFillStroke); //根据坐标绘制路径/*画贝塞尔曲线*///二次曲线CGContextMoveToPoint(context, 120, 300);//设置Path的起点CGContextAddQuadCurveToPoint(context,190, 310, 120, 390);//设置贝塞尔曲线的控制点坐标和终点坐标CGContextStrokePath(context);//三次曲线函数CGContextMoveToPoint(context, 200, 300);//设置Path的起点CGContextAddCurveToPoint(context,250, 280, 250, 400, 280, 300);//设置贝塞尔曲线的控制点坐标和控制点坐标终点坐标CGContextStrokePath(context);/*图片*/UIImage *image = [UIImage imageNamed:@"Snip20150715_1"];[image drawInRect:CGRectMake(60, 340, 60, 60)];//在坐标中画出图片
// [image drawAtPoint:CGPointMake(100, 340)];//保持图片大小在point点开始画图片CGContextDrawImage(context, CGRectMake(100, 340, 60, 60), image.CGImage);//使图片上下颠倒
这里就不贴图了。
下面综合案例,画出自己的表情小黄人
实现效果:
代码如下:
//
// YLView.m
// 我的QQ表情
// 联系方式: 492199045@qq.com
// Created by 薛银亮 on 15/7/15.
// Copyright (c) 2015年 薛银亮. All rights reserved.
//#import "YLView.h"
#define YLColor(r, g, b) [UIColor colorWithRed:r / 255.0 green:g / 255.0 blue:b / 255.0 alpha:1.1]@implementation YLView- (void)drawRect:(CGRect)rect {//获取当前上下文CGContextRef context = UIGraphicsGetCurrentContext();//画身体//头圆CGFloat x = self.bounds.size.width * 0.5;CGFloat y = self.bounds.size.height /3;CGFloat radius = self.bounds.size.width / 4;CGContextAddArc(context, x, y, radius, 0, M_PI, 1);//身线CGFloat h = y + 150;CGContextAddLineToPoint(context, x-radius, h);//下巴CGContextAddArc(context, x, h, radius, M_PI, 2*M_PI, 1);CGContextClosePath(context);//颜色[YLColor(249, 201, 40) setFill];CGContextFillPath(context);//画嘴CGFloat zuiqX = x-radius/4 -10;CGFloat zuiqY = h-20;CGFloat kongX = x;CGFloat kongY = zuiqY + 15;CGFloat zhongX = x + radius / 4 +10;CGFloat zhongY = zuiqY;CGContextMoveToPoint(context, zuiqX, zuiqY);CGContextAddQuadCurveToPoint(context, kongX, kongY, zhongX, zhongY);[YLColor(0 , 0, 0) setStroke];CGContextSetLineWidth(context, 4);CGContextStrokePath(context);//画牙CGContextMoveToPoint(context, x-5, kongY-5);CGFloat yazhongX = x -5;CGFloat yazhongY = kongY +10;[YLColor(255, 255, 255) set];CGContextAddLineToPoint(context, yazhongX, yazhongY);CGContextSetLineWidth(context, 12);
// CGContextSetLineCap(context, kCGLineCapRound);CGContextStrokePath(context);//画头符CGRect toufuRect = CGRectMake(x - radius, y, 2*radius, 30);CGContextAddRect(context, toufuRect);[YLColor(0, 0, 0) setFill];CGContextFillPath(context);//画头符汉字NSString *toufuString = @"iOS黄人";CGRect toufuStrRect = CGRectMake(zuiqX, y+4, radius, 30);NSMutableDictionary *toufuStrDict = [NSMutableDictionary dictionary];toufuStrDict[NSFontAttributeName] = [UIFont systemFontOfSize:20 weight:6];toufuStrDict[NSForegroundColorAttributeName] = [UIColor redColor];[toufuString drawInRect:toufuStrRect withAttributes:toufuStrDict];CGContextStrokePath(context);//画眼睛//左眼CGContextMoveToPoint(context, zuiqX, y+50);CGFloat zyanzhongX = zuiqX;CGFloat zyanzhongY = y + 60;[YLColor(0, 0, 0) set];CGContextAddLineToPoint(context, zyanzhongX, zyanzhongY);CGContextSetLineWidth(context, 8);CGContextSetLineCap(context, kCGLineCapRound);//右眼CGContextMoveToPoint(context, zhongX, y+50);CGFloat yyanzhongX = zhongX;CGFloat yyanzhongY = y + 60;CGContextAddLineToPoint(context, yyanzhongX, yyanzhongY);CGContextStrokePath(context);}@end
(二)进阶
上下文栈
上面的案例可以看出来存在很多不恰当的地方,我们每次画出来一部分都要重新设置
当前上下文的状态,以便下一次的使用。
这在使用的过程中很不方便,所以就有了图形上下文栈的操作。
假如我们知道当前上下文的状态在以后会使用,但是紧接着我们要使用其他的上下文状态,这时候,我们就可以把当前的上下文保存起来,相当于拷贝的操作,并存储在栈顶中:
保存:
void CGContextSaveGState(CGContextRef c)
当我们需要重新使用这个状态的上下文的时候,就可以将上下文出栈,替换掉当前正在使用的上下文。
void CGContextRestoreGState(CGContextRef c)
举例:
我们先画出来一个圆形和一个正方形,然后再来看看问题所在
- (void)drawRect:(CGRect)rect {//获得当前上下文CGContextRef context = UIGraphicsGetCurrentContext();//设置所画的图形的颜色和线宽CGContextSetLineWidth(context, 10);[[UIColor redColor]setStroke];//画一个圆形CGContextAddEllipseInRect(context, CGRectMake(100, 100, 50, 50));//显示出来所画的图形CGContextStrokePath(context);//画一个正方形CGContextAddRect(context, CGRectMake(200, 200, 50, 50));//显示出来所画的图形CGContextStrokePath(context);
}
如果我们想给正方形设置成黑色的细线形状,那么,我们就要重新设置LineWight和Color。这看起来是没有问题的。但是如果我们画的不只是两个不一样的图形,而是多个,那么这样就显得非常的麻烦。下面我们看看怎么使用上下文栈解决这个问题:
- (void)drawRect:(CGRect)rect {//获得当前上下文CGContextRef context = UIGraphicsGetCurrentContext();//保存上下文的初始状态,以便后面使用CGContextSaveGState(context);//设置所画的图形的颜色和线宽CGContextSetLineWidth(context, 10);[[UIColor redColor]setStroke];//画一个圆形CGContextAddEllipseInRect(context, CGRectMake(100, 100, 50, 50));CGContextStrokePath(context);//拿出上次保存的上下文的状态,用来设置正方形那个的样子CGContextRestoreGState(context);//画一个正方形CGContextAddRect(context, CGRectMake(200, 200, 50, 50));//显示出来所画的图形CGContextStrokePath(context);
}
矩阵操作
所谓的矩阵操作就是将类似于我们之前的所有的画线操作一起进行一些操作,比如:旋转、平移、缩放等。
下面,我们将上面的知识点举个例子学习一下:
我们将上面的例子中的圆形和正方形同时进行旋转、平移等操作:
- (void)drawRect:(CGRect)rect {//获得当前上下文CGContextRef context = UIGraphicsGetCurrentContext();//矩阵操作//旋转CGContextRotateCTM(context, M_1_PI);//平移CGContextTranslateCTM(context, 0, 100);//缩放CGContextScaleCTM(context, 1.5, 0.5);//保存上下文的初始状态,以便后面使用CGContextSaveGState(context);//设置所画的图形的颜色和线宽CGContextSetLineWidth(context, 10);[[UIColor redColor]setStroke];//画一个圆形CGContextAddEllipseInRect(context, CGRectMake(100, 100, 50, 50));CGContextStrokePath(context);//拿出上次保存的上下文的状态,用来设置正方形那个的样子CGContextRestoreGState(context);//画一个正方形CGContextAddRect(context, CGRectMake(200, 200, 50, 50));//显示出来所画的图形CGContextStrokePath(context);
}
裁剪
剪裁一
显示在指定的UIView上
我们可以把一张图片裁剪成自己想要的图形
- 设置好要裁剪的图形
- 将准备好的图片放在裁剪区域
示例:
- (void)drawRect:(CGRect)rect {//获得当前上下文CGContextRef context = UIGraphicsGetCurrentContext();//截图操作//画出要截取的区域-圆CGContextAddEllipseInRect(context, CGRectMake(100, 100, 100, 100));//剪裁CGContextClip(context);CGContextFillPath(context);//添加一张图片UIImage *image = [UIImage imageNamed:@"Snip20150716_10"];[image drawInRect:CGRectMake(50, 50, 200, 200)];
}
剪裁二
显示成一张图片,方便使用。
显示结果:
我们可以把这个功能抽取成UIImage的分类,以便以后的使用:
+ (instancetype)circleImageWithName:(NSString *)name borderWidth:(CGFloat)borderWidth borderColor:(UIColor *)borderColor
{// 1.加载原图UIImage *oldImage = [UIImage imageNamed:name];// 2.开启上下文CGFloat imageW = oldImage.size.width + 2 * borderWidth;CGFloat imageH = oldImage.size.height + 2 * borderWidth;CGSize imageSize = CGSizeMake(imageW, imageH);UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0.0);// 3.取得当前的上下文CGContextRef ctx = UIGraphicsGetCurrentContext();// 4.画边框(大圆)[borderColor set];CGFloat bigRadius = imageW * 0.5; // 大圆半径CGFloat centerX = bigRadius; // 圆心CGFloat centerY = bigRadius;CGContextAddArc(ctx, centerX, centerY, bigRadius, 0, M_PI * 2, 0);CGContextFillPath(ctx); // 画圆// 5.小圆CGFloat smallRadius = bigRadius - borderWidth;CGContextAddArc(ctx, centerX, centerY, smallRadius, 0, M_PI * 2, 0);// 裁剪(后面画的东西才会受裁剪的影响)CGContextClip(ctx);// 6.画图[oldImage drawInRect:CGRectMake(borderWidth, borderWidth, oldImage.size.width, oldImage.size.height)];// 7.取图UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();// 8.结束上下文UIGraphicsEndImageContext();return newImage;
}
补充:我们一般会将画好的图像保存起来。保存到沙河Documents的方法如下:
//先将图片压缩
NSData *data = UIImagePNGRepresentation(newImage);
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"new.png"];
[data writeToFile:path atomically:YES];
重绘(刷帧)
在使用绘画的时候,我们经常要不断的更新画面,但是系统的
- (void)drawRect:(CGRect)rect;
这个函数只会默认调用一次,而且我们不能手动去调用(因为我们在其他地方无法获取到系统的上下文)。所以就要用到重绘了。
所谓重绘,关键要用到这个函数:
- (void)setNeedsDisplay;
在重绘的时候,我们有时候会用到定时器,这里补充一下定时器知识,我们可以使用这两种定时器,例子:
CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)];[link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
这种定时器会默认在1秒钟刷新60次,而且使用时候要加入到主运行循环中,这样有时候会看着更加的流畅。
第二种:
[NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(setNeedsDisplay) userInfo:nil repeats:YES];
这种用户可以自定义刷新的频率
例子
:
贴出一个雪花下降的程序:
#import "YLView.h"@interface YLView()
/**y值*/
@property(nonatomic,assign) CGFloat snowY;
@end
@implementation YLView-(void)awakeFromNib
{CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)];[link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
// [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(setNeedsDisplay) userInfo:nil repeats:YES];
}- (void)drawRect:(CGRect)rect {self.snowY +=5;UIImage *image = [UIImage imageNamed:@"snow.jpg"];[image drawAtPoint:CGPointMake(0, self.snowY)];}
制作水印图片
水印图片是指在一张图片上面添加上属于自己的标志,例如很多商标图片上面的右下角都会有一个小小的标志。下面我们画一个这样的例子。
效果如下
像这样的例子,可能会经常用到,所以我们最好将这个功能封装成一个分类。这里因为是UIImage的功能,所以我们将其封装成UIImage的分类。
代码示例:
//
// UIImage+Water.m
// 打水印
// 联系方式: 492199045@qq.com
// Created by 薛银亮 on 15/7/17.
// Copyright (c) 2015年 薛银亮. All rights reserved.
// 水印图片#import "UIImage+Water.h"@implementation UIImage (Water)
+(UIImage *)imageWithWaterBackGroundImage:(NSString *)backgroundImageString IconImageString:(NSString *)iconImageString
{//背景图片UIImage *backImage = [UIImage imageNamed:backgroundImageString];//水印图标UIImage *iconImage = [UIImage imageNamed:iconImageString];//开启一个图片上下文UIGraphicsBeginImageContextWithOptions(backImage.size, NO, 0.0);//画背景CGFloat backW = backImage.size.width;CGFloat backH = backImage.size.height;[backImage drawInRect:CGRectMake(0, 0, backW, backH)];//画水印//计算水印所在的位置CGFloat margin = 10;CGFloat scale = 0.1;CGFloat iconW = iconImage.size.width * scale;CGFloat iconH = iconImage.size.height * scale;CGFloat X = backW - iconW - margin;CGFloat Y = backH - iconH - margin;[iconImage drawInRect:CGRectMake(X, Y, iconW, iconH)];//获取图形上下文的图片UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();//结束图形上下文UIGraphicsEndImageContext();return newImage;
}@end
屏幕截屏
这里也封装到UIImage的分类中了
+ (instancetype)captureWithView:(UIView *)view
{// 1.开启上下文UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, 0.0);// 2.将控制器view的layer渲染到上下文[view.layer renderInContext:UIGraphicsGetCurrentContext()];// 3.取出图片UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();// 4.结束上下文UIGraphicsEndImageContext();return newImage;
}
转载于:https://www.cnblogs.com/66it/p/4655966.html
iOS中-Qutarz2D详解及使用相关推荐
- iOS中scheme详解
一.什么是scheme? 我们知道在ios的程序中,由于沙盒的限制,导致程序之间相互隔离,没有一个有效的办法进行相互通信.但是也不是完全不可能实现,我们可以通过scheme url来实现程序间的通信. ...
- IOS中Socket详解
一.网络各个协议:TCP/IP.SOCKET.HTTP等 网络七层由下往上分别为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. 其中物理层.数据链路层和网络层通常被称作媒体层,是网络工程 ...
- php pcntl fork使用,php中pcntl_fork详解
pcntl_fork()函数是php-pcntl模块中用于创建进程的函数.(不支持windows) 至于php_pcntl扩展如何安装开启这里就不介绍了,只分析pcntl_fork()这个函数本身. ...
- iOS 2D绘图详解(Quartz 2D)之路径(点,直线,虚线,曲线,圆弧,椭圆,矩形)
前言:一个路径可以包含由一个或者多个shape以及子路径subpath,quartz提供了很多方便的shape可以直接调用.例如:point,line,Arc(圆弧),Curves(曲线),Ellip ...
- IOS 多线程04-GCD详解 底层并发 API
IOS 多线程04-GCD详解 底层并发 API 注:本人是翻译过来,并且加上本人的一点见解. 前言 想要揭示出表面之下深层次的一些可利用的方面.这些底层的 API 提供了大量的灵活性,随之而来的是大 ...
- 函数中{}输出格式详解(C#)
Console.WriteLine()函数中{}输出格式详解(C#) Console.WriteLine()函数的格式一直没怎么注意.今天同事问起Console.WriteLine({0:D3},a) ...
- Java中CAS详解
转载自 Java中CAS详解 在JDK 5之前Java语言是靠synchronized关键字保证同步的,这会导致有锁 锁机制存在以下问题: (1)在多线程竞争下,加锁.释放锁会导致比较多的上下文切换 ...
- 【转】图形流水线中坐标变换详解:模型矩阵、视角矩阵、投影矩阵
转自:图形流水线中坐标变换详解:模型矩阵.视角矩阵.投影矩阵_sherlockreal的博客-CSDN博客_视角矩阵 图形流水线中坐标变换详解:模型矩阵.视角矩阵.投影矩阵 图形流水线中坐标变换过程 ...
- oracle itl解析,oracle数据块dump文件中ITL详解
oracle数据块dump文件中ITL详解 dump出Oracle block后,可以看到事物槽,包含有事物槽号(ITL),XID,UBA,FLAG,LCK,SCN. 本文主要讨论FLAG标记的规则, ...
- iOS核心动画详解swift版----基础动画
2019独角兽企业重金招聘Python工程师标准>>> iOS核心动画详解swift版---基础动画 创建工程,添加2个ViewController,通过rootViewContro ...
最新文章
- 还是来说class,什么鬼,类会生宝宝
- PHP学习(php概念、基本语法、流程控制)
- map分组后取前10个_海关数据 | 图解前10个月外贸
- sap打勾选项记录_记录意外的开关选项
- Mac更新之后使用终端提示:The default interactive shell is now zsh.
- android基础面试题(三)
- Python面试-DB相关
- Android常见概念
- SD卡, EMMC固化 ,关于bootloader linux
- 生成器应用及知识推广
- RTF文件格式编码说明
- 计算机网络位置设置工作组,工作组设置【处置步骤】
- 对射式光电传感器测速使用CD10406消抖动解决办法
- 色彩空间(RGB, HSV, LAB, YUV)
- java 翻译框架_java框架外文翻译
- ps4看直播 HTML,ps4直播教学 怎么样才能直播
- PV 操作与案例分析
- linux 命令断网,linux 断网 扫描基本命令(示例代码)
- 【Linux常用指令2】
- iOS拍摄视频,自定义拍摄界面,高清压缩,添加水印
热门文章
- 【去广告插件推荐】AdBlock让浏览器清净
- unity制作伪全息投影
- python3实现网络爬虫(4)--BeautifulSoup使用(3)
- 海康威视java研发一面
- Nvivo使用步骤记录
- latch mysql_关于MySQL latch争用深入分析与判断
- 文化课很差能学计算机专业吗,文化成绩不好,想要学习计算机不知道能不能学呢?...
- DAS Over FC 技术允许 ATTO 分解存储并完成 vSAN 认证套件
- 2.2.7Python-异常处理
- LOJ#6198. 谢特【后缀自动机/数组 + Trie树查异或最大值 + Trie树合并】