Make a UIImage from a MKMapView

早过忘川 提交于 2019-11-27 15:06:58

问题


I want to create a UIImage from a MKMapView. My map is correctly displayed in the view, however the UIImage produced is just a gray image. Here's the relevant snippet.

UIGraphicsBeginImageContext(mapView.bounds.size);
[mapView.layer renderInContext:UIGraphicsGetCurrentContext()];
mapImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Anyone know how to make a UIImage using MapKit?


回答1:


I am using the same code that is tested with ios sdk 4.1 and works fine. So, when map is already displayed to user and user press the button this action will be called:

UIImage *image = [mapView renderToImage];

and here is the wrapper function realized as UIView extension:

- (UIImage*) renderToImage
{
  UIGraphicsBeginImageContext(self.frame.size);
  [self.layer renderInContext:UIGraphicsGetCurrentContext()];
  UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();  
  return image;
}

So, the problem is not in that code part.




回答2:


On iOS7, there is a new API on MapKit for this called MKMapSnapshotter. So you actually don't need to create a mapview, load the tiles and create a graphic context capturing yourself.

Take a look into it at https://developer.apple.com/library/ios/documentation/MapKit/Reference/MKMapSnapshotter_class/Reference/Reference.html




回答3:


Here is the improved function for retina display:

@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;
}



回答4:


Hey Loren. There are multiple layers in the mapView. I think the first one is the map and the second on is the google layer. They might have changed something in the mapkit after 3.1. You can try

[[[mapView.layer sublayers] objectAtIndex:1] renderInContext:UIGraphicsGetCurrentContext()];

You can also try

CGRect rect = [mapView bounds];
CGImageRef mapImage = [mapView createSnapshotWithRect:rect];

Hope this helps.




回答5:


Note that, mapView may not finish load so image may be grey. as

mapViewDidFinishLoadingMap:

will not always be called, you should get UIImage in

mapViewDidFinishRenderingMap:fullyRendered:

so, the code just like this

- (UIImage *)renderToImage:(MKMapView *)mapView
{
  UIGraphicsBeginImageContext(mapView.bounds.size);
  [mapView.layer renderInContext:UIGraphicsGetCurrentContext()];
  UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();
  return image;
}



回答6:


If you are calling this immediately after initializing the map (maybe in viewDidLoad?), you could get a gray image as the map is not finished drawing yet.

Try:

  • Calling the capture code using performSelector:withObject:afterDelay: using a short delay (even 0 seconds might work so it fires right after the current method is finished)
  • If you are adding annotations, call the capture code in the didAddAnnotationViews delegate method

Edit:
On the simulator, using performSelector, a zero delay works. On the device, a longer delay is required (about 5 seconds).

However, if you add annotations (and you capture in the didAddAnnotationViews method), it works immediately on both the simulator and device.



来源:https://stackoverflow.com/questions/4159596/make-a-uiimage-from-a-mkmapview

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!