2014-05-09 2 views
3

들어 가지 :iOS MKMapView를 UIImage로 변환 중입니다. 절대로이 답변에 따라 블록

Snapshot of MKMapView

내가 사진 내지도를 변환하는 시도를하지만, 앱은 결코 snapshotter 블록을 입력합니다.

왜?

//Get location an then get a Picture of the Map. 
CLLocation *userLoc = self.map.userLocation.location; //self.map is a MKMapView; 
CLLocationCoordinate2D punto = userLoc.coordinate; 
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(punto, 500, 500); 
[self.map setRegion:(region)]; 
[self.map setShowsUserLocation:YES]; 
//Place a Pin in actual location. 
MKPointAnnotation *pin = [[MKPointAnnotation alloc]init]; 
pin.coordinate = punto; 
pin.title = @"Localización"; 
[self.map addAnnotation:pin]; 

//Convert map to picture. 
MKMapSnapshotOptions *options = [[MKMapSnapshotOptions alloc] init]; 
options.region = self.map.region; 
options.scale = [UIScreen mainScreen].scale; 
options.size = self.map.frame.size; 

MKMapSnapshotter *snapshotter = [[MKMapSnapshotter alloc] initWithOptions:options]; 
[snapshotter startWithQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) completionHandler:^(MKMapSnapshot *snapshot, NSError *error) { 
    NSLog(@"Entering the block."); //Never prints! 
    // get the image associated with the snapshot 
    UIImage *image = snapshot.image; 
    NSLog(@"imagen %@",image); //Niether do this! 
    // Get the size of the final image 
    CGRect finalImageRect = CGRectMake(0, 0, image.size.width, image.size.height); 
    // Get a standard annotation view pin. Clearly, Apple assumes that we'll only want to draw standard annotation pins! 
    MKAnnotationView *pin = [[MKPinAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:@""]; 
    UIImage *pinImage = pin.image; 
    // ok, let's start to create our final image 
    UIGraphicsBeginImageContextWithOptions(image.size, YES, image.scale); 
    // first, draw the image from the snapshotter 
    [image drawAtPoint:CGPointMake(0, 0)]; 
    // now, let's iterate through the annotations and draw them, too 
    for (id<MKAnnotation>annotation in self.map.annotations) 
    { 
     CGPoint point = [snapshot pointForCoordinate:annotation.coordinate]; 
     if (CGRectContainsPoint(finalImageRect, point)) // this is too conservative, but you get the idea 
     { 
      CGPoint pinCenterOffset = pin.centerOffset; 
      point.x -= pin.bounds.size.width/2.0; 
      point.y -= pin.bounds.size.height/2.0; 
      point.x += pinCenterOffset.x; 
      point.y += pinCenterOffset.y; 
      [pinImage drawAtPoint:point]; 
     } 
    } 
    // grab the final image 
    UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext(); 
    NSLog(@"Picture inside the block %@",finalImage); //Never prints. 
    UIGraphicsEndImageContext(); 
    // and save it 
    NSData *data = UIImagePNGRepresentation(finalImage); 
    [data writeToFile:@"Picture.jpg" atomically:YES]; 
    if (error) { 
     NSLog(@"Error"); //This is not printed. 
    }else{ 
     NSLog(@"Success!"); //Neither do this. 
     self.fotoParaEnviar = finalImage; 
    } 
}]; 
NSLog(@"Picture outside the block %@",self.fotoParaEnviar); //This is allway NULL 

모든 것이 잘 인스턴스화 된 것처럼 보입니다.

그럼 왜 블록이 실행되지 않습니까?

+0

이 문제는 재현 할 수 없지만 본 사람은 본인이 아닙니다. http://stackoverflow.com/questions/22774090/ios-mkmapshapshotter-completion-block-is-not-always-being- – Rob

답변

0

당신이 변경하는 경우 : 여기에

[snapshotter startWithQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) 

:

