Черно-белое наложение для MKMapView - PullRequest
6 голосов
/ 24 января 2012

У меня есть MKMapView , и я добавляю оверлей (MKOverlay) к нему.

Я бы хотел, чтобы наложение сделало вид карты снизу черно-белым (т.е. монохромным).Есть ли способ сделать это?

(я думаю, я мог бы сделать наложение полупрозрачным черный / серый, но это не тот эффект, который я хотел бы.)

Сведения о системе: разработка приложения для iOS 5 в Xcode 4.2.

Ответы [ 2 ]

7 голосов
/ 24 января 2012

Самый правильный маршрут, который, к сожалению, пока недоступен на iOS, будет:

Ваш MKOverlay в какой-то момент используется для создания MKOverlayView, который будет иметь CALayerкак он спускается с UIView.Вы можете прикрепить CIFilter s как compositingFilter s к CALayer s, которые определяют, как представление комбинируется с фоном.К этому можно добавить фильтр типа CIColorMonochrome.

Поскольку эта опция недоступна, вам придется преодолеть некоторые серьезные препятствия, чтобы выполнить работу самостоятельно.Вероятно, вам потребуется реализовать свой собственный MKOverlayView, который в своих drawView использует методы, приведенные в QA1703 от Apple, для получения пиксельного содержимого вида карты в соответствующей области (будьте осторожны, чтобыв конечном итоге в бесконечном рекурсивном цикле), преобразуйте их в черно-белые и представьте их в качестве своего взгляда.

Это то, что стоит исследовать дальше, или вы будете счастливее заменить эффект, чем действительно углубляться вэтот материал?

1 голос
/ 18 октября 2017

Мне нужны были те же манипуляции с цветом на карте, и я решил, что сделать всю карту черно-белой может быть лучшим решением, вот как вы можете это сделать:

  1. создано новое изображение CGcontex
  2. рендеринг карты в новом CGcontext
  3. получил UIImage от текущего CGcontext
  4. применил CIFilter к UIImage и получил CIImage в результате
  5. визуализировал CIImage в CIContext и получил CGImageRef в результате
  6. создал UIImage из CGImageRef
  7. добавлен вид подизображения для вида карты яблока
  8. установить изображение результата для этого изображения.

Вот некоторый грязный код для этого:

  self.drawContext = [[CIContext alloc] init];
  [self.monochromeSubView removeFromSuperview];

  UIGraphicsBeginImageContext(self.appleMapView.bounds.size);
  UIImage *mySourceImage = UIGraphicsGetImageFromCurrentImageContext();
  CIImage *newMyCiImage = [[CIImage alloc] initWithImage:mySourceImage];
  CIFilter *newMyMonochromeFilter = [CIFilter filterWithName:@"CIPhotoEffectTonal"];
  [newMyMonochromeFilter setValue:newMyCiImage forKey:kCIInputImageKey];
  CIImage *newMyfilteredCIImage = newMyMonochromeFilter.outputImage;
  
  CGImageRef myOutputImageRef = [self.drawContext createCGImage:newMyfilteredCIImage
                                                       fromRect:newMyfilteredCIImage.extent];
  UIImage *newMyImage = [[UIImage alloc] initWithCGImage:myOutputImageRef];

  self.monochromeSubView.image = newMyImage;
  [self.appleMapView addSubview:self.monochromeSubView];

  CGImageRelease(myOutputImageRef);
  UIGraphicsEndImageContext();

Вот, пожалуйста, карта черного и белого цветов. Чтобы сделать это динамически, чтобы перемещать монохромную карту вместе с жестом пользователя, вы можете использовать распознаватель жестов подкласса, добавив его непосредственно в представление карты. Затем при каждом вызове touchesMoved вы можете вызывать эту функцию перерисовки, используя повторно созданный вами контекст. Я попробовал это с яблочной картой, занимающей около 1/3 экрана, и это привело к чрезвычайно низкой производительности (около 3 кадров в секунду на iPhone 5s), и есть несколько ошибок, которые вы должны исправить, например: летающая карта при жесте смахивания во время монохромного изображения является статическим, частота перерисовки пинов карты, перерисовки или анимации каждого всплывающего окна, отображаемого в ответ на нажатие. Вы можете попытаться отобразить карту в CALayer, а не в Context. Apple рекомендует улучшить производительность, но, учитывая все вышесказанное, я полагаю, если вы хотите видеть динамически фильтруемые элементы, лучше использовать другую, более настраиваемую карту: GoogleMap или MapBox.

...