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

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

作者: HanZhiZzzzz | 来源:发表于2017-08-15 18:45 被阅读0次

    最近要实现一个手写签名功能,要求是,在一定区域绘制文字签名,签名完成后,添加新的水印,并且将图片仅保留签字区域剪切,并且宽度不能大于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

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/evmvrxtx.html