4

I need to make an UIImageView supports zoom in/out, and the most important is, when an image is enlarged, it should been seen the clear and large pixels, but not the fuzzy processed effect, like the images below.

It should be like that:

enter image description here

Should not be like that:

enter image description here

My code, doesn't work:

- (void)viewDidLoad {
    [super viewDidLoad];

    self.view.backgroundColor = [UIColor whiteColor];

    imageView = [[ColorPickImageView alloc] initWithImage:self.image];
    imageView.contentMode = UIViewContentModeScaleAspectFit;

    [self addGestureRecognizerToView:imageView];
    [imageView setUserInteractionEnabled:YES];
    [imageView setMultipleTouchEnabled:YES];

    [self.view addSubview:imageView];

    [imageView setTranslatesAutoresizingMaskIntoConstraints:NO];
    NSDictionary *views = NSDictionaryOfVariableBindings(imageView);
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[imageView]-0-|" options:0 metrics:nil views:views]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[imageView]-0-|" options:0 metrics:nil views:views]];
}

- (void)addGestureRecognizerToView:(UIView *)view
{
    UIPinchGestureRecognizer *pinchGestureRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchView:)];
    [view addGestureRecognizer:pinchGestureRecognizer];
}

- (void)pinchView:(UIPinchGestureRecognizer *)pinchGestureRecognizer
{
    UIView *view = pinchGestureRecognizer.view;
    if (pinchGestureRecognizer.state == UIGestureRecognizerStateBegan || pinchGestureRecognizer.state == UIGestureRecognizerStateChanged) {
        view.transform = CGAffineTransformScale(view.transform, pinchGestureRecognizer.scale, pinchGestureRecognizer.scale);
        pinchGestureRecognizer.scale = 1;
    }
}
Suge
  • 2,808
  • 3
  • 48
  • 79
  • 1
    Possible duplicate of:http://stackoverflow.com/questions/22853863/in-ios-how-do-you-preserve-sharp-edges-when-enlarging-a-bitmap and http://stackoverflow.com/questions/27188456/how-to-prevent-the-pixels-from-becoming-blurry-when-i-enlarge-an-image-in-my-col. In fact, that last one is from the same OP and already has an answer – fishinear Nov 29 '14 at 17:47
  • Thank you, the first topic achieves my purpose, but I want to ask, when I use `magnificationFilter = kCAFilterNearest`, are the big and sharp pixels magnified really the original pixels of the image, or just produced by some processing?Thank you! – Suge Nov 30 '14 at 01:23
  • afaik, kCAFilterNearest does not fabricate any pixels. Anything you see comes from the original picture. – fishinear Nov 30 '14 at 02:22
  • @fishinear, thank you, someone says I should use `shouldRasterize = YES` to avoid the problem where some images show 4 pixels for every pixel, but if I do so, the pixels look like not the original pixels of the image, but the processed bigger ones.Do you know about that? – Suge Nov 30 '14 at 04:42
  • Your original image is already a bitmap, so `shouldRasterize` should not have any effect. – fishinear Nov 30 '14 at 12:36
  • But note that if you scale up with a non-integer factor then, with `kCAFilterNearest`, the original pixels will not all blow up to the same size, of course. – fishinear Nov 30 '14 at 12:40
  • @fishinear, thank you, but in my testing, it's different when I use `shouldRasterise=YES`, the pixels become bigger.Pls look at that answer http://stackoverflow.com/questions/3900474/how-to-scale-up-an-uiimage-without-smoothening-anything#comment-42899996 – Suge Dec 01 '14 at 03:43
  • If you have a problem with shouldRasterize, then don't use it. And I don't know what you mean with "the pixels become bigger". Maybe you should post some pictures, and the code that produces them, distilled down to the minimum. If it is not produced in the way you would like it, then you also need to be very specific about what you like to achieve. – fishinear Dec 01 '14 at 13:33

1 Answers1

11

OK, I got intrigued, and could not help but setup a quick 15 minute test. The results are in line with the SO answer I already quoted in the comments. The following works fine for me to generate a pixelated image:

- (void)viewDidLoad {
    [super viewDidLoad];

    UIImage *image = [UIImage imageNamed:@"LocationDot"];
    self.imageView.image = image;
    self.imageView.contentMode = UIViewContentModeScaleAspectFit;
    self.imageView.layer.magnificationFilter = kCAFilterNearest;
//  self.imageView.layer.shouldRasterize = YES;
//  self.imageView.transform = CGAffineTransformMakeScale( 4, 4);
}

This generates:

pixelated image

With the default kCAFilterLinear you get this:

enter image description here

When applying the transform, it also has the desired effect:

enter image description here

The shouldRasterize has no effect, as expected. With a bitmap as content, it only has some effect if you put a transform on the layer and then do composition with another layer. And even then, the documentation says:

If the rasterized bitmap requires scaling during compositing, the filters in the minificationFilter and magnificationFilter properties are applied as needed.

Community
  • 1
  • 1
fishinear
  • 6,101
  • 3
  • 36
  • 84