从 MKMapView 制作 UIImage

发布于 2024-10-01 11:48:56 字数 377 浏览 0 评论 0原文

我想从 MKMapView 创建一个 UIImage。我的地图在视图中正确显示,但是生成的 UIImage 只是灰色图像。这是相关的片段。

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

有人知道如何使用 MapKit 制作 UIImage 吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

水晶透心 2024-10-08 11:48:56

我使用的代码与 ios sdk 4.1 测试的相同并且工作正常。因此,当地图已经显示给用户并且用户按下按钮时,将调用此操作:

UIImage *image = [mapView renderToImage];

这是作为 UIView 扩展实现的包装函数:

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

所以,问题不在于该代码部分。

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.

滥情哥ㄟ 2024-10-08 11:48:56

在 iOS7 上,MapKit 上有一个新的 API,称为 MKMapSnapshotter。因此,您实际上不需要创建地图视图、加载图块并创建捕获自己的图形上下文。

请查看 https://developer .apple.com/library/ios/documentation/MapKit/Reference/MKMapSnapshotter_class/Reference/Reference.html

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

辞旧 2024-10-08 11:48:56

这是视网膜显示的改进功能:

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

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;
}
溺孤伤于心 2024-10-08 11:48:56

嘿洛伦。地图视图中有多个图层。我认为第一个是地图,第二个是谷歌图层。他们可能在 3.1 之后更改了 Mapkit 中的某些内容。您可以尝试

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

您也可以尝试

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

希望这会有所帮助。

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.

所谓喜欢 2024-10-08 11:48:56

请注意,mapView 可能无法完成加载,因此图像可能是灰色的。
as

mapViewDidFinishLoadingMap:

不会总是被调用,你应该在

mapViewDidFinishRenderingMap:fullyRendered:

so 中获取 UIImage,代码就像这样

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

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;
}
漫漫岁月 2024-10-08 11:48:56

如果您在初始化地图后立即调用此方法(也许在 viewDidLoad 中?),您可能会得到灰色图像,因为地图尚未完成绘制。

尝试:

  • 使用performSelector:withObject:afterDelay调用捕获代码:使用短暂的延迟(甚至0秒也可能有效,因此它会在当前方法完成后立即触发)
  • 如果要添加注释,请在didAddAnnotationViews委托方法中调用捕获代码

<强>编辑:
在模拟器上,使用performSelector,可以实现零延迟。在设备上,需要较长的延迟(大约5秒)。

但是,如果您添加注释(并在 didAddAnnotationViews 方法中捕获),它会立即在模拟器和设备上运行。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文