从MKMapView中创build一个UIImage
我想从MKMapView
创build一个UIImage
。 我的地图正确显示在视图中,但是生成的UIImage
只是一个灰色的图像。 这是相关的片段。
UIGraphicsBeginImageContext(mapView.bounds.size); [mapView.layer renderInContext:UIGraphicsGetCurrentContext()]; mapImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();
任何人都知道如何使用MapKit制作UIImage
?
我正在使用与ios SDK 4.1testing相同的代码,并正常工作。 所以,当地图已经显示给用户和用户按下button时,这个动作将被调用:
UIImage *image = [mapView renderToImage];
这里是实现为UIView扩展的包装函数:
- (UIImage*) renderToImage { UIGraphicsBeginImageContext(self.frame.size); [self.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; }
所以,问题不在于代码部分。
在iOS7上,MapKit上有一个新的API,称为MKMapSnapshotter。 所以你实际上不需要创build一个mapview,加载tile并创build一个捕获自己的graphics上下文。
这是改进的视网膜显示function:
@implementation UIView (Ext) - (UIImage*) renderToImage { // IMPORTANT: using weak link on UIKit if(UIGraphicsBeginImageContextWithOptions != NULL) { UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, 0.0); } else { UIGraphicsBeginImageContext(self.frame.size); } [self.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; }
嘿罗兰。 mapView中有多个图层。 我认为第一个是地图,第二个是谷歌图层。 在3.1之后,他们可能会改变mapkit中的某些东西。 你可以试试
[[[mapView.layer sublayers] objectAtIndex:1] renderInContext:UIGraphicsGetCurrentContext()];
你也可以试试
CGRect rect = [mapView bounds]; CGImageRef mapImage = [mapView createSnapshotWithRect:rect];
希望这可以帮助。
请注意,mapView可能无法完成加载,所以图像可能是灰色的。 如
mapViewDidFinishLoadingMap:
不会总是被调用,你应该得到UIImage
mapViewDidFinishRenderingMap:fullyRendered:
所以,代码就像这样
- (UIImage *)renderToImage:(MKMapView *)mapView { UIGraphicsBeginImageContext(mapView.bounds.size); [mapView.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; }
如果您在初始化地图(可能是viewDidLoad?)后立即调用此函数,则可能会得到一个灰色图像,因为地图还没有完成绘制。
尝试:
- 使用performSelector调用捕获代码:withObject:afterDelay:使用一个短暂的延迟(即使是0秒也可以工作,因此在当前方法完成后立即触发)
- 如果要添加注释,请在didAddAnnotationViews委托方法中调用捕获代码
编辑:
在模拟器上,使用performSelector,零延迟工作。 在设备上,需要更长的延迟(约5秒)。
但是,如果添加注释(并在didAddAnnotationViews方法中捕获),则它将在模拟器和设备上立即生效。