6

First of all, I'm using this AFNetworking method:

[imageView setImageWithURL:[NSURL URLWithString:@"http://site.com/img.png"]];

1 - This method is asynchronous? It will cache the image in iPhone?

2 - How can I crop/resize this image? I have a 800x600 image in the URL, but my UIImageView is 400x400, I only want to have the url image cropped before being shown, to be the same ratio, like 600x600 (It's not needed to be 400x400, just same ratio). Like facebook app.

iPatel
  • 46,010
  • 16
  • 115
  • 137
Daniel Campos
  • 971
  • 4
  • 11
  • 20
  • After download the image You can crop it. For cropping [see here](http://stackoverflow.com/questions/7087435/image-cropping-api-for-ios) – TheTiger Jul 16 '13 at 12:00
  • On image resizing, if you've got something that works, that's great, but if not, I might suggest the `scaleImageToSizeAspectFit` method as shown in [this category](http://stackoverflow.com/a/10491692/1271826). – Rob Jul 16 '13 at 13:17

4 Answers4

17

The resizing has been answered elsewhere, but to your first question:

This method is asynchronous?

Yes, it is asynchronous. You can use the callback blocks if you want to process the image, e.g.:

[imageView setImageWithURLRequest:request
                 placeholderImage:nil
                          success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {

                              // do image resize here

                              // then set image view

                              imageView.image = image;
                          }
                         failure:nil];

You then ask:

It will cache the image in iPhone?

If you're just looking to cache in memory for performance reasons, then the answer is an unequivocal yes. It employs a NSCache (which will be emptied upon memory pressure). As an aside, it will cache the image as retrieved, not reflecting any resizing you do after the fact.

If you're looking to cache in persistent storage (i.e. a cache that will persist even if you terminate app and restart it), that question is a little less clear. AFNetworking claims to support disk caching through its use of NSURLCache, but I have had problems getting that to work on iOS. If you need persistent storage caching, I might suggest a variety of other UIImageView categories, such as SDWebImage.

Anyway, for the AFNetworking official line on caching, I might refer you to the Caching discussion in the AFNetworking FAQ.


If you want an activity indicator view, you can:

UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
activityIndicatorView.center = self.imageView.center;
[self.view addSubview:activityIndicatorView];
[activityIndicatorView startAnimating];

[imageView setImageWithURLRequest:request
                 placeholderImage:nil
                          success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {

                              [activityIndicatorView removeFromSuperview];

                              // do image resize here

                              // then set image view

                              imageView.image = image;
                          }
                          failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
                              [activityIndicatorView removeFromSuperview];

                              // do any other error handling you want here
                          }];
Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Another question: placeholderImage could be a activityindicator GIF? – Daniel Campos Jul 16 '13 at 14:34
  • @DanielCampos Instead of animated GIF, I might suggest `UIActivityIndicatorView`. See revised answer. – Rob Jul 16 '13 at 14:57
  • Hi Rob, I understood everything and it's awesome. But in my case, there will be a lot of UIImageViews, something like Instagram app, and I want an activityindicador in the middle of all UIImageViews, for that I think the gif is a most effective solution. Do you agree? – Daniel Campos Jul 16 '13 at 15:01
  • @DanielCampos Personally, I'd probably stick with `UIActivityIndicatorView`, but it's up to you. If I really wanted some non-standard look to my spinner, I might be inclined to use the `UIImage` methods `animatedImage...`, but try both ways and see what works best for you. – Rob Jul 16 '13 at 15:08
  • As an aside, having a bunch of activity indicators (regardless of how you implement it) can be distracting. Many apps will just leave the image blank and the gracefully fade the images in as they're downloaded. That might be more elegant. – Rob Jul 16 '13 at 17:16
  • Yes. It's more elegant :D . But this AFNetworking method just give the SUCCESS position, not progress. :( – Daniel Campos Jul 16 '13 at 17:19
  • We've probably beat the topic to death, so if you want to let it go, that's fine. But if you want to discuss further we can [continue this discussion in chat](http://chat.stackoverflow.com/rooms/33590/discussion-between-rob-and-daniel-campos) – Rob Jul 16 '13 at 19:49
2

For Get Crop Image:

UIImage *croppedImg = nil;
CGRect cropRect = CGRectMake(AS YOu Need);
croppedImg = [self croppIngimageByImageName:self.imageView.image toRect:cropRect];

Use following method that return UIImage (as You want size of image)

- (UIImage *)croppIngimageByImageName:(UIImage *)imageToCrop toRect:(CGRect)rect
    {
        //CGRect CropRect = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height+15);

        CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage], rect);
        UIImage *cropped = [UIImage imageWithCGImage:imageRef];
        CGImageRelease(imageRef);

        return cropped;
    }

Here you get Croped Image that return by above method;

OR RESIZING

And also Use following method for specific hight and width with image for Resizing UIImage:

+ (UIImage*)resizeImage:(UIImage*)image withWidth:(int)width withHeight:(int)height
{
    CGSize newSize = CGSizeMake(width, height);
    float widthRatio = newSize.width/image.size.width;
    float heightRatio = newSize.height/image.size.height;

    if(widthRatio > heightRatio)
    {
        newSize=CGSizeMake(image.size.width*heightRatio,image.size.height*heightRatio);
    }
    else
    {
        newSize=CGSizeMake(image.size.width*widthRatio,image.size.height*widthRatio);
    }


    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
    [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

This method return NewImage, with specific size that you want.

iPatel
  • 46,010
  • 16
  • 115
  • 137
  • This method is awesome. But it is needed to use the "+" instead of the "-" at the start of the method declaration? – Daniel Campos Jul 16 '13 at 12:15
  • then change sign and you need to call this method by class name its call static method – iPatel Jul 16 '13 at 12:17
  • The "+" is a public function, and "-" is a private function. – olamarche Jul 16 '13 at 12:18
  • 3
    @olamarche close, '+' denotes a CLASS METHOD while '-' signifies an INSTANCE METHOD. A class method we all know & love [NSString stringWithFormat:] (Notice it is called on the class, NSString) where an instance method for NSString would be [instanceOfString characterAtIndex:] would be called on an instance of NSString to get the character at the index of that specific string. – self.name Nov 11 '13 at 23:44
  • Hello @iPatel I've little question arise in my mind.How can I use your code if I'm getting string from remote server?Please help me,I'm stuck with it – Vaibhav Limbani Aug 06 '14 at 05:01
0

From AFNetworking v.2.0 there's AFCoreImageSerializer

The response serializer used to create an image representation from the server response and response data. By default, this is an instance of AFImageResponseSerializer

Subclasses of AFImageResponseSerializer could be used to perform post-processing, such as color correction, face detection, or other effects.

You can use this to crop the image before setting to UIImageView.

Community
  • 1
  • 1
Hemang
  • 26,840
  • 19
  • 119
  • 186
0

I have a code sample to add to Hemang's answer.

This is what AFImageResponseSerializer is for. Just change the image scale to match the image scale you're retrieving.

AFImageResponseSerializer *imageResponseSerializer = [self.avatarImageView imageResponseSerializer]; [imageResponseSerializer setImageScale:1.0];

Steve Moser
  • 7,647
  • 5
  • 55
  • 94