Blurry Image (NSTextAttachment) in NSAttributedString

I am using NSAttributedString to include images in a string. However, the images are sometimes blurry, as if they were drawn on an integer frame.

I tried to make sure that the border of each NSTextAttachment is integer-sized, but that doesn't seem to help. Any tips on making sure it's not blurry?

See the attached screenshot, the first bus is not blurred, and the second.

enter image description here

+5
source share
2 answers

I fixed this by adding a category to NSAttributedString.

Basically, you need to get an NSTextAttachment frame and add the missing fractional part of its X coordinate so that it is well rounded.

- (void)applyBlurrinessFixToAttachments { [self enumerateAttribute:NSAttachmentAttributeName inRange:NSMakeRange(0, self.length) options:0 usingBlock:^(id value, NSRange range, BOOL *stop) { if (![value isKindOfClass:[NSTextAttachment class]]) { return; } NSTextAttachment *attachment = (NSTextAttachment*)value; CGRect bounds = attachment.bounds; CGRect attributedStringRect = [self boundingRectForCharacterRange:range]; double integral; double fractional = modf(attributedStringRect.origin.x, &integral); if (fractional > 0) { double roundedXOrigin = 1.0 - fractional; // If X coordinate starts at 0.7, add 0.3 to it bounds.origin.x += roundedXOrigin; attachment.bounds = bounds; } }]; } - (CGRect)boundingRectForCharacterRange:(NSRange)range { NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:self]; NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init]; [textStorage addLayoutManager:layoutManager]; NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)]; textContainer.lineFragmentPadding = 0; [layoutManager addTextContainer:textContainer]; NSRange glyphRange; [layoutManager characterRangeForGlyphRange:range actualGlyphRange:&glyphRange]; return [layoutManager boundingRectForGlyphRange:glyphRange inTextContainer:textContainer]; } 
+1
source

you can use below code for a round of images

UIGraphicsBeginImageContextWithOptions (CGSizeMake (14, 14), NO, [UIScreen mainScreen] .scale);

 -(UIImage *)makeRoundedImage:(UIImage *) image radius: (float) radius { CALayer *imageLayer = [CALayer layer]; imageLayer.frame = CGRectMake(0, 0, 14, 14); imageLayer.contents = (id) image.CGImage; imageLayer.masksToBounds = YES; imageLayer.cornerRadius = radius; UIGraphicsBeginImageContextWithOptions(CGSizeMake(14, 14), NO, [UIScreen mainScreen].scale); [imageLayer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *roundedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return roundedImage; } 
0
source

Source: https://habr.com/ru/post/1208298/


All Articles