天天看点

IOS:手写签名的实现(实现了手势绘制字体,添加文字水印,图片剪切、图片压缩)

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

        }

        //改成下面的代码,会将图片转成灰度

    }

    // 将内存转成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

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

 .h文件 

#import <UIKit/UIKit.h>

#import "signatureView.h"

@interface ViewController :UIViewController<GetSignatureImageDele>

{

   UIImage *saveImage;

   UIView *saveView;

}

@property (strong,nonatomic) signatureView *signatureView;

@end

.h文件 

@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);

    [imgDatawriteToFile:path atomically:YES];

}

- (void)didReceiveMemoryWarning {

    [superdidReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

效果图:

IOS:手写签名的实现(实现了手势绘制字体,添加文字水印,图片剪切、图片压缩)
IOS:手写签名的实现(实现了手势绘制字体,添加文字水印,图片剪切、图片压缩)