[snapshotter startWithQueue:dispatch_get_main_queue() 

을 그리고이 NSLog(@"Picture inside the block %@",self.fotoParaEnviar);async 항상 NULL snapshotter로되며 그 때까지는 당신은 여전히 ​​위의 NSLog 코드에 도달 그 블록을 실행하십시오

또는이 instad 시도 할 수도 있습니다 :

[snapshotter startWithCompletionHandler:^(MKMapSnapshot *snapshot, NSError *error) { 
    UIImage *image = snapshot.image; 
    // and so on 
}]; 
+0

Panayot. 나는 당신이 제안한 것을 시도했다 : [snapshotter startWithQueue : dispatch_get_main_queue() 나는 심지어 시도했다 : [snapshotter startWithCompletionHandler :^(MKMapSnapshot * snapshot, NSError * error) {그러나 여전히 작동하지 않는다. 왜 이것은 결코 인쇄되지 않습니다 : NSLog (@ "블록 입력하기."); 그리고 만약 : NSLog (@ "블록 안의 그림 % @", self.fotoParaEnviar); 항상 null입니다. 적어도 인쇄 할 것입니다 : 블록 내부의 그림 NULL 그러나 인쇄되지 않습니다. 시간 내 줘서 고마워. – user3614102

+0

코드가 편집되었습니다. 제발 봐봐 – Pancho

1

이미지도를 표시하는 경우, 다음 Snapshot of MKMapView in iOS7 나는 그들이 검은 이미지를 얻을 이유를 이해하지 않는, 거의 제대로 얻을 수 있지만 렌더링으로 0.0을 통과하지 못한 이미지로 저장하는 데 필요한 마법이 없다 스케일은 1.0이나 2.0 (망막)이고, 코드는 그래픽을 위해 있어야하기 때문에 주 스레드에 있지 않을 수도 있습니다.

어쨌든, 난 그냥 7.1이 시도하고 사용자 파란색 점 및 주석 핀 올바른 이미지를 가지고 :

[ObCommons createJPEGfromView:self.map withSize:self.map.bounds.size toPath:[ObCommons getPathInDocuments:@"test.jpg"]]; 
+(UIImage*) createImageFromView:(UIView*)newt withSize:(CGSize)rensize { 
    UIGraphicsBeginImageContextWithOptions(rensize, NO, 2.0); // 1.0 or 2.0 for retina (get it from UIScreen) 
    [newt.layer renderInContext:UIGraphicsGetCurrentContext()]; 
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();  
    UIGraphicsEndImageContext(); 

    return image; 
} 

+(UIImage*) createJPEGfromView:(UIView*)newt withSize:(CGSize)rensize toPath: (NSString*)filePath quality:(float)quality{ 
    UIImage *ximage = [ObCommons createImageFromView:newt withSize:rensize];  
    NSData *imageData = UIImageJPEGRepresentation(ximage, quality); 

    if (filePath!=nil) { 
     [imageData writeToFile:filePath atomically:YES]; 
    } 

    return ximage; 
} 

+(CGFloat)retinaFactor { 
    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] && [[UIScreen mainScreen] scale] > 1) { 
     return [[UIScreen mainScreen]scale]; 
    } else { 
     return 1.0f; 
    } 
} 

더 읽을 수를, 여기에 관련된 방법의 요점은 다음과 같습니다 https://gist.github.com/quentar/d92e95728ce0d950db65

나는 다음과 같은 솔루션이 질문을 닫습니다
+0

그래, 이건 7 이전 iOS 버전에 대한 노력과 진정한 기술입니다. "관점에서지도 키트를 넣는"WWDC에서, 그들은 명시 적으로 우리가'renderInContext' 코드를 "함께 던져"조언 iOS 7에지도가 있습니다.Snapshotter는 모든 종류의 이점을 제공합니다 (모든 관련 타일을 검색 한 후에 만 ​​자동으로 호출되며 맵보기가 전혀 필요없고보다 강력한 오류 처리). OP가 snapshotter를 작동시키지 못하면 우발적 일 수 있습니다 계획. – Rob

+0

+1 그런데, 위의 기술을 사용한다면, 이걸'mapViewDidFinishRenderingMap : fullyRendered :'(적어도 iOS 7의 경우)에 넣어 두는 것이 현명 할 수 있습니다. 그래서 화면 스냅 샷은 모든 데이터가 검색되고지도가 완전히 렌더링되었습니다 (또는 가능한 한 많이). 모든지도 데이터가 검색되기 전에 단순히'renderInContext'를 사용하면 검은 색 이미지 (또는 불필요하게 불완전한 이미지)를 얻을 수 있습니다. – Rob

0

:

FIRST하자 MKMapView의 L 보기에서 completly을 누른 다음 블록을 입력하여 UIImage로 변환하십시오.

도움 주셔서 감사합니다.

+0

코드에서 어떻게 수행했는지 나와 공유 해 주실 수 있습니까? 나는 비슷한 문제가 있다고 생각한다. 감사. – SanitLee