图片我正在使用离子型/科尔多瓦地图插件开发一个地图应用程序,我想改变标记,所以我在ios平台上改变插件。我正在传递标记图标中的自定义属性,并绘制一个矩形以显示标记上的标题。从本地加载图像时,从circularScaleAndCropImage方法调用setIcon方法。
我得到了这个上下文错误,我不知道如何解决这个问题。
`-(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;
} 请看这张图,并建议我解决这个问题的方法。
发布于 2017-05-08 13:35:08
终于明白了。
这是一个问题的宽度和高度,我是传递给矩形。宽度和高度值为0。
这就是为什么我会犯这个错误。
发布于 2017-05-05 15:12:38
我认为主要的问题就在这里,您想要异步下载映像。
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) {
...
});这种方法很好,基本问题是:返回的映像不应在主线程中处理,而处理功能实际上需要在主线程中执行。
这也是为什么稍后在代码块中要在主线程中执行更改的原因:
dispatch_async(dispatch_get_main_queue(), ^{
marker.icon = image;
...
});因此,您必须做的是:在主线程中执行图像处理--在您的情况下,您甚至可以使用以下调度器:
因此,与其:
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;
...
});将处理移到主线程中,因此最终看起来如下:
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
https://stackoverflow.com/questions/43806365
复制相似问题