2016-02-08 5 views
1

Я нашел пару алгоритмов для нашего приложения, чтобы повернуть аннотации на MKMapView, и в каждом алгоритме плотность пикселей пикселей падает. Вот пример, зеленая стрелка Аннотация: Green arrow annotation exampleНизкая плотность пикселей при вращении UIImage

Algorithm

Может кто знает алгоритм или расширение для выполнения правильного поворота изображения?

ответ

1

Вместо UIGraphicsBeginImageContext используйте UIGraphicsBeginImageContextWithOptions с нулевым значением для последнего параметра. Это позволит увеличить разрешение экрана в соответствии с экраном вашего устройства (например, сетчаткой).


Даже при создании разрешения сетчатки изображения, при вращении растрового изображения, вы собираетесь представят некоторые дополнительные пикселизации. Вы можете получить более точные результаты, если вы рисуете его самостоятельно (например, в drawRect подкласса в пояснительных в):

@interface CustomUserAnnotationView : MKAnnotationView 

@property (nonatomic) CGFloat angle; 
@property (nonatomic) CGFloat lineWidth; 
@property (nonatomic, strong) UIColor *strokeColor; 
@property (nonatomic, strong) UIColor *fillColor; 

@end 

@implementation CustomUserAnnotationView 

- (instancetype)initWithAnnotation:(id<MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier { 
    self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]; 

    if (self) { 
     self.lineWidth = 2; 
     self.strokeColor = [UIColor lightGrayColor]; 
     self.fillColor = [UIColor greenColor]; 
     self.backgroundColor = [UIColor clearColor]; 
     self.frame = CGRectMake(0, 0, 50, 50);    
    } 

    return self; 
} 

// you should probably `setNeedsDisplay` on the other properties' setters, too, but I'm assuming angle is the only one we're worried about right now. 

- (void)setAngle:(CGFloat)angle { 
    _angle = angle; 
    [self setNeedsDisplay]; 
} 

- (void)drawRect:(CGRect)rect { 
    CGPoint center = CGPointMake(self.bounds.size.width/2.0, self.bounds.size.height/2.0); 
    CGFloat radius = (MIN(self.bounds.size.width, self.bounds.size.height) - self.lineWidth)/2.0; 

    UIBezierPath *path = [UIBezierPath bezierPath]; 
    [path moveToPoint: [self pointAtRadius:radius  percentAngle:0.0 center:center angleOffset:self.angle]]; 
    [path addLineToPoint:[self pointAtRadius:radius  percentAngle:0.4 center:center angleOffset:self.angle]]; 
    [path addLineToPoint:[self pointAtRadius:radius * 0.6 percentAngle:0.5 center:center angleOffset:self.angle]]; 
    [path addLineToPoint:[self pointAtRadius:radius  percentAngle:0.6 center:center angleOffset:self.angle]]; 
    [path closePath]; 
    path.lineWidth = self.lineWidth; 
    path.lineJoinStyle = kCGLineJoinRound; 

    [self.fillColor setFill]; 
    [path fill]; 

    [self.strokeColor setStroke]; 
    [path stroke]; 
} 

- (CGPoint)pointAtRadius:(CGFloat)radius percentAngle:(CGFloat)percentAngle center:(CGPoint)center angleOffset:(CGFloat)angleOffset { 
    CGFloat angle = M_PI * 2.0 * percentAngle + angleOffset; 
    return CGPointMake(center.x + radius * sin(angle), center.y - radius * cos(angle)); 
} 

@end 

enter image description here

+0

да, это работает) спасибо) –

+0

FYI, вы можете по-прежнему страдают некоторые пикселизации , но это будет не так плохо. Возможно, вы можете сделать это еще лучше с изображением с более высоким разрешением. Или создайте 'UIBezierPath', который рисует это изображение при любом повороте, соответствующем вашим потребностям. Но если выше это достаточно хорошо, тогда это здорово. – Rob

Смежные вопросы