Reputation: 157
I have found a couple algorithm for our application to rotate annotations on MKMapView, and in every algorithm pixel density of image is crashing. Here is the example, green arrow annotation:
Maybe someone knows algorithm or extension to perform correct rotation of image?
Upvotes: 1
Views: 58
Reputation: 437632
Rather than UIGraphicsBeginImageContext
, use UIGraphicsBeginImageContextWithOptions
with zero for the last parameter. That will maximize the screen resolution to match your device's screen (e.g. retina).
Even when you create the retina resolution image, when you rotate a bitmap, you're going to be introducing some further pixelation. You may get the sharper results if you draw it yourself (e.g. in the drawRect
of the annotation view's subclass):
@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
Upvotes: 1