iOS 网页内长按图片识别二维码功能封装

.h

#import <WebKit/WebKit.h>

NS_ASSUME_NONNULL_BEGIN
typedef  void((^LongBlock)(BOOL haveErWeiMa,NSString *qrCodeString,UIImage *image));
@interface WebView : WKWebView

/// 加载地址
@property(nonatomic,strong)NSString *url;

/// 回调
@property(nonatomic,copy)LongBlock longBlock;


/// 图片保存
/// @param image image description
-(void)saveImage:(UIImage *)image;


/// 不可识别二维码吗? 默认NO
@property(nonatomic,assign)BOOL canNotQRcode;

@end

NS_ASSUME_NONNULL_END

.m

#import "WebView.h"
#import <WebKit/WebKit.h>

@interface WebView ()
<
WKNavigationDelegate,
WKUIDelegate,
UIGestureRecognizerDelegate
>
@property(nonatomic,strong)UIImage *saveImage;

@property(nonatomic,strong)UILongPressGestureRecognizer *longPress;

@end

@implementation WebView

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/
- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        self.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
        self.contentMode = UIViewContentModeRedraw;
        self.opaque = YES;
        self.UIDelegate =self;
        self.navigationDelegate = self;
        self.allowsBackForwardNavigationGestures = YES;
        self.canNotQRcode = NO;
    }
    return self;
}

- (void)setCanNotQRcode:(BOOL)canNotQRcode
{
    _canNotQRcode = canNotQRcode;
    if (_canNotQRcode == YES)
    {
        [self removeGestureRecognizer:self.longPress];
    }
    else
    {
        [self addGestureRecognizer:self.longPress];
    }
}

-(void)setUrl:(NSString *)url
{
    _url = url;
    [self loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:_url]]];
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

#pragma mark ————————— 禁止弹出菜单JS代码 —————————————
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
    // 禁止弹出菜单JS代码
    NSString *jsString = @"document.documentElement.style.webkitTouchCallout = 'none';";
    
    NSString *jsString2 = @"document.documentElement.style.webkitUserSelect = 'none';";
    
    if (_canNotQRcode == YES)
    {
        jsString = @"document.documentElement.style.webkitTouchCallout = 'default';";
        jsString2 = @"document.documentElement.style.webkitUserSelect = 'default';";
    }

//    document.documentElement.style.webkitTouchCallout ='none'; //禁止弹出菜单 default
//    document.documentElement.style.webkitUserSelect = 'none'; //禁止选中 default
    
    [self setJsCodeFromJsString:jsString block:nil];
    
    [self setJsCodeFromJsString:jsString2 block:nil];
}

#pragma mark ————————— 系统调用js方法封装 —————————————
-(void)setJsCodeFromJsString:(NSString *)jsString block:(void (^ _Nullable)(id _Nullable ids, NSError * _Nullable error))block
{
    [self evaluateJavaScript:jsString completionHandler:block];
}

#pragma mark ————————— 长按 —————————————
- (void)handleLongPress:(UILongPressGestureRecognizer *)sender{
    if (sender.state != UIGestureRecognizerStateBegan)
    {
        return;
    }
    CGPoint touchPoint = [sender locationInView:self];
    // 获取长按位置对应的图片url的JS代码
    NSString *imgJS = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).src", touchPoint.x, touchPoint.y];
    __weak typeof(self) weakSelf = self;
    [self setJsCodeFromJsString:imgJS block:^(id _Nullable ids, NSError * _Nullable error) {
        if (ids) {
            NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:ids]];
            UIImage *image = [UIImage imageWithData:data];
            if (!image) {
                NSLog(@"读取图片失败");
                return;
            }
            _saveImage = image;
            [weakSelf isHaveQRcodeFromImage:image block:^(BOOL ishave, NSString *qrCodeString) {
                
                if (weakSelf.longBlock)
                {
                    weakSelf.longBlock(ishave,qrCodeString,image);
                }
            }];
        }
    }];
}

#pragma mark ————————— 判断有无二维码并识别二维码 —————————————
- (void)isHaveQRcodeFromImage:(UIImage *)img block:(void(^)(BOOL ishave,NSString *qrCodeString))block
{
    UIImage *image = [self imageFromInsetEdge:UIEdgeInsetsMake(-20, -20, -20, -20) color:[UIColor lightGrayColor] iamge:img];
    CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{}];
    NSArray *features = [detector featuresInImage:[CIImage imageWithCGImage:image.CGImage]];
    BOOL isHave ;
    NSString *qrCodeString = nil;
    if (features.count >= 1)
    {
        CIQRCodeFeature *feature = features.firstObject;
        qrCodeString = [feature.messageString copy];
        NSLog(@"二维码信息:%@", qrCodeString);
        isHave = YES;
    }
    else
    {
        NSLog(@"无可识别的二维码");
        isHave = NO;
    }
    block(isHave,qrCodeString);
}

