I am fetching a gif from the NOAA of the current weather radar, I store it in a UIImage and then draw it to an MKMapView, here is some of the code I am using:
image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://radar.weather.gov/ridge/Conus/RadarImg/latest_radaronly.gif"]]];
MKMapRect theMapRect = [self.overlay boundingMapRect];
CGRect theRect = [self rectForMapRect:theMapRect];
#try {
UIGraphicsBeginImageContext(image.size);
UIGraphicsPushContext(ctx);
[image drawInRect:theRect];
UIGraphicsPopContext();
UIGraphicsEndImageContext();
}
#catch (NSException *exception) {
NSLog(#"Caught an exception while drawing radar on map - %#",[exception description]);
}
#finally {
}
Does anyone know how I can animate this gif repeatedly to achieve a weather like radar you see on the news. I have found several apps that do this and am wondering how I can incorporate it into my own project.
The link you provided doesn't actually show an animated gif. It just retrieves the latest gif. One way you could do it is load the latest 10-20 gif's the NOAA has uploaded here, they seem to update it every 10 minutes, then create a UIImage for each gif and cycle through them in a UIImageview which overlays your map.
For example:
// Set images
radarGIF01 = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://radar.weather.gov/ridge/Conus/RadarImg/Conus_20150209_0108_N0Ronly.gif"]]];
radarGIF02 = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://radar.weather.gov/ridge/Conus/RadarImg/Conus_20150209_0118_N0Ronly.gif"]]];
radarGIF03 = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://radar.weather.gov/ridge/Conus/RadarImg/Conus_20150209_0128_N0Ronly.gif"]]];
radarGIF04 = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://radar.weather.gov/ridge/Conus/RadarImg/Conus_20150209_0138_N0Ronly.gif"]]];
radarGIF05 = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://radar.weather.gov/ridge/Conus/RadarImg/Conus_20150209_0148_N0Ronly.gif"]]];
// Add images to array
radarImagesArray = [[NSArray alloc]initWithObjects: radarGIF01, radarGIF02, radarGIF03, radarGIF04, radarGIF05, nil];
// Animate images in UIImageview
_radarImageView.animationImages = radarImagesArray;
_radarImageView.animationDuration = 3.0;
_radarImageView.animationRepeatCount = 0;
[_radarImageView startAnimating];
Related
I have a folder in Images.xcassets which have 24 images. I want to add those images to the UIImage array and try to animate those images in a sequence. Is it possible to load the images from Images.xcassets into Array? Or is it better to use SVG images for animation?
To get single image I tried the following:
UIImage *image = [UIImage imageNamed:#"FolderName"];
But I guess this needs to be modified as an Image array.
I guess this might help you
UIImageView *imageView = [UIImageView.alloc initWithFrame:self.view.bounds];
[self.view addSubview:imageView];
NSMutableArray *images = NSMutableArray.array;
NSInteger imageCount = 24;
NSString *imagePrefix = #"imageName_";
for(int i = 0; i<=imageCount; i++){
NSString *imageName = [NSString stringWithFormat:#"%#%d",imagePrefix, i];
UIImage *image = [UIImage imageNamed:imageName];
[images addObject:image];
}
imageView.animationImages = images;
imageView.animationRepeatCount = 1;
imageView.animationDuration = 3.0;
[imageView startAnimating];
I am trying to create an app like this:
(source: topmobiletrends.com)
where each of the views show an image for every in a photo in a JSON array.
I have successfully set and downloaded the array of images and set them in a UIImageView with with NSURLRequest and SDWebImage.
I created a UIView with an image view inside to test the code in my ViewController(Storyboard), everything works fine. However, when I try to create a UIView to loop programmatically, it shows up blank, with no ImageView. I'm not sure what I'm doing wrong.
Here is my code for my ViewController.m
for (NSObject *photo in photos) {
UIView *dView = [[UIView alloc]initWithFrame:CGRectMake(160,250,258,229)];
dView.backgroundColor = [UIColor whiteColor];
dispatch_async(dispatch_get_main_queue(),^{
UIImage *image = [UIImage imageWithData:data];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
myImage.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:imageURL]];
//Get image from url
[self.imageView setImageWithURL:imageURL];
[self.myImage addSubview:imageView];
priceLabel.text = [[[jsonDictionary objectForKey:#"site"] objectAtIndex:index] objectForKey:#"price"];
[imageView addSubview:dView];
});
}
}];
[task resume];
}
you are adding dView as subview for your image view may be it is [dView addSubview:imageView];
try this. the main issue is you are not setting frame for image view
for (NSObject *photo in photos) {
//UIView *dView = [[UIView alloc]initWithFrame:CGRectMake(160,250,258,229)];
//dView.backgroundColor = [UIColor whiteColor];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(160,250,258,229)];
[self.myImage addSubview:imageView];
priceLabel.text = [[[jsonDictionary objectForKey:#"site"] objectAtIndex:index] objectForKey:#"price"];
//[imageView addSubview:dView];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"URL"]];
dispatch_async(dispatch_get_main_queue(), ^{
if (imgData) {
[imageView setImage:[UIImage imageWithData:imgData]];
}
});
});
}
I wish to implement caching feature for an image in iOS.
I wish to create a sample app for that, just for my understanding.
Here is what I want to do:
Get a high resolution image from internet and cache it, display it.
Now next time when this ViewController loads up, the image should be loaded from cache and not from internet.
I know how to cache an image using SDWebImage framework. I wish to try it with NSCache.
How can I implement it using NSCache? Examples are welcomed.
EDITED :
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
NSCache *cache = [self imageCache];
NSURL *url = [NSURL URLWithString:#"http://i1.ytimg.com/vi/YbT0xy_Jai0/maxresdefault.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [[UIImage alloc] initWithData:data];
NSString *imagePath = #"http://i1.ytimg.com/vi/YbT0xy_Jai0/maxresdefault.jpg";
// UIImage *image;
if (!(image = [cache objectForKey:imagePath])) { // always goes inside condition
// Cache miss, recreate image
image = [[UIImage alloc] initWithData:data];
if (image) { // Insert image in cache
[cache setObject:image forKey:imagePath]; // cache is always nil
}
}
_imgCache.image = image;
You can add image to cache using and Id:
[imageCache setObject:image forKey:#"myImage"];
Later you can retreive the image by using:
UIImage *image = [imageCache objectForKey:#"myImage"];
Entire flow will be like:
UIImage *image = [imageCache objectForKey:#"myImage"];
if (!image)
{
// download image
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:yourURL]];
if (imageData)
{
// Set image to cache
[imageCache setObject: [UIImage imageWithData:imageData] forKey:#"myImage"];
dispatch_async(dispatch_get_main_queue(), ^{
[yourImageView setImage:[UIImage imageWithData:imageData]];
});
}
});
}
else
{
// Use image from cache
[yourImageView setImage:image];
}
Refer the sample code to load image asynchronously and image caching,
https://developer.apple.com/library/ios/samplecode/LazyTableImages/Introduction/Intro.html
I use the following code to create borders around images. I loop through the following multiple times to create thumbnail images with borders that are then placed in a UICollectionView.
The problem seems to be that every time I reload the UICollectionView the images are not being released from memory and it seems to build up to the point where it crashes. I don't think it is the UICollectionView code because If I run it with images that don't require a border I don't get any issues.
- (UIImage *)applyFrame:(UIImage *)image selectedFrame:(NSString *)selectedFrame {
UIImage *frame;
NSLog(#"Image Size For Frames: %f, %f",image.size.width,image.size.height);
if(image.size.width == image.size.height){
frame = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%#-Square.png",selectedFrame] ofType:nil]];
}
if(image.size.width > image.size.height){
frame = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%#.png",selectedFrame] ofType:nil]];
}
if(image.size.width < image.size.height){
frame = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%#.png",selectedFrame] ofType:nil]];
frame = [self rotateUIImage:frame clockwise:true];
}
GPUImageAlphaBlendFilter *blendFilter = [[GPUImageAlphaBlendFilter alloc] init];
GPUImagePicture *imageToProcess = [[GPUImagePicture alloc] initWithImage:image];
GPUImagePicture *border = [[GPUImagePicture alloc] initWithImage:frame];
blendFilter.mix = 1.0f;
[imageToProcess addTarget:blendFilter];
[border processImage];
[border addTarget:blendFilter];
[imageToProcess processImage];
return [blendFilter imageFromCurrentlyProcessedOutput];
}
- (UIImage*)rotateUIImage:(UIImage*)sourceImage clockwise:(BOOL)clockwise {
CGSize size = sourceImage.size;
UIGraphicsBeginImageContext(CGSizeMake(size.height, size.width));
[[UIImage imageWithCGImage:[sourceImage CGImage] scale:1.0 orientation:clockwise ? UIImageOrientationRight : UIImageOrientationLeft] drawInRect:CGRectMake(0,0,size.height ,size.width)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
UIImage imageWithContentsOfFile: returns an autorelease object, which will be released only when the app returns to the current run loop. So, might it be that you app loops for a long time executing this code? In this case, the autorelease objects might accumulate, and increase the heap usage.
If so, you could try to insert into the body of the responsible loop an autorelease block:
#autoreleasepool {
...your statements
}
I have the following code to play animation with images:
-(void)playPopAnimation:(void (^)(void))completion{
__block NSMutableArray *images;
float animationDuration = 1.0f;
images = [[NSMutableArray alloc] initWithCapacity:26];
for(int i=1; i<26; i++){
NSString *fileName = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"bulut_pop%d",i] ofType:#"png"];
UIImage *image = [UIImage imageWithContentsOfFile:fileName];
//UIImage* image = [UIImage imageNamed:[NSString stringWithFormat:#"bulut_pop%d.png",i]];
[images addObject:image];
}
[Helper playSound:#"button_pop"];
UIImageView* imageView = [[UIImageView alloc] initWithFrame:self.itemImage.frame];
imageView.animationImages = images;
imageView.animationDuration = animationDuration;
imageView.animationRepeatCount = 1; // 0 = nonStop repeat
[self addSubview:imageView];
[imageView startAnimating];
self.imageButton.userInteractionEnabled = NO;
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, animationDuration * NSEC_PER_SEC), dispatch_get_current_queue(), ^{
//[self.delegate myItemCell:self cellDidTappedFor:[self item]];
self.imageButton.userInteractionEnabled = YES;
images = nil;
});
Each time I call this function, memory increases by 10 MB. What is the good way to play animated image views?
Each time you call this method, you add a new image view (with its array of images) to your view. You should refactor your code so that the creation of the array and imageView are inside an if clause testing whether imageView is nil, so that part only runs the first time the method is called (and make imageView a property).