简介
现在很多项目在完善信息或者注册信息的时候,或者支付这一方面,都希望用户手写签名,这样既可以保证是用户亲自签名的,保证该记录是用用户操作的,而不是别人操作的.所以手写签字这个还是比较重要的.下面就是通过QuartzCore来绘制签名.QuartzCore是iOS的核心动画框架.
绘制
- 1定义一个结构体
static CGPoint midpoint(CGPoint p0,CGPoint p1) {
return (CGPoint) {
(p0.x + p1.x) /2.0,
(p0.y + p1.y) /2.0
};
}
- 2添加手势
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
pan.maximumNumberOfTouches = pan.minimumNumberOfTouches =1;
[self addGestureRecognizer:pan];
- 3开始绘制
CGPoint currentPoint = [pan locationInView:self];
CGPoint midPoint = midpoint(previousPoint, currentPoint);
NSLog(@"获取到的触摸点的位置为--currentPoint:%@",NSStringFromCGPoint(currentPoint));
[self.currentPointArr addObject:[NSValue valueWithCGPoint:currentPoint]];
self.hasSignatureImg = YES;
CGFloat viewHeight = self.frame.size.height;
CGFloat currentY = currentPoint.y;
if (pan.state ==UIGestureRecognizerStateBegan) {
[path moveToPoint:currentPoint];
} else if (pan.state ==UIGestureRecognizerStateChanged) {
[path addQuadCurveToPoint:midPoint controlPoint:previousPoint];
}
if(0 <= currentY && currentY <= viewHeight)
{
if(max == 0&&min == 0)
{
max = currentPoint.x;
min = currentPoint.x;
}
else
{
if(max <= currentPoint.x)
{
max = currentPoint.x;
}
if(min>=currentPoint.x)
{
min = currentPoint.x;
}
}
}
previousPoint = currentPoint;
//记得调用,及时刷新视图
[self setNeedsDisplay];
- 4获取绘制视图,在进行一系列处理就好
if(UIGraphicsBeginImageContextWithOptions !=NULL)
{
UIGraphicsBeginImageContextWithOptions(self.bounds.size,NO, [UIScreen mainScreen].scale);
}else {
UIGraphicsBeginImageContext(self.bounds.size);
}
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image =UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//绘制成图
image = [self imageBlackToTransparent:image];
NSLog(@"width:%f,height:%f",image.size.width,image.size.height);
//截取图片
UIImage *img = [self cutImage:image];
//压缩图片
self.SignatureImg = [self scaleToSize:img];
- 5附上处理的方法
1.绘制成图
- (UIImage*) imageBlackToTransparent:(UIImage*) image
{
// 分配内存
const int imageWidth = image.size.width;
const int imageHeight = image.size.height;
size_t bytesPerRow = imageWidth * 4;
uint32_t* rgbImageBuf = (uint32_t*)malloc(bytesPerRow * imageHeight);
// 创建context
CGColorSpaceRef colorSpace =CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(rgbImageBuf, imageWidth, imageHeight, 8, bytesPerRow, colorSpace,
kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);
CGContextDrawImage(context, CGRectMake(0, 0, imageWidth, imageHeight), image.CGImage);
// 遍历像素
int pixelNum = imageWidth * imageHeight;
uint32_t* pCurPtr = rgbImageBuf;
for (int i =0; i < pixelNum; i++, pCurPtr++)
{
// if ((*pCurPtr & 0xFFFFFF00) == 0) //将黑色变成透明
if (*pCurPtr == 0xffffff)
{
uint8_t* ptr = (uint8_t*)pCurPtr;
ptr[0] =0;
}
//改成下面的代码,会将图片转成灰度
/*uint8_t* ptr = (uint8_t*)pCurPtr;
// gray = red * 0.11 + green * 0.59 + blue * 0.30
uint8_t gray = ptr[3] * 0.11 + ptr[2] * 0.59 + ptr[1] * 0.30;
ptr[3] = gray;
ptr[2] = gray;
ptr[1] = gray;*/
}
// 将内存转成image
CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, rgbImageBuf, bytesPerRow * imageHeight,/*ProviderReleaseData**/NULL);
CGImageRef imageRef = CGImageCreate(imageWidth, imageHeight, 8,32, bytesPerRow, colorSpace,
kCGImageAlphaLast | kCGBitmapByteOrder32Little, dataProvider,
NULL, true,kCGRenderingIntentDefault);
CGDataProviderRelease(dataProvider);
UIImage* resultUIImage = [UIImage imageWithCGImage:imageRef];
// 释放
CGImageRelease(imageRef);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
// free(rgbImageBuf) 创建dataProvider时已提供释放函数,这里不用free
return resultUIImage;
}
2.截图图片
CGRect rect ;
//签名事件没有发生
if(min == 0&&max == 0)
{
rect =CGRectMake(0,0, 0, 0);
}
else//签名发生
{
rect =CGRectMake(min-3,0, max-min+6,self.frame.size.height);
}
CGImageRef imageRef =CGImageCreateWithImageInRect([image CGImage], rect);
UIImage * img = [UIImage imageWithCGImage:imageRef];
//添加水印
UIImage *lastImage = [self addText:img text:self.showMessage];
CGImageRelease(imageRef);
[self setNeedsDisplay];
3.压缩
//压缩图片,最长边为128(根据不同的比例来压缩)
- (UIImage *)scaleToSize:(UIImage *)img {
CGRect rect ;
CGFloat imageWidth = img.size.width;
//判断图片宽度
if(imageWidth >= 128)
{
rect =CGRectMake(0,0, 128, self.frame.size.height);
}
else
{
rect =CGRectMake(0,0, img.size.width,self.frame.size.height);
}
CGSize size = rect.size;
UIGraphicsBeginImageContext(size);
[img drawInRect:rect];
UIImage* scaledImage =UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//此处注释是为了防止该签名图片被保存到本地
// UIImageWriteToSavedPhotosAlbum(scaledImage,nil, nil, nil);
[self setNeedsDisplay];
return scaledImage;
}
剩下的,都是一些细节问题,根据不同的项目进行不同的修改就好.
自己做的demo效果
image附上demo
个人小笔~,欢迎大家指导.
网友评论