Custom Image Rotation? - ios

How can I rotate these images clockwise? When they load they are on their side for some reason.
//load the image
API* api = [API sharedInstance];//afnetworking call
int IdPhoto = [[data objectForKey:#"IdPhoto"] intValue];
NSURL* imageURL = [api urlForImageWithId:[NSNumber numberWithInt: IdPhoto] isThumb:YES];
AFImageRequestOperation* imageOperation = [AFImageRequestOperation imageRequestOperationWithRequest: [NSURLRequest requestWithURL:imageURL] success:^(UIImage *image) {
//create an image view, add it to the view
UIImageView* thumbView = [[UIImageView alloc] initWithImage: image];
thumbView.frame = CGRectMake(0,0,90,90);//thumbsize of image 180 is width and size 0 is spacing coordinates x,y
thumbView.contentMode = UIViewContentModeScaleAspectFit;
[self insertSubview: thumbView belowSubview: caption];
}];
NSOperationQueue* queue = [[NSOperationQueue alloc] init];
[queue addOperation:imageOperation];
}
return self;
}
#end

I'd look at just rotating the imageView like this:
thumbView.transform=CGAffineTransformMakeRotation(M_PI*1.5); //or perhaps M_PI*0.5 for a quarter turn the other direction...
because its much easier, altering the orientation on the image itself requires drawing it to a context somewhere in order to pull out a fresh data representation.

Related

How to zoom and swipe multiple images coming from webservise in objective c

