Iphone 使用石英二维/核心图形完成此绘图的最佳方法?
作为我应用程序中一个视图的背景,我想在它的框架内画一个相当简单的矩形边框。这基本上是一个矩形渐变:在帧周围有一条黑线,在大约10-20像素的范围内逐渐变为白色。不幸的是,据我所知,Core Graphics不提供矩形渐变(使用Iphone 使用石英二维/核心图形完成此绘图的最佳方法?,iphone,objective-c,quartz-graphics,Iphone,Objective C,Quartz Graphics,作为我应用程序中一个视图的背景,我想在它的框架内画一个相当简单的矩形边框。这基本上是一个矩形渐变:在帧周围有一条黑线,在大约10-20像素的范围内逐渐变为白色。不幸的是,据我所知,Core Graphics不提供矩形渐变(使用CGGradient或CGShading)。所以我想知道最好的方法是什么 我想到两件事: 绘制一系列同心矩形,每个矩形的颜色都较浅,并在每侧插入1px。我想不出一个更简单的方法,但我必须自己做所有的梯度计算,可能需要很多图形操作 在线性模式下使用CGGradient,每侧一
CGGradient
或CGShading
)。所以我想知道最好的方法是什么
我想到两件事:
CGGradient
,每侧一次。但是为了让它工作,我想我需要先为每一侧设置一个梯形的剪裁区域,以便在拐角处斜接渐变NSBezierPath
创建梯形区域相当简单,只需执行四次绘图操作
以下是创建左侧梯形区域的基本代码:
NSRect outer = [self bounds];
NSPoint outerPoint[4];
outerPoint[0] = NSMakePoint(0, 0);
outerPoint[1] = NSMakePoint(0, outer.size.height);
outerPoint[2] = NSMakePoint(outer.size.width, outer.size.height);
outerPoint[3] = NSMakePoint(outer.size.width, 0);
NSRect inner = NSInsetRect([self bounds], borderSize, borderSize);
NSPoint innerPoint[4];
innerPoint[0] = inner.origin;
innerPoint[1] = NSMakePoint(inner.origin.x,
inner.origin.y + inner.size.height);
innerPoint[2] = NSMakePoint(inner.origin.x + inner.size.width,
inner.origin.y + inner.size.height);
innerPoint[3] = NSMakePoint(inner.origin.x + inner.size.width,
inner.origin.y);
NSBezierPath leftSidePath = [[NSBezierPath bezierPath] retain];
[leftSidePath moveToPoint:outerPoint[0]];
[leftSidePath lineToPoint:outerPoint[1]];
[leftSidePath lineToPoint:innerPoint[1]];
[leftSidePath lineToPoint:innerPoint[0]];
[leftSidePath lineToPoint:outerPoint[0]];
// ... etc.
[leftSidePath release];
像这样的事情也可以奏效。 基本上:不使用剪切路径,只需使用blendmode。 在这个例子中,梯度被缓存在CGLayer中
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGColorSpaceRef cspace = CGColorSpaceCreateDeviceRGB();
CGContextSetRGBFillColor(ctx, 1.0, 1.0, 1.0, 1.0);
CGContextFillRect(ctx,self.bounds);
CGFloat w = self.bounds.size.width;
CGFloat h = self.bounds.size.height;
CGFloat dh = (w-h)/2;
CGLayerRef l = CGLayerCreateWithContext(ctx,CGSizeMake(h,48.0f),NULL);
CGContextRef lctx = CGLayerGetContext(l);
float comp[] = { .2,.5,1.0,1.0,1.0,1.0,1.0,1.0};
CGGradientRef gradient = CGGradientCreateWithColorComponents(cspace, comp, NULL, 2);
CGContextDrawLinearGradient(lctx, gradient,CGPointMake(0,0),CGPointMake(0,48), 0);
CGContextSaveGState(ctx);
CGContextSetBlendMode(ctx,kCGBlendModeDarken);
for(int n=1;n<5;n++)
{
CGContextTranslateCTM(ctx,w/2.0,h/2.0);
CGContextRotateCTM(ctx, M_PI_2);
CGContextTranslateCTM(ctx,-w/2.0,-h/2.0);
CGContextDrawLayerAtPoint(ctx,CGPointMake((n%2)*dh,(n%2)*-dh),l);
}
CGContextRestoreGState(ctx);
CGContextRef ctx=UIGraphicsGetCurrentContext();
CGColorSpaceRef cspace=CGColorSpaceCreateDeviceRGB();
CGContextSetRGBFillColor(ctx,1.0,1.0,1.0,1.0);
CGContextFillRect(ctx,self.bounds);
CGFloat w=self.bounds.size.width;
CGH=self.bounds.size.height;
cgdh=(w-h)/2;
CGLayerRef l=CGLayerCreateWithContext(ctx,CGSizeMake(h,48.0f),NULL);
CGContextRef lctx=CGLayerGetContext(l);
浮点comp[]={.2,5,1.0,1.0,1.0,1.0,1.0,1.0,1.0};
CGGradientRef gradient=CGGradientCreateWithColorComponents(cspace,comp,NULL,2);
CGContextDrawLinearGradient(lctx,梯度,CGPointMake(0,0),CGPointMake(0,48),0);
CGContextSaveGState(ctx);
CGContextSetBlendMode(ctx、kCGBlendModeDarken);
对于(int n=1;对每条边使用CGGradient会更快,但如果速度仍然太慢,可以使用UIImage作为缓存(绘制一次UIImage,然后在需要时将图像绘制到视图上)是的,我认为无论我采取什么方法绘制,缓存带有结果的图像可能都是一个好主意。但我有点喜欢按程序绘制,而不是在应用程序中发布PNG。作为一个(显然?)没有在iPhone(或Mac)上做过很多图形编程的人来说然而…有没有理由选择NSBezierPath?我看到的大多数示例都集中在核心图形API上。我在这里使用它是因为我以前使用过它,所以知道它是有效的。:)核心图形完全有可能做得更好。尝试一下也无妨,但一定要对代码进行分析,看看您是否获得了可衡量的性能提升(或者您是否真的需要这样做)。这与我最终得到的代码并不完全相同,但也很相似。没有比画四个梯形更好的解决方案了。