Skip to main content

Zooming Images with Text in an iOS Scroll View

You have an image containing text. As such, there’s lots of sharp edges. You want to put this image into a scroll view and allow the user to zoom in with a pinch gesture. This is very easy to implement in iOS. Technically, you don’t even need to write code. This can all be done in Interface Builder. However, the further the image is zoomed the blurrier it looks.

Solution 1

Start with a fully zoomed of the image and scale it down when initially adding it to the scroll view. After all, it’s much easier to scale an image down and keep it looking good than it is to scale it up. So during the whole zoom operation the image being displayed is a scaled down version of the original. This would work great except that iOS doesn’t apply the right interpolation when scaling the original large down to fit into the initial smaller frame. You would think self.imageView.layer.minificationFilter = kCAFilterTrilinear; would do the trick but it doesn’t. I could be doing it wrong but I haven’t been able to get this to work yet.

Solution 2

This is a variation of the previous solution. We still start with a large image at the size of its maximum zoom level. We keep a reference to this image on hand so we can create smaller versions of it whenever we need to. We’ll programatically resize the image down to its minimum zoom level and add that to our scroll view as the initial image. We’re using Core Graphics code to do the resizing so the interpolation is done correctly. Credit: variations of this method have appeared in several answers on StackOverflow.

- (UIImage*)resizeImage:(UIImage*)image newSize:(CGSize)newSize
{
    CGRect newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height));
    CGImageRef imageRef = image.CGImage;

    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
    CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, newSize.height);

    CGContextConcatCTM(context, flipVertical);
    CGContextDrawImage(context, newRect, imageRef);

    CGImageRef newImageRef = CGBitmapContextCreateImage(context);
    UIImage *newImage = [UIImage imageWithCGImage:newImageRef];

    CGImageRelease(newImageRef);
    UIGraphicsEndImageContext();

    return newImage;
}

We use this method in two different places. First, when the image is initially added to the scroll view. Second, when the user releases a pinch-zoom gesture. This approach may be a little heavy handed but it ensures a good-looking image at any point the pinch-zoom gesture is released.

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.originalImage = [UIImage imageNamed:@"continuo_display"];

    self.imageView.layer.minificationFilter = kCAFilterTrilinear;
    self.imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"continuo_display"]];
    self.imageView.frame = CGRectMake(0, 0, ORIGINAL_WIDTH, ORIGINAL_HEIGHT);
    self.imageView.image = [self resizeImage:self.originalImage newSize:CGSizeMake(ORIGINAL_WIDTH, ORIGINAL_HEIGHT)];

    self.scrollView.minimumZoomScale = 1.0f;
    self.scrollView.maximumZoomScale = 2.0f;
    [self.scrollView addSubview:self.imageView];
}

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
{
    int new_width = ORIGINAL_WIDTH * self.scrollView.zoomScale;
    int new_height = ORIGINAL_HEIGHT * self.scrollView.zoomScale;
    self.imageView.image = [self resizeImage:self.originalImage newSize:CGSizeMake(new_width, new_height)];
}

The performance of this measured on an entrey-level iPad is pretty smooth.


The above solution and content was initially published by mluton on his own website which was left to decay and domain expiration and was recovered by projTek - an AI-powered R&D project. The GitHub repo of the original author: https://github.com/mluton 

Comments

Popular posts from this blog

What is .csp extension? C++ Server Pages

C++ Server Pages C++ Server Pages (CSP) is a Web Engine for advanced Web Application Development, that uses blended Markup Language / C++ scripts ( such as HTML/C++, XML/C++, WML/C++ etc.) Similar to ASP and JSP, it provides a great easiness in creating web pages with dynamic content, as well as complex business applications. However, instead of Java, Javascript or VBscript, it uses C++ . This brings some significant advantages: Incredibly high processing efficiency. Benchmarks have shown a range of 80 to 250 times higher processing speed than ASP. The use of pure C++ allows the use of tons of libraries that are currently available. It is important to notice that the libraries written in C++ are tens or hundreds of times more than in any other language. It is widely accepted that the most skilled programmers in the IT market are the C++ ones. However, CGI, ISAPI and other frameworks where C++ applies, do not provide the web developer with facilities for efficient app

Valid styles for converting datetime to string

I wrote this little table and procedure to help me remember what style 104 did, or how to get HH:MM AM/PM out of a DATETIME column. Basically, it populates a table with the valid style numbers, then loops through those, and produces the result (and the syntax for producing that result) for each style, given the current date and time. It uses also a cursor. This is designed to be a helper function, not something you would use as part of a production environment, so I don't think the performance implications should be a big concern. Read more »