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;

        }

        

        //改成下面的代碼,會將圖片轉成灰度

        /*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


在根視圖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.

}



效果圖:







發佈了111 篇原創文章 · 獲贊 9 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章