1) In my application, I want to zoom and pinch an image. In xib file, there is a imageView inside a scrollview.Page control is used for swiping images. For a single image it gets zoomed, but for multiple images(coming from web service) it is not getting swipe and zoom.
In setMultipleImages method, images are not getting zoomed and swiped, while if image is single it gets zoom properly.
2) In UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]]]; line code, want to replace uiimage with uiimageview. How can I do it?
My code is:
-(void)setMultipleImages{
for (int i = 0; i < [imageMArray count]; i++){
NSString *logoName;
NSArray *imageNameArray = [[imageMArray objectAtIndex:i] componentsSeparatedByString:#"/"];
logoName = [[NSString alloc]initWithFormat:#"%#",[imageNameArray lastObject]];
if (![[AppDelegateHelper getInstance] fileExist:logoName])
{
NSString *imageURL = [[NSString alloc]initWithFormat:#"%#%#",[UrlBuilder getWebsiteUrl],[imageMArray objectAtIndex:i]];
[self startProcessing];
UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]]];
[activityIndicator stopAnimating];
DebugLog(#"%f,%f",image.size.width,image.size.height);
NSArray *docDir = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cacheDirectory = [docDir objectAtIndex:0];
DebugLog(#"saving png");
NSString *pngFilePath = [NSString stringWithFormat:#"%#/%#",cacheDirectory,[imageNameArray lastObject]];
NSData *data1 = [NSData dataWithData:UIImageJPEGRepresentation(image, 1.0f)];
[data1 writeToFile:pngFilePath atomically:YES];
}
}
[self loadImageData];
}
-(void)loadImageData
{
int X =0;
for (int s=0; s<imageMArray.count; s++) {
NSString *logoName;
NSArray *imageNameArray = [[imageMArray objectAtIndex:s] componentsSeparatedByString:#"/"];
logoName = [[NSString alloc]initWithFormat:#"%#",[imageNameArray lastObject]];
if([[AppDelegateHelper getInstance] loadImage:logoName] != nil)
{
// UIImageView *imageView = [[UIImageView alloc] initWithFrame: CGRectMake(X, 0, scrollView.frame.size.width, 300)] ;
[imageView setImage:[[AppDelegateHelper getInstance] loadImage:logoName]];
imageView.contentMode = UIViewContentModeScaleAspectFit;
[scrollView addSubview: imageView];
X = X + imageView.frame.size.width;
}
else
{
//UIImageView *imageView = [[UIImageView alloc] initWithFrame: CGRectMake(X, 0, scrollView.frame.size.width, 300)] ;
[imageView setImage:[UIImage imageNamed:#"NoImage.png"]];
imageView.contentMode = UIViewContentModeScaleAspectFit;
[scrollView addSubview: imageView];
X = X + imageView.frame.size.width;
}
}
self.pageControl.numberOfPages = [imageMArray count];
scrollView.contentSize = CGSizeMake(X,scrollView.frame.size.height);
lblCount.text = [[NSString alloc]initWithFormat:#"1 sur %lu",(unsigned long)imageMArray.count];
}
Add all your images to imageview. Then apply pinchguesture to images view for zoom effect.
Pinch Guesture:
UIPinchGestureRecognizer *imageviewguesture=[[UIPinchGestureRecognizer alloc]initWithTarget:self action:#selector(ImageViewPinchGuesture:)];
add pinch guesture to your image view:
[YourImageView addGestureRecognizer:imageviewguesture];
Make your selector method:
-(void)ImageViewPinchGuesture:(UIPinchGestureRecognizer *)pinGuestureregonizer{
pinGuestureregonizer.view.transform = CGAffineTransformScale(pinGuestureregonizer.view.transform, pinGuestureregonizer.scale, pinGuestureregonizer.scale);
pinGuestureregonizer.scale = 1;
}
In your .h file add this line
-(void)ImageViewPinchGuesture:(UIPinchGestureRecognizer *)pinGuestureregonizer;
To check effect in simulator Press Cmd+alt then press left mouse pad button and drag.
Hope this will Help. Don't forget to accept the answer if it helps you.

Setting subviews quicker than in viewDidLoad

Right now I'm allocating and initializing three UIImageViews that take up the entire screen and are stacked in the viewDidLoad method. Its actually taking some time to do this. Is there a way to do this automatically so the view just has them before its even loaded? like an init method that would speed this up?
- (void)viewDidLoad {
[super viewDidLoad];
self.mySubviews = [[NSMutableArray alloc] init];
self.videoCounterTags = [[NSMutableArray alloc] init];
int c = (int)[self.scenes count];
c--;
NSLog(#"int c = %d", c);
self.myCounter = [NSNumber numberWithInt:c];
for (int i=0; i<=c; i++) {
//create imageView
UIImageView *imageView =[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
[imageView setUserInteractionEnabled:YES]; // <--- This is very important
imageView.tag = i; // <--- Add tag to track this subview in the view stack
[self.view addSubview:imageView];
NSLog(#"added image view %d", i);
//get scene object
PFObject *sceneObject = self.scenes[i];
//get the PFFile and filetype
PFFile *file = [sceneObject objectForKey:#"file"];
NSString *fileType = [sceneObject objectForKey:#"fileType"];
//check the filetype
if ([fileType isEqual: #"image"])
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
//get image
NSURL *imageFileUrl = [[NSURL alloc] initWithString:file.url];
NSData *imageData = [NSData dataWithContentsOfURL:imageFileUrl];
dispatch_async(dispatch_get_main_queue(), ^{
imageView.image = [UIImage imageWithData:imageData];
});
});
}
//its a video
else
{
// the video player
NSURL *fileUrl = [NSURL URLWithString:file.url];
self.avPlayer = [AVPlayer playerWithURL:fileUrl];
self.avPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
self.avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:self.avPlayer];
//self.avPlayerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[self.avPlayer currentItem]];
CGRect screenRect = [[UIScreen mainScreen] bounds];
self.avPlayerLayer.frame = CGRectMake(0, 0, screenRect.size.width, screenRect.size.height);
[imageView.layer addSublayer:self.avPlayerLayer];
NSNumber *tag = [NSNumber numberWithInt:i+1];
NSLog(#"tag = %#", tag);
[self.videoCounterTags addObject:tag];
}
}
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(viewTapped:)];
// dummyScreen is just a see through view that sits on top of my image stack and holds my tap gesture recognizer
[self.view bringSubviewToFront:self.dummyScreen];
[self.dummyScreen addGestureRecognizer:tapGesture];
}
The problem is this line:
dispatch_async(dispatch_get_global_queue...
That moves you onto a background thread, and thus there is no telling when the code will be executed. Hence the delay.
If these are local files (i.e., the URL is the file URL of an image file in your app bundle), there is no need for any dispatch_async in your code. Remove all of that and do everything on the main thread. That way, it will happen as fast as possible.
If these are remote files (i.e., you have to do networking to get hold of them), then there's probably nothing you can do to speed things up; networking takes time, and viewDidLoad is just about as early as you can possibly be notified that it's time to get hold of the images.

Load remote server image in UIScrollView with NSOperatoinQueue

I want to load some "image" (In remote server) in a UIScrollView with NSOperatoinQueue. Because If I load it with normal NSURL, NSData or with NSMutableURLRequest it takes too much time to load for all the images. After that I show those images in UIButton. Here is my code:
- (void)viewDidLoad
{
[super viewDidLoad];
[self startAnimation:nil];
self.imageDownloadingQueue = [[NSOperationQueue alloc] init];
self.imageDownloadingQueue.maxConcurrentOperationCount = 4; // many servers limit how many concurrent requests they'll accept from a device, so make sure to set this accordingly
self.imageCache = [[NSCache alloc] init];
[self performSelector:#selector(loadData) withObject:nil afterDelay:0.5];
}
-(void) loadData
{
adParser = [[AdParser alloc] loadXMLByURL:getXMLURL];
adsListArray = [adParser ads];
displayArray = [[NSMutableArray alloc] init];
for (AdInfo *adInfo1 in adsListArray)
{
AdInfo *adInfo2 = [[AdInfo alloc] init];
[adInfo2 setBannerIconURL:adInfo1.bannerIconURL];
[adInfo2 setBannerIconLink:adInfo1.bannerIconLink];
[displayArray addObject:adInfo2];
}
[self loadScrollView];
[activityIndicator stopAnimating];
}
-(void) loadScrollView
{
[self.scrollView setScrollEnabled:YES];
[self.scrollView setContentSize:CGSizeMake([displayArray count] * ScrollerWidth, ScrollerHight)];
for (int i = 0; i < [displayArray count]; i++)
{
adButtonOutLet = [[UIButton alloc] initWithFrame:CGRectMake(i*320, 0, ButtonWidth, ButtonHight)];
currentAd = [displayArray objectAtIndex:i];
NSString *imageUrlString = [currentAd bannerIconURL];
UIImage *cachedImage = [self.imageCache objectForKey:imageUrlString];
if (cachedImage)
{
[adButtonOutLet setImage:cachedImage forState:UIControlStateNormal];
}
else
{
[self.imageDownloadingQueue addOperationWithBlock:^
{
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrlString]];
UIImage *image = nil;
image = [UIImage imageWithData:imageData];
// add the image to your cache
[self.imageCache setObject:image forKey:imageUrlString];
// finally, update the user interface in the main queue
[[NSOperationQueue mainQueue] addOperationWithBlock:^
{
[adButtonOutLet setImage:image forState:UIControlStateNormal];
}];
}];
}
adButtonOutLet.userInteractionEnabled= YES;
[adButtonOutLet setTag:i];
[adButtonOutLet addTarget:self action:#selector(goToURL:) forControlEvents:UIControlEventTouchUpInside];
[self.scrollView addSubview:adButtonOutLet];
}
}
Can anyone tell me what's wrong with the above code? There is no problem of parsing or retrieving data from Remote server. I check it by NSLog. I think the NSOperationQueue have some problem, which I can't manage properly. Thanks in advance. If you needed more information, I will attach here.
Have a nice day.
Not sure if this is your problem or your solution, its hard to tell without testing myself.
Taken from RayWenderlich
addOperationWithBlock: if you have a simple operation that does not
need to be subclassed, you can create an operation using the block
API. If you want to reference any object from outside in the block,
remember that you should pass in a weak reference. Also, if you want
to do something that is related to the UI in the block, you must do it
on the main thread:
// Create a weak reference
__weak MyViewController *weakSelf = self;
// Add an operation as a block to a queue
[myQueue addOperationWithBlock: ^ {
NSURL *aURL = [NSURL URLWithString:#"http://www.somewhere.com/image.png"];
NSError *error = nil;
NSData *data = [NSData dataWithContentsOfURL:aURL options:nil error:&error];
UIImage *image = nil;
If (data)
image = [UIImage imageWithData:data];
// Update UI on the main thread.
[[NSOperationQueue mainQueue] addOperationWithBlock: ^ {
weakSelf.imageView.image = image;
}];
}];

Set Image of Custom UIView from ViewController

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]];
}
});
});
}

Memory Warning while playing animated image view

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).

Resources