首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CGContextBeginPath:无效上下文0x0

CGContextBeginPath:无效上下文0x0
EN

Stack Overflow用户
提问于 2017-05-05 13:33:28
回答 2查看 99关注 0票数 0

图片我正在使用离子型/科尔多瓦地图插件开发一个地图应用程序,我想改变标记,所以我在ios平台上改变插件。我正在传递标记图标中的自定义属性,并绘制一个矩形以显示标记上的标题。从本地加载图像时,从circularScaleAndCropImage方法调用setIcon方法。

我得到了这个上下文错误,我不知道如何解决这个问题。

代码语言:javascript
复制
    `-(void)setIcon_:(GMSMarker *)marker iconProperty:(NSDictionary *)iconProperty
   pluginResult:(CDVPluginResult *)pluginResult
     callbackId:(NSString*)callbackId {

    if (self.mapCtrl.debuggable) {
        NSLog(@"---- setIcon_");
    }
    NSString *iconPath = nil;
    CGFloat width = 0;
    CGFloat height = 0;
    CGFloat anchorX = 0;
    CGFloat anchorY = 0;

    NSString *iconType = nil;
    NSString *borderColor = nil;
    NSString *ImageMarkerString = @"ImageMarker";
    NSString *markerLabel = nil;
    NSString *markerHeading = nil;
    // `url` property
    iconPath = [iconProperty valueForKey:@"url"];
    iconType = [iconProperty valueForKey:@"iconType"];
    //    NSLog(@"iconType = %@", iconType);
    borderColor = [iconProperty valueForKey:@"borderColor"];
    if(!borderColor){
        borderColor = @"#006600";
    }

    markerLabel =[iconProperty valueForKey:@"markerLabel"];
    if(!markerLabel){
        markerLabel= @"no_Label";
    }
    markerHeading =[iconProperty valueForKey:@"markerHeading"];
    if(!markerHeading){
        markerHeading = @"no_Heading";
    }

    // `size` property
    if ([iconProperty valueForKey:@"size"]) {
        NSDictionary *size = [iconProperty valueForKey:@"size"];
        width = [[size objectForKey:@"width"] floatValue];
        height = [[size objectForKey:@"height"] floatValue];
    }

    // `animation` property
    NSString *animationValue = nil;
    if ([iconProperty valueForKey:@"animation"]) {
        animationValue = [iconProperty valueForKey:@"animation"];
    }
    __block NSString *animation = animationValue;

    if (iconPath) {

        NSRange range = [iconPath rangeOfString:@"http"];
        if (range.location != 0) {
            /**
             * Load icon from file or Base64 encoded strings
             */
            Boolean isTextMode = true;

            UIImage *image;
            if ([iconPath rangeOfString:@"data:image/"].location != NSNotFound &&
                [iconPath rangeOfString:@";base64,"].location != NSNotFound) {

                /**
                 * Base64 icon
                 */
                isTextMode = false;
                NSArray *tmp = [iconPath componentsSeparatedByString:@","];

                NSData *decodedData;
#if !defined(__IPHONE_8_0)
                if ([PluginUtil isIOS7_OR_OVER]) {
                    decodedData = [NSData dataFromBase64String:tmp[1]];
                } else {
#if !defined(__IPHONE_7_0)
                    decodedData = [[NSData alloc] initWithBase64Encoding:(NSString *)tmp[1]];
#endif
                }
#else
                decodedData = [NSData dataFromBase64String:tmp[1]];
#endif
                image = [[UIImage alloc] initWithData:decodedData];
                if (width && height) {
                    image = [image resize:width height:height];
                }
                if([iconType isEqualToString:ImageMarkerString ]){
                    NSLog(@"ICON Marker Type Condition True 1");
                    CGRect newRect = CGRectMake(0, 0, width, height);
                    image = [self circularScaleAndCropImage:image frame:newRect color:borderColor label : markerLabel heading :markerHeading];
                }

                // The `anchor` property for the icon
                if ([iconProperty valueForKey:@"anchor"]) {
                    NSArray *points = [iconProperty valueForKey:@"anchor"];
                    anchorX = [[points objectAtIndex:0] floatValue] / image.size.width;
                    anchorY = [[points objectAtIndex:1] floatValue] / image.size.height;
                    marker.groundAnchor = CGPointMake(anchorX, anchorY);
                }

            } else {
                /**
                 * Load the icon from local path
                 */

                range = [iconPath rangeOfString:@"cdvfile://"];
                if (range.location != NSNotFound) {

                    iconPath = [PluginUtil getAbsolutePathFromCDVFilePath:self.webView cdvFilePath:iconPath];

                    if (iconPath == nil) {
                        if (self.mapCtrl.debuggable) {
                            NSLog(@"(debug)Can not convert '%@' to device full path.", iconPath);
                        }
                        [self.commandDelegate sendPluginResult:pluginResult callbackId:callbackId];
                        return;
                    }
                }


                range = [iconPath rangeOfString:@"://"];
                if (range.location == NSNotFound) {
                    range = [iconPath rangeOfString:@"www/"];
                    if (range.location == NSNotFound) {
                        iconPath = [NSString stringWithFormat:@"www/%@", iconPath];
                    }

                    range = [iconPath rangeOfString:@"/"];
                    if (range.location != 0) {
                      // Get the absolute path of the www folder.
                      // https://github.com/apache/cordova-plugin-file/blob/1e2593f42455aa78d7fff7400a834beb37a0683c/src/ios/CDVFile.m#L506
                      NSString *applicationDirectory = [[NSURL fileURLWithPath:[[NSBundle mainBundle] resourcePath]] absoluteString];
                      iconPath = [NSString stringWithFormat:@"%@%@", applicationDirectory, iconPath];
                    } else {
                      iconPath = [NSString stringWithFormat:@"file://%@", iconPath];
                    }
                }

                range = [iconPath rangeOfString:@"file://"];
                if (range.location != NSNotFound) {

                    #ifdef __CORDOVA_4_0_0
                        NSURL *fileURL = [NSURL URLWithString:iconPath];
                        NSURL *resolvedFileURL = [fileURL URLByResolvingSymlinksInPath];
                        iconPath = [resolvedFileURL path];
                    #else
                        iconPath = [iconPath stringByReplacingOccurrencesOfString:@"file://" withString:@""];
                    #endif

                    NSFileManager *fileManager = [NSFileManager defaultManager];
                    if (![fileManager fileExistsAtPath:iconPath]) {
                        if (self.mapCtrl.debuggable) {
                            NSLog(@"(debug)There is no file at '%@'.", iconPath);
                        }
                        [self.commandDelegate sendPluginResult:pluginResult callbackId:callbackId];
                        return;
                    }
                }

                image = [UIImage imageNamed:iconPath];

                if (width && height) {
                    image = [image resize:width height:height];
                }
            }
            if([iconType isEqualToString:ImageMarkerString ]){
                NSLog(@"ICON Marker Type Condition True 2");
                CGRect newRect = CGRectMake(0, 0, width, height);
                dispatch_async(dispatch_get_main_queue(), ^{[self circularScaleAndCropImage:image frame:newRect color:borderColor label : markerLabel heading :markerHeading];});

            }

            marker.icon = image;
            // The `anchor` property for the icon
            if ([iconProperty valueForKey:@"anchor"]) {
                NSArray *points = [iconProperty valueForKey:@"anchor"];
                anchorX = [[points objectAtIndex:0] floatValue] / image.size.width;
                anchorY = [[points objectAtIndex:1] floatValue] / image.size.height;
                marker.groundAnchor = CGPointMake(anchorX, anchorY);
            }

            // The `infoWindowAnchor` property
            if ([iconProperty valueForKey:@"infoWindowAnchor"]) {
                NSArray *points = [iconProperty valueForKey:@"infoWindowAnchor"];
                anchorX = [[points objectAtIndex:0] floatValue] / image.size.width;
                anchorY = [[points objectAtIndex:1] floatValue] / image.size.height;
                marker.infoWindowAnchor = CGPointMake(anchorX, anchorY);
            }


            // The `visible` property
            if (iconProperty[@"visible"]) {
                marker.map = self.mapCtrl.map;
            }

            if (animation) {
                // Do animation, then send the result
                [self setMarkerAnimation_:animation marker:marker pluginResult:pluginResult callbackId:callbackId];
            } else {
                // Send the result
                [self.commandDelegate sendPluginResult:pluginResult callbackId:callbackId];
            }
        } else {
            if (self.mapCtrl.debuggable) {
                NSLog(@"---- Load the icon from the internet");
            }
            /***
             * Load the icon from the internet
             */

            /*
             // download the image asynchronously
             R9HTTPRequest *request = [[R9HTTPRequest alloc] initWithURL:url];
             [request setHTTPMethod:@"GET"];
             [request setTimeoutInterval:5];
             [request setFailedHandler:^(NSError *error){}];
             */


            dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
            dispatch_async(queue, ^{

                NSURL *url = [NSURL URLWithString:iconPath];

                [self downloadImageWithURL:url completionBlock:^(BOOL succeeded, UIImage *image) {

                    if (!succeeded) {

                        // The `visible` property
                        if ([[iconProperty valueForKey:@"visible"] boolValue]) {
                            marker.map = self.mapCtrl.map;
                        }

                        [self.commandDelegate sendPluginResult:pluginResult callbackId:callbackId];
                        return;
                    }

                    if (width && height) {
                        image = [image resize:width height:height];
                    }

                    if([iconType isEqualToString:ImageMarkerString ]){
                        NSLog(@"ICON Marker Type Condition True 3");
                        CGRect newRect = CGRectMake(0, 0, width, height);
                        image = [self circularScaleAndCropImage:image frame:newRect color:borderColor label : markerLabel heading :markerHeading];
                    }
                    dispatch_async(dispatch_get_main_queue(), ^{
                        marker.icon = image;

                        // The `anchor` property for the icon
                        if ([iconProperty valueForKey:@"anchor"]) {
                            NSArray *points = [iconProperty valueForKey:@"anchor"];
                            CGFloat anchorX = [[points objectAtIndex:0] floatValue] / image.size.width;
                            CGFloat anchorY = [[points objectAtIndex:1] floatValue] / image.size.height;
                            marker.groundAnchor = CGPointMake(anchorX, anchorY);
                        }


                        // The `infoWindowAnchor` property
                        if ([iconProperty valueForKey:@"infoWindowAnchor"]) {
                            NSArray *points = [iconProperty valueForKey:@"infoWindowAnchor"];
                            CGFloat anchorX = [[points objectAtIndex:0] floatValue] / image.size.width;
                            CGFloat anchorY = [[points objectAtIndex:1] floatValue] / image.size.height;
                            marker.infoWindowAnchor = CGPointMake(anchorX, anchorY);
                        }

                        // The `visible` property
                        if ([[iconProperty valueForKey:@"visible"] boolValue]) {
                            marker.map = self.mapCtrl.map;
                        }


                        if (animation) {
                            // Do animation, then send the result
                            if (self.mapCtrl.debuggable) {
                                NSLog(@"---- do animation animation = %@", animation);
                            }
                            [self setMarkerAnimation_:animation marker:marker pluginResult:pluginResult callbackId:callbackId];
                        } else {
                            // Send the result
                            if (self.mapCtrl.debuggable) {
                                NSLog(@"---- no marker animation");
                            }
                            [self.commandDelegate sendPluginResult:pluginResult callbackId:callbackId];
                        }

                    });


                }];

            });


        }
    } else if ([iconProperty valueForKey:@"iconColor"]) {
        UIColor *iconColor = [iconProperty valueForKey:@"iconColor"];
        marker.icon = [GMSMarker markerImageWithColor:iconColor];

        // The `visible` property
        if ([[iconProperty valueForKey:@"visible"] boolValue]) {
            marker.map = self.mapCtrl.map;
        }

        if (animation) {
            // Do animation, then send the result
            [self setMarkerAnimation_:animation marker:marker pluginResult:pluginResult callbackId:callbackId];
        } else {
            // Send the result
            [self.commandDelegate sendPluginResult:pluginResult callbackId:callbackId];
        }

    }

}
`
- (UIImage*)circularScaleAndCropImage:(UIImage*)image frame:(CGRect)frame color:(NSString *)color label :(NSString *)label heading :(NSString *)heading{
    // This function returns a newImage, based on image, that has been:
    // - scaled to fit in (CGRect) rect
    // - and cropped within a circle of radius: rectWidth/2

    NSLog(@"function called");
    NSString *htmlTemplate =
    @"<html>\n"
    "<head>\n"
    "<style type=\"text/css\">\n"
    "body span{\n"
    "font-family: HelveticaNeue;\n"
    "border-radius : 3px;\n"
    "font-size: 11px;\n"
    "font-weight: normal;\n"
    "text-align: center;\n"
    "}\n"
    "</style>\n"
    "</head>\n"
    "<body>\n"
    "%@\n"
    "</body>\n"
    "</html>";
    //Create the bitmap graphics context
    NSString *noLabel = @"no_Label";
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(frame.size.width, frame.size.width), NO, 0.0);
    CGContextRef context = UIGraphicsGetCurrentContext();

    NSLog(@"function called");
    //Get the width and heights
    CGFloat imageWidth = image.size.width;
    CGFloat imageHeight = image.size.height;
    CGFloat rectWidth = frame.size.width;

    //Calculate the centre of the circle
    CGFloat imageCentreX = imageWidth/2;

    //Calculate the radius of circle
    CGFloat radius = rectWidth/2;

    //Create circle
    CGContextBeginPath (context);
    CGContextAddArc (context, imageCentreX, imageCentreX, radius-3, 0, 2*M_PI, 0);
    CGContextClosePath (context);

    //Crop circle
    CGContextClip (context);

    //Create rectangle for image and draw in it.
    CGRect NewMmyRect = CGRectMake(0,0,  imageWidth, imageHeight);
    [[self colorFromHexString: color] setFill];  // changes are here
    UIRectFill(NewMmyRect);               // and here

    if(label != noLabel){
        NSString * htmlString = label;
        NSAttributedString * attrStr = [[NSAttributedString alloc] initWithData:[[NSString stringWithFormat:htmlTemplate, htmlString]  dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];

        UILabel * myLabel = [[UILabel alloc] initWithFrame:NewMmyRect];
        myLabel.attributedText = attrStr;
        myLabel.numberOfLines = 0;
        [myLabel sizeToFit];
        [myLabel drawTextInRect:NewMmyRect];
    } else{
        [image drawInRect:NewMmyRect];
    }

    //Convert context into an image and remoove the context
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    //Create a new Image context
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(frame.size.width*2, (imageWidth-2)*1.5-8+25), NO, 0.0);
    CGContextRef context2 = UIGraphicsGetCurrentContext();
    //Create a rectange around the circled image and draw stroke on it.
    float frameWidth =frame.size.width*2;
    float newRectWidth =rectWidth-5;
    CGRect NewMmyRect2 = CGRectMake((frameWidth/2-newRectWidth/2),25,  rectWidth-5, rectWidth-5);
    [newImage drawInRect:NewMmyRect2];


    UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:NewMmyRect2 cornerRadius:imageWidth];
    bezierPath.lineWidth =4;
    CGContextSetStrokeColorWithColor(context2,  [self colorFromHexString: color].CGColor);
    [bezierPath stroke];


    //Create a triangle for bottom pin
    CGContextBeginPath(context2);

    float fithpart =frameWidth/6;
    CGContextMoveToPoint(context2, fithpart*2.5, newRectWidth+25);
    CGContextAddLineToPoint(context2,fithpart*3.5, newRectWidth+25);
    CGContextAddLineToPoint(context2,(frameWidth/2), newRectWidth+25+12);

    CGContextClosePath(context2);



    CGContextSetFillColorWithColor(context2, [self colorFromHexString:color].CGColor);
    CGContextFillPath(context2);
    NSString *noLabel2 = @"no_Heading";
    if(heading != noLabel2){


        CGRect rect1 = NewMmyRect;
        CGRect rect2 = CGRectMake(0, 0, frame.size.width*2, 22);
        UIBezierPath *bezierCorner = [UIBezierPath bezierPathWithRoundedRect:rect2 cornerRadius:3.00];
        CGContextSetFillColorWithColor(context2,  [self colorFromHexString: color].CGColor);
        [bezierCorner fill];
        NSString * htmlStringHeading = heading;
        NSAttributedString * attrStr2 = [[NSAttributedString alloc] initWithData:[[NSString stringWithFormat:htmlTemplate, htmlStringHeading] dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
        //UIRectFill(rect2);
        UILabel * myLabel2 = [[UILabel alloc] initWithFrame:rect2];
        myLabel2.attributedText = attrStr2;
        myLabel2.numberOfLines = 0;
        [myLabel2 sizeToFit];
        [myLabel2 drawTextInRect:rect2];
        CGRectUnion(rect2, rect1);
    }

    UIImage *newImage2 = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage2;
} 

请看这张图,并建议我解决这个问题的方法。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-05-08 13:35:08

终于明白了。

这是一个问题的宽度和高度,我是传递给矩形。宽度和高度值为0。

这就是为什么我会犯这个错误。

票数 0
EN

Stack Overflow用户

发布于 2017-05-05 15:12:38

我认为主要的问题就在这里,您想要异步下载映像。

代码语言:javascript
复制
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
    NSURL *url = [NSURL URLWithString:iconPath];
    [self downloadImageWithURL:url completionBlock:^(BOOL succeeded, UIImage *image) {

    ...
});

这种方法很好,基本问题是:返回的映像不应在主线程中处理,而处理功能实际上需要在主线程中执行。

这也是为什么稍后在代码块中要在主线程中执行更改的原因:

代码语言:javascript
复制
dispatch_async(dispatch_get_main_queue(), ^{
    marker.icon = image;
    ...
});

因此,您必须做的是:在主线程中执行图像处理--在您的情况下,您甚至可以使用以下调度器:

因此,与其:

代码语言:javascript
复制
if([iconType isEqualToString:ImageMarkerString ]){
    NSLog(@"ICON Marker Type Condition True 3");
    CGRect newRect = CGRectMake(0, 0, width, height);
    image = [self circularScaleAndCropImage:image frame:newRect color:borderColor label : markerLabel heading :markerHeading];
}
dispatch_async(dispatch_get_main_queue(), ^{
    marker.icon = image;
    ...
});

将处理移到主线程中,因此最终看起来如下:

代码语言:javascript
复制
dispatch_async(dispatch_get_main_queue(), ^{
    if([iconType isEqualToString:ImageMarkerString ]){
        NSLog(@"ICON Marker Type Condition True 3");
        CGRect newRect = CGRectMake(0, 0, width, height);
        image = [self circularScaleAndCropImage:image frame:newRect color:borderColor label : markerLabel heading :markerHeading];
    }
    marker.icon = image;

    ...
});

有关如何使用调度程序的其他信息,请参见以下内容:https://developer.apple.com/library/content/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html

下面是有关上下文的一些die注释,在其中应该执行操作:https://developer.apple.com/library/content/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43806365

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档