Bergutov Ruslan February 2016

Low pixel density when rotation UIImage

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: Green arrow annotation example

Algorithm

Maybe someone knows algorithm or extension to perform correct rotation of image?

Answers


Rob February 2016

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 cent 

Post Status

Asked in February 2016
Viewed 3,052 times
Voted 14
Answered 1 times

Search




Leave an answer