头文件:
#include <CoreGraphics/CoreGraphics.h>
//绘制方式常量
//一个矩形区域
#define FS_DRAW_REGION_RECT (1 << 31)
//左上角圆角
#define FS_DRAW_REGION_LEFT_TOP_RADIUS (1)
//右上角圆角
#define FS_DRAW_REGION_RIGHT_TOP_RADIUS (1 << 1)
//右下角圆角
#define FS_DRAW_REGION_RIGHT_BOTTOM_RADIUS (1 << 2)
//左下角圆角
#define FS_DRAW_REGION_LEFT_BOTTOM_RADIUS (1 << 3)
//四周圆角
#define FS_DRAW_REGION_ROUND_RECT (FS_DRAW_REGION_LEFT_TOP_RADIUS | FS_DRAW_REGION_RIGHT_TOP_RADIUS | FS_DRAW_REGION_RIGHT_BOTTOM_RADIUS | FS_DRAW_REGION_LEFT_BOTTOM_RADIUS)
//从上往下
#define FS_LIGHT_FROM_TOP_TO_BOTTOM (1 << 8)
//从左往右
#define FS_LIGHT_FROM_LEFT_TO_RIGHT (1 << 9)
//从下往上
#define FS_LIGHT_FROM_BOTTOM_TO_TOP (1 << 10)
//从右往左
#define FS_LIGHT_FROM_RIGHT_TO_LEFT (1 << 11)
//从里往外
#define FS_LIGHT_FROM_INNER_TO_OUTER (1 << 12)
//往外往里
#define FS_LIGHT_FROM_OUTER_TO_INNER (1 << 13)
#define FS_ARROW_UP (1)
#define FS_ARROW_DOWN (1 << 1)
#define FS_ARROW_LEFT (1 << 2)
#define FS_ARROW_RIGHT (1 << 3)
//文本位置
#define TEXT_ALIGN_LEFT (1)
#define TEXT_ALIGN_RIGHT (2)
#define TEXT_ALIGN_TOP (3)
#define TEXT_ALIGN_BOTTOM (4)
//矩形渐变方向
#define GRADIENT_RECT_FROM_TOP_TO_BOTTOM (1)
#define GRADIENT_RECT_FROM_BOTTOM_TO_TOP (2)
#define GRADIENT_RECT_FROM_LEFT_TO_RIGHT (3)
#define GRADIENT_RECT_FROM_RIGHT_TO_LEFT (4)
//////////////////////////////////////////////////////////////////
// 函数说明:FOUNDATION_EXTERN
//////////////////////////////////////////////////////////////////
FOUNDATION_EXTERN void buildPathForRect(CGContextRef context, CGRect rect, CGFloat radius, NSUInteger radiusflag);
FOUNDATION_EXTERN void drawLightForPath(CGContextRef context, CGRect rect, NSUInteger lightFlag, CGGradientRef gradient, CGFloat startRadius, CGFloat endRadius);
FOUNDATION_EXTERN void drawCrystalRect(CGContextRef context, CGRect rect, CGFloat radius, const CGFloat *components, NSUInteger componentCount);
FOUNDATION_EXTERN UIImage *createImageWithRect(CGRect rect, CGFloat radius, const CGFloat *components, NSUInteger componentCount);
FOUNDATION_EXTERN void drawNavigatorArrow(CGContextRef context, CGRect rect, NSUInteger arrowDirection, const CGFloat *components, NSUInteger componentCount);
FOUNDATION_EXTERN UIImage *createNavigatorArrowWithRect(CGRect rect, NSUInteger arrowDirection, CGFloat boundSpace, const CGFloat *components, NSUInteger componentCount);
FOUNDATION_EXTERN void drawImageWithRect(CGContextRef context, CGRect rect, UIImage *image);
FOUNDATION_EXTERN UIImage *scaleImage(UIImage *source, CGSize destSize);
FOUNDATION_EXTERN UIImage *drawImageAndTextInRect(CGRect rect, UIImage *source, NSString *text, NSInteger textAlign);
//FOUNDATION_EXTERN void drawButtonImage
//还得加入参数,抽取成为一个函数
FOUNDATION_EXTERN UIImage *createImageInRectWithGradient(CGRect rect, CGFloat radius, const CGFloat *components, NSUInteger componentCount, CGFloat borderWidth);
FOUNDATION_EXTERN void drawGradientInRect(CGRect rect, CGContextRef context, CGColorSpaceRef colorSpace, const CGFloat *components, NSUInteger componentCount, NSUInteger directFlag);
FOUNDATION_EXTERN void drawTopGradientInRect(CGRect rect, CGContextRef context, CGColorSpaceRef colorSpace);
FOUNDATION_EXTERN void drawBottomGradientInRect(CGRect rect, CGContextRef context, CGColorSpaceRef colorSpace);
FOUNDATION_EXTERN void drawGradientInRectWithSingleColor(CGRect rect, CGFloat radius, CGFloat borderWidth, CGContextRef context, CGColorSpaceRef colorSpace, const CGFloat *components, NSUInteger componentCount, NSUInteger directFlag);
.mm 文件
#include "FSGraphicsEx.h"
#define RGB_ADDTION (30.0f / 255.0f)
typedef void(* DRAW_GRADIENT_FUNC)(CGContextRef, CGRect, CGColorSpaceRef, CGFloat *, CGFloat, NSUInteger);
void buildPathForRect(CGContextRef context, CGRect rect, CGFloat radius, NSUInteger radiusflag) {
if ((radiusflag & FS_DRAW_REGION_RECT) == FS_DRAW_REGION_RECT || radius == 0) {
#ifdef MYDEBUG
NSLog(@"FS_DRAW_REGION_RECT");
#endif
CGContextMoveToPoint(context, CGRectGetMinX(rect), CGRectGetMinY(rect));
CGContextAddLineToPoint(context, CGRectGetMaxX(rect), CGRectGetMinY(rect));
CGContextAddLineToPoint(context, CGRectGetMaxX(rect), CGRectGetMaxY(rect));
CGContextAddLineToPoint(context, CGRectGetMinX(rect), CGRectGetMaxY(rect));
CGContextClosePath(context);
} else {
//左上
CGContextMoveToPoint(context, CGRectGetMinX(rect), CGRectGetMidY(rect));
if ((radiusflag & FS_DRAW_REGION_LEFT_TOP_RADIUS) == FS_DRAW_REGION_LEFT_TOP_RADIUS) {
#ifdef MYDEBUG
NSLog(@"FS_DRAW_REGION_LEFT_TOP_RADIUS");
#endif
CGContextAddArcToPoint(context, CGRectGetMinX(rect), CGRectGetMinY(rect), CGRectGetMidX(rect), CGRectGetMinY(rect), radius);
} else {
CGContextAddLineToPoint(context, CGRectGetMinX(rect), CGRectGetMinY(rect));
}
CGContextAddLineToPoint(context, CGRectGetMidX(rect), CGRectGetMinY(rect));
//右上
if ((radiusflag & FS_DRAW_REGION_RIGHT_TOP_RADIUS) == FS_DRAW_REGION_RIGHT_TOP_RADIUS) {
#ifdef MYDEBUG
NSLog(@"FS_DRAW_REGION_RIGHT_TOP_RADIUS");
#endif
CGContextAddArcToPoint(context, CGRectGetMaxX(rect), CGRectGetMinY(rect), CGRectGetMaxX(rect), CGRectGetMidY(rect), radius);
} else {
CGContextAddLineToPoint(context, CGRectGetMaxX(rect), CGRectGetMinY(rect));
}
CGContextAddLineToPoint(context, CGRectGetMaxX(rect), CGRectGetMidY(rect));
//右下
if ((radiusflag & FS_DRAW_REGION_RIGHT_BOTTOM_RADIUS) == FS_DRAW_REGION_RIGHT_BOTTOM_RADIUS) {
#ifdef MYDEBUG
NSLog(@"FS_DRAW_REGION_RIGHT_BOTTOM_RADIUS");
#endif
CGContextAddArcToPoint(context, CGRectGetMaxX(rect), CGRectGetMaxY(rect), CGRectGetMidX(rect), CGRectGetMaxY(rect), radius);
} else {
CGContextAddLineToPoint(context, CGRectGetMaxX(rect), CGRectGetMaxY(rect));
}
CGContextAddLineToPoint(context, CGRectGetMidX(rect), CGRectGetMaxY(rect));
//左下
if ((radiusflag & FS_DRAW_REGION_LEFT_BOTTOM_RADIUS) == FS_DRAW_REGION_LEFT_BOTTOM_RADIUS) {
#ifdef MYDEBUG
NSLog(@"FS_DRAW_REGION_LEFT_BOTTOM_RADIUS");
#endif
CGContextAddArcToPoint(context, CGRectGetMinX(rect), CGRectGetMaxY(rect), CGRectGetMinX(rect), CGRectGetMidY(rect), radius);
} else {
CGContextAddLineToPoint(context, CGRectGetMinX(rect), CGRectGetMaxY(rect));
}
CGContextAddLineToPoint(context, CGRectGetMinX(rect), CGRectGetMidY(rect));
if (radiusflag == FS_DRAW_REGION_ROUND_RECT) {
CGContextClosePath(context);
}
}
}
void drawLightForPath(CGContextRef context, CGRect rect, NSUInteger lightFlag, CGGradientRef gradient, CGFloat startRadius, CGFloat endRadius) {
CGPoint startPoint = CGPointZero;
CGPoint endPoint = CGPointZero;
if (lightFlag == FS_LIGHT_FROM_INNER_TO_OUTER ||
lightFlag == FS_LIGHT_FROM_OUTER_TO_INNER) {
CGFloat radius1 = 0;
CGFloat radius2 = 0;
startPoint = CGPointMake(CGRectGetMinX(rect) + rect.size.width / 2.0f, CGRectGetMinY(rect) + rect.size.height / 2.0f);
endPoint = startPoint;
if (lightFlag == FS_LIGHT_FROM_INNER_TO_OUTER) {
radius1 = MIN(startRadius, endRadius);
radius2 = MAX(startRadius, endRadius);
} else {
radius1 = MAX(startRadius, endRadius);
radius2 = MIN(startRadius, endRadius);
}
CGContextDrawRadialGradient(context, gradient, startPoint, radius1, endPoint, radius2, 0);
} else {
if (lightFlag == FS_LIGHT_FROM_TOP_TO_BOTTOM) {
startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
} else if (lightFlag == FS_LIGHT_FROM_LEFT_TO_RIGHT) {
startPoint = CGPointMake(CGRectGetMinX(rect), CGRectGetMidY(rect));
endPoint = CGPointMake(CGRectGetMaxX(rect), CGRectGetMidY(rect));
} else if (lightFlag == FS_DRAW_REGION_LEFT_BOTTOM_RADIUS) {
startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
} else if (lightFlag == FS_LIGHT_FROM_RIGHT_TO_LEFT) {
startPoint = CGPointMake(CGRectGetMaxX(rect), CGRectGetMidY(rect));
endPoint = CGPointMake(CGRectGetMinX(rect), CGRectGetMidY(rect));
}
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
}
}
void drawCrystalRect(CGContextRef context, CGRect rect, CGFloat radius, const CGFloat *components, NSUInteger componentCount) {
//STEP 1.
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
//STEP 2.
CGFloat colors[4] = {0};
if (componentCount >= 4) {
colors[0] = components[0];
colors[1] = components[1];
colors[2] = components[2];
colors[3] = components[3];
} else if (componentCount == 2) {
colors[0] = components[0];
colors[1] = components[0];
colors[2] = components[0];
colors[3] = components[1];
}
#ifdef MYDEBUG
NSLog(@"componentCount=%d;r=%f;g=%f;b=%f;a=%f", componentCount, colors[0], colors[1], colors[2], colors[3]);
#endif
CGRect rClient = rect;
rClient.origin.x++;
rClient.origin.y++;
rClient.size.width -= 2;
rClient.size.height -= 2;
CGContextSaveGState(context);
buildPathForRect(context, rClient, radius, (FS_DRAW_REGION_LEFT_TOP_RADIUS | FS_DRAW_REGION_RIGHT_TOP_RADIUS | FS_DRAW_REGION_RIGHT_BOTTOM_RADIUS | FS_DRAW_REGION_LEFT_BOTTOM_RADIUS));
CGContextSetRGBFillColor(context, colors[0], colors[1], colors[2], colors[3]);
CGContextSetRGBStrokeColor(context, colors[0], colors[1], colors[2], colors[3]);
CGContextSetLineWidth(context, 2.0f);
CGContextDrawPath(context, kCGPathFillStroke);
CGContextRestoreGState(context);
//STEP 3.
CGContextSaveGState(context);
CGContextSetLineWidth(context, 2.0f);
CGFloat topGradientColors[] =
{
1.0f, 1.0f, 1.0f, 0.6,
1.0f, 1.0f, 1.0f, 0.3,
1.0f, 1.0f, 1.0f, 0.0
};
CGRect topRect = CGRectMake(CGRectGetMinX(rClient), CGRectGetMinY(rClient), rClient.size.width, rClient.size.height / 2.0f);
CGGradientRef topGradient = CGGradientCreateWithColorComponents(colorSpace, topGradientColors, NULL, sizeof(topGradientColors) / (4 * sizeof(CGFloat)));
buildPathForRect(context, topRect, radius, (FS_DRAW_REGION_LEFT_TOP_RADIUS | FS_DRAW_REGION_RIGHT_TOP_RADIUS));
CGContextClip(context);
drawLightForPath(context, topRect, FS_LIGHT_FROM_TOP_TO_BOTTOM, topGradient, 0.0f, 0.0f);
CGGradientRelease(topGradient);
CGContextRestoreGState(context);
//STEP 4.
CGContextSaveGState(context);
CGContextSetLineWidth(context, 2.0f);
CGFloat bottomGradientColors[] =
{
0.0f, 0.0f, 0.0f, 0.15,
0.0f, 0.0f, 0.0f, 0.15,
0.0f, 0.0f, 0.0f, 0.15
};
CGRect bottomRect = CGRectMake(CGRectGetMinX(rClient), CGRectGetMidY(rClient), rClient.size.width, rClient.size.height / 2.0f);
CGGradientRef bottomGradient = CGGradientCreateWithColorComponents(colorSpace, bottomGradientColors, NULL, sizeof(bottomGradientColors) / (4 * sizeof(CGFloat)));
buildPathForRect(context, bottomRect, radius, FS_DRAW_REGION_RIGHT_BOTTOM_RADIUS | FS_DRAW_REGION_LEFT_BOTTOM_RADIUS);
CGContextClip(context);
drawLightForPath(context, bottomRect, FS_LIGHT_FROM_TOP_TO_BOTTOM, bottomGradient, 0.0f, 0.0f);
CGGradientRelease(bottomGradient);
CGContextRestoreGState(context);
//STEP 5.
rect.origin.x += 0.5;
rect.origin.y += 0.5;
rect.size.width -= 1;
rect.size.height -= 1;
CGContextSaveGState(context);
buildPathForRect(context, rect, radius, (FS_DRAW_REGION_LEFT_TOP_RADIUS | FS_DRAW_REGION_RIGHT_TOP_RADIUS | FS_DRAW_REGION_RIGHT_BOTTOM_RADIUS | FS_DRAW_REGION_LEFT_BOTTOM_RADIUS));
colors[0] += RGB_ADDTION * 1.2;
colors[1] += RGB_ADDTION * 1.2;
colors[2] += RGB_ADDTION * 1.2;
if (colors[0] > 1) {
colors[0] = 1.0f;
}
if (colors[1] > 1) {
colors[1] = 1.0f;
}
if (colors[2] > 1) {
colors[2] = 1.0f;
}
//CGContextSetRGBStrokeColor(context, 125.0f / 255.0f, 125.0f / 255.0f, 125.0f / 255.0f, 1.0f);
CGContextSetRGBStrokeColor(context, colors[0], colors[1], colors[2], 1.0f);
CGContextSetLineWidth(context, 1);
CGContextDrawPath(context, kCGPathStroke);
CGContextRestoreGState(context);
//STEP 6.
CGContextSaveGState(context);
rect.origin.x += 1;
rect.origin.y += 1;
rect.size.width -= 2;
rect.size.height -= 2;
radius--;
colors[0] -= RGB_ADDTION * 1.5f;
colors[1] -= RGB_ADDTION * 1.5f;
colors[2] -= RGB_ADDTION * 1.5f;
if (colors[0] < 0) {
colors[0] = 0.0f;
}
if (colors[1] < 0) {
colors[1] = 0.0f;
}
if (colors[2] < 0) {
colors[2] = 0.0f;
}
buildPathForRect(context, rect, radius, (FS_DRAW_REGION_LEFT_TOP_RADIUS | FS_DRAW_REGION_RIGHT_TOP_RADIUS | FS_DRAW_REGION_RIGHT_BOTTOM_RADIUS | FS_DRAW_REGION_LEFT_BOTTOM_RADIUS));
//CGContextSetRGBStrokeColor(context, 229.0f / 255.0f, 229.0f / 255.0f, 229.0f / 255.0f, 1.0f);
CGContextSetRGBStrokeColor(context, colors[0], colors[1], colors[2], 1.0f);
CGContextSetLineWidth(context, 1.5);
CGContextDrawPath(context, kCGPathStroke);
CGContextRestoreGState(context);
//STEP 7.
CGColorSpaceRelease(colorSpace);
}
UIImage *createImageWithRect(CGRect rect, CGFloat radius, const CGFloat *components, NSUInteger componentCount) {
UIImage *result = nil;
//STEP 1.
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, rect.size.width, rect.size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Little);
CGContextTranslateCTM (context, 0, rect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
//STEP 2.
drawCrystalRect(context, CGRectMake(0.0f, 0.0f, rect.size.width, rect.size.height), radius, components, componentCount);
//STEP 3.
CGImageRef image = CGBitmapContextCreateImage(context);
result = [UIImage imageWithCGImage:image];
CGImageRelease(image);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
//STEP 4.
return result;
}
/////////////////////////////////////////
// 绘制导航箭头
////////////////////////////////////////
void drawNavigatorArrow(CGContextRef context, CGRect rect, NSUInteger arrowDirection, const CGFloat *components, NSUInteger componentCount) {
CGFloat colors[4] = {0};
if (componentCount >= 4) {
colors[0] = components[0];
colors[1] = components[1];
colors[2] = components[2];
colors[3] = components[3];
} else if (componentCount == 2) {
colors[0] = components[0];
colors[1] = components[0];
colors[2] = components[0];
colors[3] = components[1];
} else {
colors[0] = 239.0f / 255.0f;
colors[1] = 239.0f / 255.0f;
colors[2] = 239.0f / 255.0f;
colors[3] = 1.0f;
}
//STEP 1.
CGContextSaveGState(context);
CGContextSetRGBStrokeColor(context, 1.0f, 1.0f, 1.0f, 0.0f);
CGContextSetRGBFillColor(context, 1.0f, 1.0f, 1.0f, 0.0f);
CGContextSetLineWidth(context, 0.0f);
buildPathForRect(context, rect, 0.0f, FS_DRAW_REGION_RECT);
CGContextDrawPath(context, kCGPathFillStroke);
CGContextRestoreGState(context);
//STEP 2.
CGContextSaveGState(context);
if (arrowDirection == FS_ARROW_UP) {
CGContextMoveToPoint(context, CGRectGetMidX(rect), CGRectGetMinY(rect));
CGContextAddLineToPoint(context, CGRectGetMaxX(rect), CGRectGetMidY(rect));
CGContextAddLineToPoint(context, rect.size.width * 2 / 3.0f + CGRectGetMinX(rect), CGRectGetMidY(rect));
CGContextAddLineToPoint(context, rect.size.width * 2 / 3.0f + CGRectGetMinX(rect), CGRectGetMaxY(rect));
CGContextAddLineToPoint(context, rect.size.width / 3.0f + CGRectGetMinX(rect), CGRectGetMaxY(rect));
CGContextAddLineToPoint(context, rect.size.width / 3.0f + CGRectGetMinX(rect), CGRectGetMidY(rect));
CGContextAddLineToPoint(context, CGRectGetMinX(rect), CGRectGetMidY(rect));
CGContextClosePath(context);
} else if (arrowDirection == FS_ARROW_DOWN) {
CGContextMoveToPoint(context, CGRectGetMidX(rect), CGRectGetMaxY(rect));
CGContextAddLineToPoint(context, CGRectGetMaxX(rect), CGRectGetMidY(rect));
CGContextAddLineToPoint(context, rect.size.width * 2 / 3.0f + CGRectGetMinX(rect), CGRectGetMidY(rect));
CGContextAddLineToPoint(context, rect.size.width * 2 / 3.0f + CGRectGetMinX(rect), CGRectGetMinY(rect));
CGContextAddLineToPoint(context, rect.size.width / 3.0f + CGRectGetMinX(rect), CGRectGetMinY(rect));
CGContextAddLineToPoint(context, rect.size.width / 3.0f + CGRectGetMinX(rect), CGRectGetMidY(rect));
CGContextAddLineToPoint(context, CGRectGetMinX(rect), CGRectGetMidY(rect));
CGContextClosePath(context);
} else if (arrowDirection == FS_ARROW_LEFT) {
CGContextMoveToPoint(context, CGRectGetMinX(rect), CGRectGetMidY(rect));
CGContextAddLineToPoint(context, CGRectGetMidX(rect), CGRectGetMinY(rect));
CGContextAddLineToPoint(context, CGRectGetMidX(rect), rect.size.height / 3.0f + CGRectGetMinY(rect));
CGContextAddLineToPoint(context, CGRectGetMaxX(rect), rect.size.height / 3.0f + CGRectGetMinY(rect));
CGContextAddLineToPoint(context, CGRectGetMaxX(rect), rect.size.height * 2.0 / 3.0f + CGRectGetMinY(rect));
CGContextAddLineToPoint(context, CGRectGetMidX(rect), rect.size.height * 2.0 / 3.0f + CGRectGetMinY(rect));
CGContextAddLineToPoint(context, CGRectGetMidX(rect), CGRectGetMaxY(rect));
CGContextClosePath(context);
} else if (arrowDirection == FS_ARROW_RIGHT) {
CGContextMoveToPoint(context, CGRectGetMaxX(rect), CGRectGetMidY(rect));
CGContextAddLineToPoint(context, CGRectGetMidX(rect), CGRectGetMaxY(rect));
CGContextAddLineToPoint(context, CGRectGetMidX(rect), rect.size.height * 2.0 / 3.0f + CGRectGetMinY(rect));
CGContextAddLineToPoint(context, CGRectGetMinX(rect), rect.size.height * 2.0 / 3.0f + CGRectGetMinY(rect));
CGContextAddLineToPoint(context, CGRectGetMinX(rect), rect.size.height / 3.0f + CGRectGetMinY(rect));
CGContextAddLineToPoint(context, CGRectGetMidX(rect), rect.size.height / 3.0f + CGRectGetMinY(rect));
CGContextAddLineToPoint(context, CGRectGetMidX(rect), CGRectGetMinY(rect));
CGContextClosePath(context);
} else {
CGContextMoveToPoint(context, CGRectGetMinX(rect), CGRectGetMidY(rect));
CGContextAddLineToPoint(context, CGRectGetMidX(rect), CGRectGetMinY(rect));
CGContextAddLineToPoint(context, CGRectGetMidX(rect), rect.size.height / 3.0f + CGRectGetMinY(rect));
CGContextAddLineToPoint(context, CGRectGetMaxX(rect), rect.size.height / 3.0f + CGRectGetMinY(rect));
CGContextAddLineToPoint(context, CGRectGetMaxX(rect), rect.size.height * 2.0 / 3.0f + CGRectGetMinY(rect));
CGContextAddLineToPoint(context, CGRectGetMidX(rect), rect.size.height * 2.0 / 3.0f + CGRectGetMinY(rect));
CGContextAddLineToPoint(context, CGRectGetMidX(rect), CGRectGetMaxY(rect));
CGContextClosePath(context);
}
CGContextSetRGBFillColor(context, colors[0], colors[1], colors[2], colors[3]);
CGContextSetRGBStrokeColor(context, colors[0], colors[1], colors[2], colors[3]);
CGContextSetLineWidth(context, 1.0f);
CGContextDrawPath(context, kCGPathFillStroke);
CGContextRestoreGState(context);
}
UIImage *createNavigatorArrowWithRect(CGRect rect, NSUInteger arrowDirection, CGFloat boundSpace, const CGFloat *components, NSUInteger componentCount) {
UIImage *result = nil;
//STEP 1.
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, rect.size.width, rect.size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Little);
CGContextTranslateCTM (context, 0, rect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
//STEP 2.
CGRect rArrow = CGRectMake(boundSpace + CGRectGetMinX(rect), boundSpace + CGRectGetMinY(rect), rect.size.width - boundSpace * 2.0f, rect.size.height - boundSpace * 2.0f);
drawNavigatorArrow(context, rArrow, arrowDirection, components, componentCount);
//STEP 3.
CGImageRef image = CGBitmapContextCreateImage(context);
result = [UIImage imageWithCGImage:image];
CGImageRelease(image);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
//STEP 4.
return result;
}
UIImage *scaleImage(UIImage *source, CGSize destSize) {
CGFloat destW = destSize.width;
CGFloat destH = destSize.height;
CGImageRef imageRef = source.CGImage;
CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast;//CGImageGetBitmapInfo(imageRef);
CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef);
CGContextRef bitmap = NULL;
size_t bitsPerComponent = CGImageGetBitsPerComponent(imageRef);
size_t bytesPerRow = 0;// CGImageGetBytesPerRow(imageRef);
#ifdef MYDEBUG
NSLog(@"bitsPerComponent=%d;bytesPerRow=%d", bitsPerComponent, bytesPerRow);
#endif
if (source.imageOrientation == UIImageOrientationUp || source.imageOrientation == UIImageOrientationDown) {
bitmap = CGBitmapContextCreate(NULL, destW, destH, bitsPerComponent, bytesPerRow, colorSpaceInfo, bitmapInfo);
} else {
bitmap = CGBitmapContextCreate(NULL, destH, destW, bitsPerComponent, bytesPerRow, colorSpaceInfo, bitmapInfo);
}
if (source.imageOrientation == UIImageOrientationLeft) {
CGContextRotateCTM (bitmap, M_PI / 2.0f);
CGContextTranslateCTM (bitmap, 0, - destW);
} else if (source.imageOrientation == UIImageOrientationRight) {
CGContextRotateCTM (bitmap, - M_PI / 2.0f);
CGContextTranslateCTM (bitmap, - destW, 0);
} else if (source.imageOrientation == UIImageOrientationUp) {
// NOTHING
} else if (source.imageOrientation == UIImageOrientationDown) {
CGContextTranslateCTM (bitmap, destW, destH);
CGContextRotateCTM (bitmap, - M_PI);
}
//CGContextScaleCTM(bitmap, destW / source.size.width, destH / source.size.height);
CGContextDrawImage(bitmap, CGRectMake(0, 0, destW, destH), imageRef);
CGImageRef ref = CGBitmapContextCreateImage(bitmap);
UIImage *result = [UIImage imageWithCGImage:ref];
CGContextRelease(bitmap);
CGImageRelease(ref);
return result;
}
void drawImageWithRect(CGContextRef context, CGRect rect, UIImage *image) {
NSInteger colCount = rect.size.width / image.size.width + 1;
NSInteger rowCount = rect.size.height / image.size.height + 1;
CGFloat left = CGRectGetMinX(rect);
CGFloat top = CGRectGetMinY(rect);
for (int i = 0; i < rowCount; i++) {
for (int j = 0; j < colCount; j++) {
CGRect rImage = CGRectMake(left, top, image.size.width, image.size.height);
CGContextDrawImage(context, rImage, image.CGImage);
left += rImage.size.width;
}
top += image.size.height;
left = CGRectGetMinX(rect);
//top += 100;
}
}
UIImage *drawImageAndTextInRect(CGRect rect, UIImage *source, NSString *text, NSInteger textAlign) {
UIImage *result = nil;
CGFloat radius = 4.0f;
CGFloat components[] =
{
184.0f / 255.0f,
235.0f / 255.0f,
255.0f / 255.0f,
1.0f
};
NSInteger componentCount = sizeof(components) / sizeof(CGFloat);
//STEP 1.
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, rect.size.width, rect.size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Little);
CGContextTranslateCTM (context, 0, rect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
//STEP 2.
drawCrystalRect(context, CGRectMake(0.0f, 0.0f, rect.size.width, rect.size.height), radius, components, componentCount);
//STEP 3.文字
//STEP 3.
CGImageRef image = CGBitmapContextCreateImage(context);
result = [UIImage imageWithCGImage:image];
CGImageRelease(image);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
//STEP 4.
return result;
}
UIImage *createImageInRectWithGradient(CGRect rect, CGFloat radius, const CGFloat *components, NSUInteger componentCount, CGFloat borderWidth) {
UIImage *result = nil;
//STEP 1.
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, rect.size.width, rect.size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Little);
CGContextTranslateCTM (context, 0, rect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
//STEP 2.
drawGradientInRectWithSingleColor(rect, radius, borderWidth, context, colorSpace, components, componentCount, GRADIENT_RECT_FROM_TOP_TO_BOTTOM);
//STEP 3.
CGImageRef image = CGBitmapContextCreateImage(context);
result = [UIImage imageWithCGImage:image];
CGImageRelease(image);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
//STEP 4.
return result;
}
//在一个矩形内部进行绘制渐变
void drawGradientInRect(CGRect rect, CGContextRef context, CGColorSpaceRef colorSpace, const CGFloat *components, NSUInteger componentCount, NSUInteger directFlag) {
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, NULL, componentCount / 4);
CGPoint startPoint = CGPointZero;
CGPoint endPoint = CGPointZero;
if (directFlag == GRADIENT_RECT_FROM_TOP_TO_BOTTOM) {
startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
} else if (directFlag == GRADIENT_RECT_FROM_BOTTOM_TO_TOP) {
endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
} else if (directFlag == GRADIENT_RECT_FROM_LEFT_TO_RIGHT) {
startPoint = CGPointMake(CGRectGetMinX(rect), CGRectGetMidY(rect));
endPoint = CGPointMake(CGRectGetMaxX(rect), CGRectGetMidY(rect));
} else if (directFlag == GRADIENT_RECT_FROM_RIGHT_TO_LEFT) {
endPoint = CGPointMake(CGRectGetMinX(rect), CGRectGetMidY(rect));
startPoint = CGPointMake(CGRectGetMaxX(rect), CGRectGetMidY(rect));
} else {
startPoint = CGPointMake(CGRectGetMinX(rect), CGRectGetMidY(rect));
endPoint = CGPointMake(CGRectGetMaxX(rect), CGRectGetMidY(rect));
}
CGContextDrawLinearGradient(context,
gradient,
startPoint,
endPoint,
0);
CGGradientRelease(gradient);
}
void drawTopGradientInRect(CGRect rect, CGContextRef context, CGColorSpaceRef colorSpace) {
CGFloat colorTop[] =
{
//239.0f / 255.0f, 239.0f / 255.0f, 239.0f / 255.0f, 0.35f,
239.0f / 255.0f, 239.0f / 255.0f, 239.0f / 255.0f, 0.40f,
//239.0f / 255.0f, 239.0f / 255.0f, 239.0f / 255.0f, 0.25f,
239.0f / 255.0f, 239.0f / 255.0f, 239.0f / 255.0f, 0.20f,
//239.0f / 255.0f, 239.0f / 255.0f, 239.0f / 255.0f, 0.15f,
239.0f / 255.0f, 239.0f / 255.0f, 239.0f / 255.0f, 0.10f,
239.0f / 255.0f, 239.0f / 255.0f, 239.0f / 255.0f, 0.05f,
239.0f / 255.0f, 239.0f / 255.0f, 239.0f / 255.0f, 0.0f,
};
drawGradientInRect(rect, context, colorSpace, colorTop, sizeof(colorTop) / sizeof(CGFloat), GRADIENT_RECT_FROM_TOP_TO_BOTTOM);
}
void drawBottomGradientInRect(CGRect rect, CGContextRef context, CGColorSpaceRef colorSpace) {
CGFloat colorBottom[] =
{
//5.0f / 255.0f, 5.0f / 255.0f, 5.0f / 255.0f, 0.05f,
//5.0f / 255.0f, 5.0f / 255.0f, 5.0f / 255.0f, 0.20f,
5.0f / 255.0f, 5.0f / 255.0f, 5.0f / 255.0f, 0.15f,
5.0f / 255.0f, 5.0f / 255.0f, 5.0f / 255.0f, 0.25f,
5.0f / 255.0f, 5.0f / 255.0f, 5.0f / 255.0f, 0.35f,
5.0f / 255.0f, 5.0f / 255.0f, 5.0f / 255.0f, 0.45f,
//5.0f / 255.0f, 5.0f / 255.0f, 5.0f / 255.0f, 0.0f,
};
drawGradientInRect(rect, context, colorSpace, colorBottom, sizeof(colorBottom) / sizeof(CGFloat), GRADIENT_RECT_FROM_TOP_TO_BOTTOM);
}
void drawGradientInRectWithSingleColor(CGRect rect, CGFloat radius, CGFloat borderWidth, CGContextRef context, CGColorSpaceRef colorSpace, const CGFloat *components, NSUInteger componentCount, NSUInteger directFlag) {
CGFloat borderWidth_Real = borderWidth;
if (borderWidth_Real >= 0.0f) {
borderWidth_Real = 1.0f;
}
CGFloat colors[4] = {0};
if (componentCount >= 4) {
colors[0] = components[0];
colors[1] = components[1];
colors[2] = components[2];
colors[3] = components[3];
} else if (componentCount == 2) {
colors[0] = components[0];
colors[1] = components[0];
colors[2] = components[0];
colors[3] = components[1];
}
CGRect rClient = rect;
CGFloat boundsSpace = 1.0f;
rClient.origin.x += (borderWidth_Real / 2.0f + boundsSpace);
rClient.origin.y += (borderWidth_Real / 2.0f + boundsSpace);
rClient.size.width -= (borderWidth_Real + boundsSpace * 2.0f);
rClient.size.height -= (borderWidth_Real + boundsSpace * 2.0f);
//STEP 1.
CGContextSaveGState(context);
CGContextSetRGBFillColor(context, colors[0], colors[1], colors[2], colors[3]);
CGContextSetRGBStrokeColor(context, colors[0], colors[1], colors[3], colors[3]);
buildPathForRect(context, rClient, radius, FS_DRAW_REGION_ROUND_RECT);
UIColor *shadowColor = [[UIColor alloc] initWithRed:colors[0] green:colors[1] blue:colors[2] alpha:colors[3]];
CGContextSetShadowWithColor(context, CGSizeMake(-1.0f, 1.0f), 2.0f, shadowColor.CGColor);
[shadowColor release];
CGContextSetLineWidth(context, 0.0f);
CGContextDrawPath(context, kCGPathFillStroke);
CGContextRestoreGState(context);
//STEP 2.
CGContextSaveGState(context);
CGFloat gradientColors[] =
{
1.0f, 1.0f, 1.0f, 0.75f,
1.0f, 1.0f, 1.0f, 0.55f,
1.0f, 1.0f, 1.0f, 0.25f,
1.0f, 1.0f, 1.0f, 0.0f,
};
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, gradientColors, NULL, sizeof(gradientColors)/ (4 * sizeof(CGFloat)));
buildPathForRect(context, rClient, radius, FS_DRAW_REGION_ROUND_RECT);
CGContextClip(context);
CGPoint startPoint = CGPointZero;
CGPoint endPoint = CGPointZero;
if (directFlag == GRADIENT_RECT_FROM_TOP_TO_BOTTOM) {
startPoint = CGPointMake(CGRectGetMidX(rClient), CGRectGetMinY(rClient));
endPoint = CGPointMake(CGRectGetMidX(rClient), CGRectGetMaxY(rClient));
} else if (directFlag == GRADIENT_RECT_FROM_BOTTOM_TO_TOP) {
endPoint = CGPointMake(CGRectGetMidX(rClient), CGRectGetMinY(rClient));
startPoint = CGPointMake(CGRectGetMidX(rClient), CGRectGetMaxY(rClient));
} else if (directFlag == GRADIENT_RECT_FROM_LEFT_TO_RIGHT) {
startPoint = CGPointMake(CGRectGetMinX(rClient), CGRectGetMidY(rClient));
endPoint = CGPointMake(CGRectGetMaxX(rClient), CGRectGetMidY(rClient));
} else if (directFlag == GRADIENT_RECT_FROM_RIGHT_TO_LEFT) {
endPoint = CGPointMake(CGRectGetMinX(rClient), CGRectGetMidY(rClient));
startPoint = CGPointMake(CGRectGetMaxX(rClient), CGRectGetMidY(rClient));
} else {
startPoint = CGPointMake(CGRectGetMinX(rClient), CGRectGetMidY(rClient));
endPoint = CGPointMake(CGRectGetMaxX(rClient), CGRectGetMidY(rClient));
}
CGContextDrawLinearGradient(context,
gradient,
startPoint,
endPoint,
0);
CGGradientRelease(gradient);
CGContextRestoreGState(context);
}
使用方法:
UIColor *btnBGColor = [[UIColor alloc] initWithRed:0.0f / 255.0f green:132.0f / 255.0f blue:189.0f / 255.0f alpha:1.0f];
UIImage *bgImage = createImageWithRect(CGRectMake(0.0f, 0.0f, SNSLOGIN_BUTTON_WIDTH, SNSLOGIN_BUTTON_HEIGHT), SNSLOGIN_BUTTON_RADIUS, CGColorGetComponents(btnBGColor.CGColor), CGColorGetNumberOfComponents(btnBGColor.CGColor));
[btnBGColor release];
_btnLogin = [[UIButton alloc] initWithFrame:CGRectZero];
[_btnLogin setTitle:@"登录" forState:UIControlStateNormal];
[_btnLogin setBackgroundImage:bgImage forState:UIControlStateNormal];
[_btnLogin.titleLabel setFont:[UIFont boldSystemFontOfSize:18.0f]];
[_btnLogin addTarget:self action:@selector(loginAction:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:_btnLogin];
示例图片: