IOS-手写签名的实现(实现了手势绘制字体,添加文字水印,图片剪

2017-08-15  本文已影响0人  HanZhiZzzzz

最近要实现一个手写签名功能,要求是,在一定区域绘制文字签名,签名完成后,添加新的水印,并且将图片仅保留签字区域剪切,并且宽度不能大于128,经多方努力,终于完成了,现在上代码,总结一下:
首先,新建单视图项目,然后新建一个继承view的类signatureView,绘制功能和图片的处理就是在该类实现的,该类代码如下:

.h文件

#import <UIKit/UIKit.h>

@protocol GetSignatureImageDele <NSObject>

-(void)getSignatureImg:(UIImage*)image;

@end

@interface signatureView : UIView
{
    CGFloat min;
    CGFloat max;
    CGRect origRect;
    CGFloat origionX;
    CGFloat totalWidth;
    BOOL  isSure;
}
//签名完成后的水印文字
@property (strong,nonatomic) NSString *showMessage;
@property(nonatomic,assign)id<GetSignatureImageDele> delegate;
- (void)clear;
- (void)sure;
@end

.m文件

#import "signatureView.h"
#import <QuartzCore/QuartzCore.h>
#define StrWidth 150
#define StrHeight 20

staticCGPoint midpoint(CGPoint p0,CGPoint p1) {
   return (CGPoint) {
        (p0.x + p1.x) /2.0,
        (p0.y + p1.y) /2.0
    };
}

@interface signatureView () {
    UIBezierPath *path;
   CGPoint previousPoint;
}
@end

@implementation signatureView
- (void)commonInit {
    
    path = [UIBezierPathbezierPath];
    [pathsetLineWidth:2];
    
   max = 0;
   min = 0;
    // Capture touches
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizeralloc] initWithTarget:selfaction:@selector(pan:)];
    pan.maximumNumberOfTouches = pan.minimumNumberOfTouches =1;
    [selfaddGestureRecognizer:pan];
    
}

-(void)clearPan
{
    path = [UIBezierPathbezierPath];
    [pathsetLineWidth:3];
    
    [selfsetNeedsDisplay];
}


- (id)initWithCoder:(NSCoder *)aDecoder
{
   if (self = [superinitWithCoder:aDecoder]) [selfcommonInit];
    return self;
}
- (id)initWithFrame:(CGRect)frame
{
   if (self = [superinitWithFrame:frame]) [selfcommonInit];
    return self;
}


void ProviderReleaseData (void *info,const void *data,size_t size)
{
   free((void*)data);
}


- (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);
   CGImageRef imageRef = CGImageCreate(imageWidth, imageHeight, 8,32, bytesPerRow, colorSpace,
                                       kCGImageAlphaLast | kCGBitmapByteOrder32Little, dataProvider,
                                       NULL, true,kCGRenderingIntentDefault);
    CGDataProviderRelease(dataProvider);
    
   UIImage* resultUIImage = [UIImageimageWithCGImage:imageRef];
    
    // 释放
   CGImageRelease(imageRef);
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
    // free(rgbImageBuf) 创建dataProvider时已提供释放函数,这里不用free
    
   return resultUIImage;
}


-(void)handelSingleTap:(UITapGestureRecognizer*)tap
{
    return [selfimageRepresentation];
}
-(void) imageRepresentation {
   
    if(UIGraphicsBeginImageContextWithOptions !=NULL)
    {
        UIGraphicsBeginImageContextWithOptions(self.bounds.size,NO, [UIScreenmainScreen].scale);
    }else {
        UIGraphicsBeginImageContext(self.bounds.size);
        
    }
    
    [self.layerrenderInContext:UIGraphicsGetCurrentContext()];
    
    UIImage *image =UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
    image = [selfimageBlackToTransparent:image];
    
   NSLog(@"width:%f,height:%f",image.size.width,image.size.height);
    
   UIImage *img = [selfcutImage:image];
    
    [self.delegategetSignatureImg:[selfscaleToSize:img]];
}

//压缩图片,最长边为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);
    [imgdrawInRect:rect];
    UIImage* scaledImage =UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    UIImageWriteToSavedPhotosAlbum(scaledImage,nil, nil, nil);
    
    [selfsetNeedsDisplay];
   return scaledImage;
}

//只截取签名部分图片
- (UIImage *)cutImage:(UIImage *)image
{
   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 = [UIImageimageWithCGImage:imageRef];
    
   UIImage *lastImage = [selfaddText:img text:self.showMessage];
    
    [selfsetNeedsDisplay];
   return lastImage;
}

//签名完成,给签名照添加新的水印
- (UIImage *) addText:(UIImage *)img text:(NSString *)mark {
   int w = img.size.width;
   int h = img.size.height;
    
    //根据截取图片大小改变文字大小
   CGFloat size = 20;
   UIFont *textFont = [UIFontsystemFontOfSize:size];
   CGSize sizeOfTxt = [mark sizeWithFont:textFont constrainedToSize:CGSizeMake(128,30)];
    
   if(w<sizeOfTxt.width)
    {
        
       while (sizeOfTxt.width>w) {
            size --;
            textFont = [UIFontsystemFontOfSize:size];
            
            sizeOfTxt = [marksizeWithFont:textFont constrainedToSize:CGSizeMake(128,30)];
        }
        
    }
   else
    {
        
        size =45;
        textFont = [UIFontsystemFontOfSize:size];
        sizeOfTxt = [marksizeWithFont:textFont constrainedToSize:CGSizeMake(self.frame.size.width,30)];
       while (sizeOfTxt.width>w) {
            size ++;
            textFont = [UIFontsystemFontOfSize:size];
            sizeOfTxt = [marksizeWithFont:textFont constrainedToSize:CGSizeMake(self.frame.size.width,30)];
        }
        
    }
    UIGraphicsBeginImageContext(img.size);
    [[UIColorredColor] set];
    [imgdrawInRect:CGRectMake(0,0, w, h)];
    [markdrawInRect:CGRectMake((w-sizeOfTxt.width)/2,(h-sizeOfTxt.height)/2, sizeOfTxt.width, sizeOfTxt.height)withFont:textFont];
    UIImage *aimg =UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
   return aimg;
}
- (void)pan:(UIPanGestureRecognizer *)pan {
   CGPoint currentPoint = [pan locationInView:self];
   CGPoint midPoint = midpoint(previousPoint, currentPoint);
     NSLog(@"获取到的触摸点的位置为--currentPoint:%@",NSStringFromCGPoint(currentPoint));
    
   CGFloat viewHeight = self.frame.size.height;
   CGFloat currentY = currentPoint.y;
    if (pan.state ==UIGestureRecognizerStateBegan) {
        [pathmoveToPoint:currentPoint];
                
    } elseif (pan.state ==UIGestureRecognizerStateChanged) {
        [pathaddQuadCurveToPoint: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;
    
    [selfsetNeedsDisplay];
}

- (void)drawRect:(CGRect)rect
{
    self.backgroundColor = [UIColorwhiteColor];
    [[UIColorblackColor] setStroke];
    [pathstroke];
    
    self.layer.cornerRadius =5.0;
    self.clipsToBounds =YES;
    self.layer.borderWidth =0.5;
   self.layer.borderColor = [[UIColorgrayColor] CGColor];
    
    CGContextRef context =UIGraphicsGetCurrentContext();
    
   if(!isSure)
    {
        
       NSString *str = @"请绘制签名";
       CGContextSetRGBFillColor (context,  108/255, 108/255,108/255, 0.3);//设置填充颜色
       CGRect rect1 = CGRectMake((rect.size.width -StrWidth)/2, (rect.size.height -StrHeight)/2-5,StrWidth, StrHeight);
       origionX = rect1.origin.x;
       totalWidth = rect1.origin.x+StrWidth;
        
       UIFont  *font = [UIFontsystemFontOfSize:25];//设置字体
        [strdrawInRect:rect1 withFont:font];
    }
   else
        
    {
       isSure = NO;
    }
    
}

- (void)clear
{
   max = 0;
   min = 0;
    path = [UIBezierPathbezierPath];
    [pathsetLineWidth:2];
    
    [selfsetNeedsDisplay];
}
- (void)sure
{
    //没有签名发生时
   if(min == 0&&max == 0)
    {
       min = 0;
       max = 0;
    }
   isSure = YES;
    [selfsetNeedsDisplay];
    return [selfimageRepresentation];
}


@end

其中有两个方法过期了

替换方法:

1:

   NSDictionary *attribute = @{NSFontAttributeName:textFont};
    CGSize sizeOfTxt = [str boundingRectWithSize:size options: NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:attribute context:nil].size;

2:

    [mark drawInRect:CGRectMake((w-sizeOfTxt.width)/2,(h-sizeOfTxt.height)/2, sizeOfTxt.width, sizeOfTxt.height) withAttributes:@{NSFontAttributeName:textFont}];

在根视图viewController里面代码如下:

.h文件

#import <UIKit/UIKit.h>
#import "signatureView.h"
@interface ViewController :UIViewController<GetSignatureImageDele>
{
   UIImage *saveImage;
   UIView *saveView;
}
@property (strong,nonatomic) signatureView *signatureView;
@end

.m文件

@implementation ViewController

- (void)viewDidLoad {
    [superviewDidLoad];
    self.view.backgroundColor = [UIColorgrayColor];
    self.signatureView = [[signatureViewalloc] initWithFrame:CGRectMake(10,70, 300, 100)];
    self.signatureView.backgroundColor = [UIColorwhiteColor];
    self.signatureView.delegate =self;
    self.signatureView.showMessage =@"完成";
    [self.viewaddSubview:self.signatureView];
    
    UIButton *button = [UIButtonbuttonWithType:UIButtonTypeCustom];
    [button setTitle:@"重签"forState:UIControlStateNormal];
    [button setTitleColor:[UIColorcolorWithHue:72saturation:106brightness:123alpha:0.7]forState:UIControlStateNormal];
    [buttonsetFrame:CGRectMake(20,self.signatureView.frame.origin.y+120,130, 40)];
    button.layer.cornerRadius =5.0;
    button.clipsToBounds =YES;
    button.layer.borderWidth =1.0;
    button.titleLabel.font = [UIFontsystemFontOfSize:17];
    button.layer.borderColor = [[UIColorblackColor]CGColor];
    [button addTarget:selfaction:@selector(clear:)forControlEvents:UIControlEventTouchUpInside];
    [self.viewaddSubview:button];
    
    UIButton *button2 = [UIButtonbuttonWithType:UIButtonTypeCustom];
    [button2 setTitle:@"确认"forState:UIControlStateNormal];
    [button2 setTitleColor:[UIColorwhiteColor] forState:UIControlStateNormal];
    button2.titleLabel.font = [UIFontsystemFontOfSize:17];
    button2.backgroundColor = [UIColorblueColor];
    [button2setFrame:CGRectMake(170,self.signatureView.frame.origin.y+120,130, 40)];
    button2.layer.cornerRadius =5.0;
    button2.clipsToBounds =YES;
    [button2 addTarget:selfaction:@selector(add:)forControlEvents:UIControlEventTouchUpInside];
    [self.viewaddSubview:button2];

    saveView = [[UIViewalloc] initWithFrame:CGRectMake(10, button2.frame
                                                        .origin.y+60,300, 140)];
    saveView.backgroundColor = [UIColorlightGrayColor];
    [self.viewaddSubview:saveView];
    // Do any additional setup after loading the view, typically from a nib.
}
- (void)add:(UIButton *)sender
{
    [self.signatureViewsure];
    
}

- (void)clear:(UIButton *)sender
{
   NSLog(@"重签");
    [self.signatureViewclear];
   for(UIView *viewin saveView.subviews)
    {
        [view removeFromSuperview];
    }
}

-(void)getSignatureImg:(UIImage*)image
{
   if(image)
    {
        NSLog(@"haveImage");
        
       UIImageView *image1 = [[UIImageViewalloc] initWithImage:image];
        image1.frame =CGRectMake((saveView.frame.size.width-image.size.width)/2, (saveView.frame.size.height-image.size.height)/2, image.size.width, image.size.height) ;
        [saveViewaddSubview:image1];

       saveImage = image;
        [selfsaveImage:saveImage];
        //[self makeUpLoad];
        
    }
   else
    {
       NSLog(@"NoImage");
        
    }
    
}

//图片保存到本地
- (void)saveImage:(UIImage *)image
{
    //设置图片名
    NSDateFormatter *dateFormatter = [[NSDateFormatteralloc] init];
    [dateFormattersetDateFormat:@"yyyyMMdd"];
   NSString *currentDateStr = [dateFormatter stringFromDate:[NSDate date]];
   NSString *dateStr = [NSStringstringWithFormat:@"%@.png",currentDateStr];
    
   
    NSString *path = [NSTemporaryDirectory()stringByAppendingFormat:@"%@",dateStr];
    BOOL existed = [[NSFileManagerdefaultManager] fileExistsAtPath:pathisDirectory:nil];
   if ( existed  )
    {
        [[NSFileManagerdefaultManager] removeItemAtPath:patherror:nil];
    }
   //NSData *imgData = UIImageJPEGRepresentation(image, 1);
    NSData *imgData = UIImagePNGRepresentation(image);
    [imgDatawriteToFile:path atomically:YES];
    
}

- (void)didReceiveMemoryWarning {
    [superdidReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

效果图:


DF8DD5F1-DD2C-4794-9B40-8694AC2B48F0.png EAE337AC-582B-4F42-B670-A43ACCB7AFDE.png

摘自:http://blog.csdn.net/u012890196/article/details/42269045

上一篇下一篇

猜你喜欢

热点阅读