iOS: How to flip image based on current orientation? - ios

I am trying to check the current orientation of an image and flip it to the opposite of what it currently is.
This code works if I only have 1 element on my screen, but as soon as i increase the array its a 50/50 chance of getting the orientation right.
-(IBAction)flipBtn:(id)sender
{
UIImage* flippedImage;
if(flipBtn.tag==FLIP_BUTTON_TAG)
{
UIImage* sourceImage1 = self.outletImageView.image;
flippedImage = [UIImage imageWithCGImage:sourceImage1.CGImage scale:1.0 orientation: UIImageOrientationUpMirrored];
flipBtn.tag = FLIP_VUTTON_TAG2;
}else{
UIImage* sourceImage1 = self.outletImageView.image;
flippedImage = [UIImage imageWithCGImage:sourceImage1.CGImage scale:1.0 orientation: UIImageOrientationUp];
flipBtn.tag = FLIP_BUTTON_TAG;
}
NSInteger index1 = [imgViewArray indexOfObject:self.outletImageView];
[imgViewArray removeObject:self.outletImageView];
self.outletImageView.image = flippedImage;
[imgViewArray insertObject:self.outletImageView atIndex:index1];
}

Instead of: [imgViewArray removeObject:self.outletImageView];
Write: [imgViewArray removeObjectAtIndex:index1];
And afterwards you need to check flippedImage.imageOrientation == UIImageOrientationUp to see if it's inverted or not and make the appropriate change.
You can verify which orientation the picture has by accessing the info dictionary [info objectForKey:#"Orientation"]
Here is a method that will return the new desired orientation based on your previous check (you'd pass flippedImage.imageOrientation as the argument):
- (UIImageOrientation)orientation:(int)orientation
{
UIImageOrientation newOrientation;
switch (orientation)
{
case 1:
newOrientation = UIImageOrientationUp;
break;
case 2:
newOrientation = UIImageOrientationUpMirrored;
break;
}
return newOrientation;
}

Related

iOS how can I make undo action for rotating, scaling and adding UIView to UIIMageView

I have a UIImageView and I can add new items (as a subview) to this UIImageView or I can move & rotate the items in UIImageView.
I'm try to make undo actions for this items, so my code;
Before each new actions I get the copy of UIImageView and store them in NSMutableArray
[self.lastActions addObject:[self getCopy]];
I get the same UIImageView with different memory address. (I'm not sure this is the right approach)
-(UIImageView *)getCopy{
NSData *archivedViewData = [NSKeyedArchiver archivedDataWithRootObject:self.imageView];
id clone = [NSKeyedUnarchiver unarchiveObjectWithData:archivedViewData];
return clone;
}
And when I make the undo;
-(IBAction)undoButtonClicked:(id)sender{
UIImageView *lastImageView = [self.lastActions lastObject];
[UIView animateWithDuration:0.1 animations:^{
self.imageView = lastImageView;
}];
[self.lastActions removeObject:lastImageView];
}
But it does not change the UIImageView on screen.
Any ideas for whats wrong on my code ?
I am try your above idea. Not able to get the output. this is another idea to achieve the same.
I am using image to reveal the image change on the same imageview "undo" operation. I have implemented like below method.
its working fine in my side.
I hope this will help us.
// Undo button action
-(IBAction)undoButtonClicked:(id)sender{
UIImage *lastImageView = lastImageView = (UIImage *)[lastActions lastObject];
if( [lastActions count]!=0) {
[UIView animateWithDuration:0.2 animations:^{
self.imageView.image = lastImageView;
}];
[lastActions removeObject:lastImageView];
}
}
// Copy the image from public variable self.imageview
-(IBAction)copyButton:(id)sender{
[lastActions addObject:self.imageView.image];
}
// Random Orientation change to rotate the image.
-(UIImageOrientation )randonImageOrientation {
int min = 0 ;
int max = 3;
UIImageOrientation ori;
int randomNumber = min + rand() % (max-min);
switch (randomNumber)
{
case 0 :
ori = UIImageOrientationDown;
break;
case 1:
ori = UIImageOrientationLeft;
break;
case 2:
ori = UIImageOrientationRight;
break;
case 3:
ori = UIImageOrientationUp;
break;
default :
ori = UIImageOrientationUp;
break;
}
return ori;
}
// below method using to rotate the image
-(UIImage *)imageOrientation :(UIImageOrientation)imageOri image:(UIImage *)oriImage {
UIImage * LandscapeImage = oriImage;
UIImage * PortraitImage = [[UIImage alloc] initWithCGImage: LandscapeImage.CGImage
scale: 0.5
orientation: imageOri];
return PortraitImage;
}

Background Image setup issue (GHWalkThrough library on github)

this is a walkthrough open library on github that I want to use in my app.
https://github.com/GnosisHub/GHWalkThrough
there is a method to set up bg view:
- (UIImage*) bgImageforPage:(NSInteger)index
{
UIImage* image = [UIImage imageNamed:#"bgimage"];
return image;
}
And I wanted to add set different image for each index, so i did this:
- (UIImage*) bgImageforPage:(NSInteger)index {
UIImage* image;
if (index == 0) {
image = [UIImage imageNamed:#"screen 1"];
} else if (index == 1) {
image = [UIImage imageNamed:#"screen 2"];
} else if (index == 2) {
image = [UIImage imageNamed:#"screen 3"];
} else if (index == 3) {
image = [UIImage imageNamed:#"screen 4"];
}
return image;
}
Result:
whenever the view is loaded there is a clear bg, and if I swipe left to index 1 I get screen 1 > and if I swipe left for index 2, 3 & 4 the bg stays screen 1...
Can someone see what is wrong here?
i think you have minor mistak from code.
- (UIImage*) bgImageforPage:(NSInteger)index
{
NSString* imageName =[NSString stringWithFormat:#"bg_0%ld.jpg", index+1]; // you have manually add name but not increment index
UIImage* image = [UIImage imageNamed:imageName];
return image;
}
if you can't use bottom code & use upper code you got your result or same as use bottom code & use upper code then also you got same result.
- (UIImage*) bgImageforPage:(NSInteger)index
{
NSString* imageName =[NSString stringWithFormat:#"bg_0%ld.jpg", index+1];
UIImage* image;// = [UIImage imageNamed:imageName];
if (index == 0) {
image = [UIImage imageNamed:imageName];
} else if (index == 1) {
image = [UIImage imageNamed:imageName];
} else if (index == 2) {
image = [UIImage imageNamed:imageName];
} else if (index == 3) {
image = [UIImage imageNamed:imageName];
}
return image;
}
Please add image name in your app image folder like below.
(Note: your image name set below as in your project.)
Example Image Name :-
your condition wise you got new index but not getting images but when you set images name like same as upper images name & you got your images as index wise.
You don't seem to update index, which means it stays at 0.
If it stays at 0, the image will always be "screen 1".

MKAnnotationView image orientation

I have a MKMapView in which I can have multiple ARDVenueAnnotationView (subclass of MKAnnotationView) with a custom image at same coordinates. Thus, these annotations overlap. What I have done for this, is to change the anchorPoint of the annotation view's layer. This is working as image below (4 centered annotations have the same coordinates) :
Besides, I would like the annotations to change their image orientation so the little image tail points to the coordinate (don't mind the annotations order) :
Here comes my issue, when I setImage: on my annotation view, constructing this image with + (UIImage *)imageWithCGImage:scale:orientation:, the orientation does not change. Here is my code that update the image :
- (void)updateImage
{
UIImage *selectedImage = [UIImage imageNamed:#"redPin"];
if (!self.isCluster && self.selected) {
selectedImage = [UIImage imageNamed:#"whitePin"];
}
UIImageOrientation orientation;
switch (self.anchorCorner) {
case ARDVenueAnnotationAnchorCornerBottomLeft:
orientation = UIImageOrientationUpMirrored;
break;
case ARDVenueAnnotationAnchorCornerTopLeft:
orientation = UIImageOrientationDown;
break;
case ARDVenueAnnotationAnchorCornerTopRight:
orientation = UIImageOrientationDownMirrored;
break;
default:
orientation = UIImageOrientationUp;
break;
}
UIImage *image = [[UIImage alloc] initWithCGImage:selectedImage.CGImage scale:selectedImage.scale orientation:orientation];
[self setImage:image];
}
Where anchorCorner is the property to set when I want the annotation view to shift for the image little tail to points to the coordinates.
This method never changes the image orientation (default image has the tail at bottom right) and it keeps rendering as first picture above.
When I add an UIImageView as subview of my annotation view, it shows the good image orientation (as shown in the second picture).
My questions :
Why setImage: does not consider the image orientation ? Or maybe I am doing something wrong...
How can I achieve this without adding UIImageView as subview ? after all, image property is here for a reason
Try creating an image with the original image with the code:
static inline double radians (double degrees) {return degrees * M_PI/180;}
-(UIImage*) image :(UIImage*) src withOrientation: (UIImageOrientation) orientation
{
UIGraphicsBeginImageContext(src.size);
CGContextRef context = UIGraphicsGetCurrentContext();
if (orientation == UIImageOrientationRight) {
CGContextRotateCTM (context, radians(90));
} else if (orientation == UIImageOrientationLeft) {
CGContextRotateCTM (context, radians(-90));
} else if (orientation == UIImageOrientationDown) {
// NOTHING
} else if (orientation == UIImageOrientationUp) {
CGContextRotateCTM (context, radians(90));
}
[src drawAtPoint:CGPointMake(0, 0)];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
You may also need to flip the image so use this code:
UIImage* flippedImage = [UIImage imageWithCGImage:image.CGImage
scale:image.scale
orientation:UIImageOrientationUpMirrored];

Image auto-rotates after using CIFilter

I am writing an app that lets users take a picture and then edit it. I am working on implementing tools with UISliders for brightness/contrast/saturation and am using the Core Image Filter class to do so. When I open the app, I can take a picture and display it correctly. However, if I choose to edit a picture, and then use any of the described slider tools, the image will rotate counterclockwise 90 degrees. Here's the code in question:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.navigationItem.hidesBackButton = YES; //hide default nav
//get image to display
DBConnector *dbconnector = [[DBConnector alloc] init];
album.moments = [dbconnector getMomentsForAlbum:album.title];
Moment *mmt = [album.moments firstObject];
_imageView.image = [mmt.moment firstObject];
CGImageRef aCGImage = _imageView.image.CGImage;
CIImage *aCIImage = [CIImage imageWithCGImage:aCGImage];
_editor = [CIFilter filterWithName:#"CIColorControls" keysAndValues:#"inputImage", aCIImage, nil];
_context = [CIContext contextWithOptions: nil];
[self startEditControllerFromViewController:self];
}
//cancel and finish buttons
- (BOOL) startEditControllerFromViewController: (UIViewController*) controller {
[_cancelEdit addTarget:self action:#selector(cancelEdit:) forControlEvents:UIControlEventTouchUpInside];
[_finishEdit addTarget:self action:#selector(finishEdit:) forControlEvents:UIControlEventTouchUpInside];
return YES;
}
//adjust brightness
- (IBAction)brightnessSlider:(UISlider *)sender {
[_editor setValue:[NSNumber numberWithFloat:_brightnessSlider.value] forKey: #"inputBrightness"];
CGImageRef cgiimg = [_context createCGImage:_editor.outputImage fromRect:_editor.outputImage.extent];
_imageView.image = [UIImage imageWithCGImage: cgiimg];
CGImageRelease(cgiimg);
}
I believe that the problem stems from the brightnessSlider method, based on breakpoints that I've placed. Is there a way to stop the auto-rotating of my photo? If not, how can I rotate it back to the normal orientation?
Mere minutes after posting, I figured out the answer to my own question. Go figure. Anyway, I simply changed the slider method to the following:
- (IBAction)brightnessSlider:(UISlider *)sender {
[_editor setValue:[NSNumber numberWithFloat:_brightnessSlider.value] forKey: #"inputBrightness"];
CGImageRef cgiimg = [_context createCGImage:_editor.outputImage fromRect:_editor.outputImage.extent];
UIImageOrientation originalOrientation = _imageView.image.imageOrientation;
CGFloat originalScale = _imageView.image.scale;
_imageView.image = [UIImage imageWithCGImage: cgiimg scale:originalScale orientation:originalOrientation];
CGImageRelease(cgiimg);
}
This simply records the original orientation and scale of the image, and re-sets them when the data is converted back to a UIImage. Hope this helps someone else!

Ios image collision with one imageview

I am making an app that has 2 UIImageViews but in each image view the image changes 3 times. How can I make it so that if image A collides with image B or C action happens but not with image A and so on. Here is the code for the image changing
ImageView Changing 1
This is a random change
Trap.center = CGPointMake(350,220);
Trap1 = rand() %3;
switch (Trap1) {
case 0:
Trap.image = [UIImage imageNamed:#"Image1.png"];
break;
case 1:
Trap.image = [UIImage imageNamed:#"Image2.png"];
break;
case 2:
Trap.image = [UIImage imageNamed:#"Image3.png"];
break;
default:
break;
}
ImageView Changing 2
This is set with a swipe and is copied for the other 2 changes.
-(IBAction)Change3:(id)sender{
UIImage *img = [UIImage imageNamed:#"Image4.tif"];
[Change3 setImage:img];
}
You can add a tag to your Trap object. Compare the tags and if they are different, do something.
Set tag:
switch (Trap1) {
case 0:
Trap.image = [UIImage imageNamed:#"Image1.png"];
Trap.tag = 1;
break;
case 1:
Trap.image = [UIImage imageNamed:#"Image2.png"];
Trap.tag = 2;
break;
case 2:
Trap.image = [UIImage imageNamed:#"Image3.png"];
Trap.tag = 3;
break;
default:
break;
}
Compare tags
If (trap1.tag != trap2.tag){
//Do something
}

Resources