- (UIImage *)imageFromInsetEdge:(UIEdgeInsets)insets color:(UIColor *)color iamge:(UIImage *)iamge
{
    CGSize size = iamge.size;
    size.width -= insets.left + insets.right;
    size.height -= insets.top + insets.bottom;
    if (size.width <= 0 || size.height <= 0) {
        return nil;
    }
    CGRect rect = CGRectMake(-insets.left, -insets.top, iamge.size.width, iamge.size.height);
    UIGraphicsBeginImageContextWithOptions(size, NO, iamge.scale);
    CGContextRef context = UIGraphicsGetCurrentContext();
    if (color) {
        CGContextSetFillColorWithColor(context, color.CGColor);
        CGMutablePathRef path = CGPathCreateMutable();
        CGPathAddRect(path, NULL, CGRectMake(0, 0, size.width, size.height));
        CGPathAddRect(path, NULL, rect);
        CGContextAddPath(context, path);
        CGContextEOFillPath(context);
        CGPathRelease(path);
    }
    [iamge drawInRect:rect];
    UIImage *insetEdgedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return insetEdgedImage;
}
-(UILongPressGestureRecognizer *)longPress{
    if (!_longPress)
    {
        UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
        longPress.minimumPressDuration = 0.2;
        longPress.delegate = self;
        _longPress = longPress;
    }
    return _longPress;
}
#pragma mark ————————— 相片存相册 —————————————
-(void)saveImage:(UIImage *)image
{
    if (image)
    {
        UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
    }
    else
    {
        UIImageWriteToSavedPhotosAlbum(_saveImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
    }
}

#pragma mark ————————— 相片存相册结果代理 —————————————
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{
    NSString *message;
    if (error)
    {
        message = @"图片保存失败";
    }
    else
    {
        message = @"图片保存成功";
    }
    NSLog(@"%@", message);
}

@end

调用

#import "ViewController.h"
#import "WebView.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSString *url = @"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1607424126182&di=60bb487b369cfec3c19a14934816c628&imgtype=0&src=http%3A%2F%2Fbpic.588ku.com%2Felement_pic%2F20%2F06%2F30%2F6a360d84e25b7d78512f00511416a169.jpg%2521%2Ffw%2F253%2Fquality%2F90%2Funsharp%2Ftrue%2Fcompress%2Ftrue";
    
    WebView *view = [[WebView alloc]initWithFrame:self.view.bounds];
    view.url = url;
    
    view.longBlock = ^(BOOL haveErWeiMa, NSString * _Nonnull qrCodeString, UIImage * _Nonnull image) {
        if (haveErWeiMa)
        {
//            view.url = qrCodeString;
//
//            view.canNotQRcode = YES;
            
            [self alertText:qrCodeString];
        }
    };
    [self.view addSubview:view];
}

#pragma mark ————————— 弹框 —————————————
-(void)alertText:(NSString *)text
{
    UIAlertController *alertC = [UIAlertController alertControllerWithTitle:@"识别图中二维码" message:nil preferredStyle:UIAlertControllerStyleAlert];

    [alertC addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        NSLog(@"取消");
        
    }]];

//    __weak typeof (self)weakSelf = self;
    [alertC addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        
        
        NSURL *url = [NSURL URLWithString:text];
        // Safari打开
        if ([[UIApplication sharedApplication] canOpenURL:url])
        {
            [[UIApplication sharedApplication] openURL:url];
        }
        
    }]];

    [self presentViewController:alertC animated:YES completion:nil];
}

@end

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在iOS开发中获取图片中二维码的定位,可以使用CoreImage框架。具体步骤如下: 1. 使用CIImage加载图片: ``` CIImage *image = [CIImage imageWithCGImage:image.CGImage]; ``` 2. 创建CIDetector并设置识别类型: ``` CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{CIDetectorAccuracy:CIDetectorAccuracyHigh}]; ``` 3. 识别二维码: ``` NSArray *features = [detector featuresInImage:image]; ``` 4. 遍历识别结果,获取二维码定位: ``` for (CIQRCodeFeature *feature in features) { NSArray *corners = feature.corners; // 获取定位四个角的坐标 // 在图像上绘制定位 UIGraphicsBeginImageContext(imageSize); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetStrokeColorWithColor(context, [UIColor greenColor].CGColor); CGContextSetLineWidth(context, 2.0); CGContextMoveToPoint(context, corners[0].x, corners[0].y); CGContextAddLineToPoint(context, corners[1].x, corners[1].y); CGContextAddLineToPoint(context, corners[2].x, corners[2].y); CGContextAddLineToPoint(context, corners[3].x, corners[3].y); CGContextAddLineToPoint(context, corners[0].x, corners[0].y); CGContextStrokePath(context); UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); } ``` 这样就可以在原图上绘制出二维码的定位了。需要注意的是,CIDetector只能识别二维码,如果要识别其他类型的码,需要设置不同的detector类型。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值