Stop a sprite accurately at destination using vectors - graphics

I want my sprite to move to a precise pixel location. I use the following code in the update method to move my sprite (kPlayerSpeed = 60.0f):
if (ccpDistance(self.position, requestedPosition) < kPlayerSpeed) {
[self changeState:kStateWalking];
return;
}
switch (self.characterState) {
case kStateWalkingUp:
self.position = ccp(self.position.x, self.position.y + kPlayerSpeed * deltaTime);
break;
case kStateWalkingDown:
self.position = ccp(self.position.x, self.position.y - kPlayerSpeed * deltaTime);
break;
case kStateWalkingLeft:
self.position = ccp(self.position.x - kPlayerSpeed * deltaTime, self.position.y);
break;
case kStateWalkingRight:
self.position = ccp(self.position.x + kPlayerSpeed * deltaTime, self.position.y);
break;
case kStateIdle:
break;
default:
break;
if (ccpDistance(self.position, requestedPosition) < kPlayerSpeed)
With this code the player stops near but not exactly on the spot.

I would do something along these lines. havent tested it though, im writing from my gfs pc.
CGPoint velocity = CGPointZero;
CGPoint delta = ccpSubstract(requestedPosition, self.position);
switch (self.characterState) {
case kStateWalkingUp:
velocity= ccp(0, kPlayerSpeed * deltaTime);
break;
case kStateWalkingDown:
velocity = ccp(0,-kPlayerSpeed * deltaTime);
break;
case kStateWalkingLeft:
velocity= ccp(-kPlayerSpeed * deltaTime, 0);
break;
case kStateWalkingRight:
velocity= ccp(kPlayerSpeed * deltaTime, 0);
break;
case kStateIdle:
break;
default:
break;
}
CGPoint signsVelocity = ccpNormalize(velocity);
CGPoint absVelocity = ccp( MIN( fabsf(velocity.x), fabsf(delta.x)) , MIN(fabsf(velocity.y), fabsf(velocity.x) );
self.position = ccpAdd(self.position, ccpMult(absVelocity, signsVelocity) );

Andres, thanks for the reply.
I couldn't quite get your code to work, so using your lead I did a bit more research and came up with this...
float step = kPlayerSpeed * deltaTime;
float dist = ccpDistance(self.position, requestedPosition);
if (dist <= step) {
self.position = requestedPosition;
} else {
CGPoint vectorBetweenAB = ccpSub(self.position, requestedPosition);
CGPoint normVectorBetweenPositionAndEnd = ccpNormalize(vectorBetweenAB);
CGPoint movementVectorForThisFrame = ccpMult(normVectorBetweenPositionAndEnd, step);
if (self.position.x > movementVectorForThisFrame.x) {
movementVectorForThisFrame.x = -movementVectorForThisFrame.x;
}
if (self.position.y > movementVectorForThisFrame.y) {
movementVectorForThisFrame.y = -movementVectorForThisFrame.y;
}
self.position = ccpAdd(self.position, movementVectorForThisFrame);
}
Is there a better way to do it than this?
Thanks

Related

Rotating a label in Visual C++ 6

I am trying to rotate a label using a function but it is not working.
I only get a label without a rotation.
The label should be rotated along the point (x, y) which is the middle position
of the label (just=TX_JUST_CENTER).
The counter-clockwise rotation angle (=theta) is given as degrees.
I would appreciate any help on this. Thanks.
void do_labely(
HDC meta_dc,
SLATE_REC *slate_rec,
const DEFAULT_STYLE *styl,
double x,
double y,
unsigned char *the_str,
short just,
short style_idx,
short size,
short stylebits,
short color,
short v_just,
BOOL clip,
double theta)
{
LOGFONT lf;
HFONT font;
UINT align;
setup_logfont(meta_dc ,&styl[ style_idx ], size, &lf, slate_rec, stylebits);
font = CreateFontIndirect( &lf );
GetObject(font, sizeof(lf), &lf);
SelectObject( meta_dc,font );
switch (color) {
case WHITE:
SetTextColor( meta_dc,RGB( 0xFF,0xFF,0xFF ) );
break;
case RED:
SetTextColor( meta_dc,RGB( 0xFF,0x00,0x00 ) );
break;
case GREEN:
SetTextColor( meta_dc,RGB( 0x00,0xFF,0x00 ) );
break;
case BLUE:
SetTextColor( meta_dc,RGB( 0x00,0x00,0xFF ) );
break;
case BLACK:
// this is the default
SetTextColor( meta_dc,RGB( 0x00,0x00,0x00 ) );
break;
}
switch (just) {
case TX_JUST_LEFT:
// this is the default
align = TA_LEFT;
break;
case TX_JUST_CENTER:
align = TA_CENTER;
break;
case TX_JUST_RIGHT:
align = TA_RIGHT;
break;
}
switch (v_just) {
case TX_JUST_TOP:
// this is the default
align += TA_TOP;
break;
case TX_JUST_BASE:
align += TA_BASELINE;
break;
case TX_JUST_BOTTOM:
align += TA_BOTTOM;
break;
}
SetTextAlign(meta_dc, align);
SetGraphicsMode(meta_dc, GM_ADVANCED);
double rad = theta * PI/180;
XFORM xform;
xform.eM11 = cos(rad);
xform.eM12 = -sin(rad);
xform.eM21 = sin(rad);
xform.eM22 = cos(rad);
//Apply rotation
ModifyWorldTransform(meta_dc, &xform, MWT_LEFTMULTIPLY);
//Draw the text
int x1 = (int)( x * slate_rec->xscale );
int y1 = (int)( y * slate_rec->yscale);
TextOut(meta_dc, x1, y1, (char *)the_str, strlen((char *)the_str));
//Reset the world transform to original
SetWorldTransform(meta_dc, &xform);
SelectObject( meta_dc,GetStockObject(SYSTEM_FONT) );
DeleteObject(font);
}

Random text to fade

How do I get random text to fade, from text1 to text2?
My code is as follows:
-(IBAction)generateNumbers; {
int randomNumber = arc4random() % 1;
switch (randomNumber) {
case 0:
label.text = #"text1";
break;
case 1:
label.text = #"text2";
break;
default:
break;
}
}
-(IBAction)generateNumbers; {
int randomNumber = arc4random() % 2;
switch (randomNumber) {
case 0:
label.text = #"text1";
break;
case 1:
label.text = #"text2";
break;
default:
break;
}
}
For fadeIn/Out use this methods
- (void) setTextWithFade {
[label setAlpha:1];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(fadeDidStop)];
[lbl setAlpha:0];
[UIView commitAnimations];
}
- (void)fadeDidStop {
label.text = #"new text";
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1];
[lbl setAlpha:1];
[UIView commitAnimations];
}
call the first method when you are click the button like this:
[self setTextWithFade];

resize UIImage in table cell programmatically

how can i resize the UIImage in table cell
cell.imageView.layer.masksToBounds = YES;
cell.imageView.layer.cornerRadius = 5.0;
cell.imageView.frame=CGRectMake(0, 0, 20, 30);
cell.imageView.image =[UIImage imageNamed:#"Diseases.png"];
it is not working
Use this method, pass the size and image, and get the image then show in cell
+ (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
UIGraphicsBeginImageContext(newSize);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
You can also make your custom UITableViewCell, and design as you want to look it
This worked for me.
///////////////////////////////// TO RESIZE IMAGE //////////////////////////////////
////////// FIRST WRITE DESIRED SIZE AND CALL BELOW FINCTION ///////
CGSize newSize ;
newSize.width = 30;
newSize.height = 30;
UIImage *imgSelectedNew = [self imageWithImage:savedImage scaledToSize:newSize];
- (UIImage*)imageWithImage:(UIImage*)sourceImage scaledToSize:(CGSize)targetSize
{
//UIImage *sourceImage = sourceImage;//= self;
UIImage *newImage = nil;
CGSize imageSize = sourceImage.size;
CGFloat width = imageSize.width;
CGFloat height = imageSize.height;
CGFloat targetWidth = targetSize.width;
CGFloat targetHeight = targetSize.height;
CGFloat scaleFactor = 0.0;
CGFloat scaledWidth = targetWidth;
CGFloat scaledHeight = targetHeight;
CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
if (CGSizeEqualToSize(imageSize, targetSize) == NO) {
CGFloat widthFactor = targetWidth / width;
CGFloat heightFactor = targetHeight / height;
if (widthFactor < heightFactor)
scaleFactor = widthFactor;
else
scaleFactor = heightFactor;
scaledWidth = width * scaleFactor;
scaledHeight = height * scaleFactor;
// center the image
if (widthFactor < heightFactor) {
thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
} else if (widthFactor > heightFactor) {
thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
}
}
// this is actually the interesting part:
UIGraphicsBeginImageContext(targetSize);
CGRect thumbnailRect = CGRectZero;
thumbnailRect.origin = thumbnailPoint;
thumbnailRect.size.width = scaledWidth;
thumbnailRect.size.height = scaledHeight;
[sourceImage drawInRect:thumbnailRect];
newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
if(newImage == nil)
NSLog(#"could not scale image");
return newImage ;
}
well m also n indorian , Gud to see the other one !!! :)

cocos2d box2d scale sprite -> removechild (how?)

I am little slow in English, please do understand.
Here is my source code:
- (void)createBall:(CGPoint)touchedAt{
CGSize winSize = [CCDirector sharedDirector].winSize;
ball2 = [CCSprite spriteWithFile:#"Ball.png" rect:CGRectMake(0, 0, 54, 54)];
ball2.position = ccp(touchedAt.x,touchedAt.y);
[self addChild:ball2];
b2BodyDef ballBodyDef2;
ballBodyDef2.type = b2_dynamicBody;
ballBodyDef2.position.Set(touchedAt.x/PTM_RATIO, touchedAt.y/PTM_RATIO);
ballBodyDef2.userData = ball2;
b2Body *body2 = _world->CreateBody(&ballBodyDef2);
b2CircleShape circle;
circle.m_radius = 89.0/PTM_RATIO;//(arc4random()*26.0)/PTM_RATIO;
b2FixtureDef ballShapeDef2;
ballShapeDef2.shape = &circle;
ballShapeDef2.density = 1.0f;
ballShapeDef2.friction = 0.2f;
ballShapeDef2.restitution = 0.8f;
body2->CreateFixture(&ballShapeDef2);
}
-(void)createBall2
{
CGSize winSize = [CCDirector sharedDirector].winSize;
globalSprite = [CCSprite spriteWithFile:#"Ball.png"];
globalSprite.position = ccp(winSize.width/2 + globalSprite.contentSize.width, winSize.height/2);
[self addChild:globalSprite];
b2BodyDef ballBodyDef3;
ballBodyDef3.type = b2_dynamicBody;
ballBodyDef3.position.Set(100/PTM_RATIO, 100/PTM_RATIO);
ballBodyDef3.userData = globalSprite ;
b2Body *body3 = _world->CreateBody(&ballBodyDef3);
b2CircleShape circle;
circle.m_radius = 26.0/PTM_RATIO;//(arc4random()*26.0)/PTM_RATIO;
b2FixtureDef ballShapeDef3;
ballShapeDef3.shape = &circle;
ballShapeDef3.density = 1.0f;
ballShapeDef3.friction = 0.2f;
ballShapeDef3.restitution = 0.8f;
body3->CreateFixture(&ballShapeDef3);
}
// initialize your instance here
-(id) init
{
if( (self=[super init])) {
// enable touch
// enable accelerometer
CGSize winSize = [CCDirector sharedDirector].winSize;
self.isAccelerometerEnabled = YES;
self.isTouchEnabled = YES;
// Create sprite and add it to the layer
// Create a world
b2Vec2 gravity = b2Vec2(0.0f, 0.0f);
bool doSleep = true;
_world = new b2World(gravity, doSleep);
// Create edges around the entire screen
b2BodyDef groundBodyDef;
groundBodyDef.position.Set(0,0);
b2Body *groundBody = _world->CreateBody(&groundBodyDef);
b2PolygonShape groundBox;
b2FixtureDef boxShapeDef;
boxShapeDef.shape = &groundBox;
groundBox.SetAsEdge(b2Vec2(0,0), b2Vec2(winSize.width/PTM_RATIO, 0));
groundBody->CreateFixture(&boxShapeDef);
groundBox.SetAsEdge(b2Vec2(0,0), b2Vec2(0, winSize.height/PTM_RATIO));
groundBody->CreateFixture(&boxShapeDef);
groundBox.SetAsEdge(b2Vec2(0, winSize.height/PTM_RATIO), b2Vec2(winSize.width/PTM_RATIO, winSize.height/PTM_RATIO));
groundBody->CreateFixture(&boxShapeDef);
groundBox.SetAsEdge(b2Vec2(winSize.width/PTM_RATIO, winSize.height/PTM_RATIO), b2Vec2(winSize.width/PTM_RATIO, 0));
groundBody->CreateFixture(&boxShapeDef);
// Create ball body and shape
[self schedule:#selector(tick:)];
//[self schedule:#selector(gameLogic:) interval:1.0];
[self createBall2];
}
return self;
}
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
// Choose one of the touches to work with
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
[self createBall:location];
}
- (void)tick:(ccTime) dt {
_world->Step(dt, 10, 10);
for(b2Body *b = _world->GetBodyList(); b; b=b->GetNext()) {
if (b->GetUserData() != NULL) {
CCSprite *ballData = (CCSprite *)b->GetUserData();
ballData.position = ccp(b->GetPosition().x * PTM_RATIO,
b->GetPosition().y * PTM_RATIO);
ballData.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
}
}
}
I want to
touch -> sprite create(circle) -> sprite scale -> sprite remove
but
- (void)tick:(ccTime) dt <---------- this is simulator turn off!
I want to way
Try this :
world->DestroyBody(sprite);

iOS 4 Image Oriented Incorrectly When Posted To Server [duplicate]

I am testing my iPhone application on an iOS 3.1.3 iPhone. I am selecting/capturing an image using a UIImagePickerController:
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
[imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
[imagePicker setDelegate:self];
[self.navigationController presentModalViewController:imagePicker animated:YES];
[imagePicker release];
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
self.image = [info objectForKey:UIImagePickerControllerOriginalImage];
imageView.image = self.image;
[self.navigationController dismissModalViewControllerAnimated:YES];
submitButton.enabled = YES;
}
I then at some point send it to my web server using the ASI classes:
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:#"http://example.com/myscript.php"]];
[request setDelegate:self];
[request setStringEncoding:NSUTF8StringEncoding];
[request setShouldContinueWhenAppEntersBackground:YES];
//other post keys/values
[request setFile:UIImageJPEGRepresentation(self.image, 100.0f) withFileName:[NSString stringWithFormat:#"%d.jpg", [[NSDate date] timeIntervalSinceNow]] andContentType:#"image/jpg" forKey:#"imageFile"];
[request startAsynchronous];
the problem:
when i take a picture with the iphone while holding it landscape, the image gets uploaded to the server and it viewed like you would expect. when taking a picture holding the phone in portrait, the image is uploaded and viewed as it had been rotated 90 degrees.
my application is set to only work in portrait modes(upsidedown and regular).
How can i make the image always show the correct orientation after uploading?
the image appears to be correct as displayed in an UIImageView(directly after taking the picture), but viewing on the server says otherwise.
A UIImage has a property imageOrientation, which instructs the UIImageView and other UIImage consumers to rotate the raw image data. There's a good chance that this flag is being saved to the exif data in the uploaded jpeg image, but the program you use to view it is not honoring that flag.
To rotate the UIImage to display properly when uploaded, you can use a category like this:
UIImage+fixOrientation.h
#interface UIImage (fixOrientation)
- (UIImage *)fixOrientation;
#end
UIImage+fixOrientation.m
#implementation UIImage (fixOrientation)
- (UIImage *)fixOrientation {
// No-op if the orientation is already correct
if (self.imageOrientation == UIImageOrientationUp) return self;
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
CGAffineTransform transform = CGAffineTransformIdentity;
switch (self.imageOrientation) {
case UIImageOrientationDown:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height);
transform = CGAffineTransformRotate(transform, M_PI);
break;
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, 0);
transform = CGAffineTransformRotate(transform, M_PI_2);
break;
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, 0, self.size.height);
transform = CGAffineTransformRotate(transform, -M_PI_2);
break;
case UIImageOrientationUp:
case UIImageOrientationUpMirrored:
break;
}
switch (self.imageOrientation) {
case UIImageOrientationUpMirrored:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
case UIImageOrientationLeftMirrored:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, self.size.height, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
case UIImageOrientationUp:
case UIImageOrientationDown:
case UIImageOrientationLeft:
case UIImageOrientationRight:
break;
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height,
CGImageGetBitsPerComponent(self.CGImage), 0,
CGImageGetColorSpace(self.CGImage),
CGImageGetBitmapInfo(self.CGImage));
CGContextConcatCTM(ctx, transform);
switch (self.imageOrientation) {
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
// Grr...
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage);
break;
default:
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage);
break;
}
// And now we just create a new UIImage from the drawing context
CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
UIImage *img = [UIImage imageWithCGImage:cgimg];
CGContextRelease(ctx);
CGImageRelease(cgimg);
return img;
}
#end
I figured out a much simpler one:
- (UIImage *)normalizedImage {
if (self.imageOrientation == UIImageOrientationUp) return self;
UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
[self drawInRect:(CGRect){0, 0, self.size}];
UIImage *normalizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return normalizedImage;
}
BTW: #Anomie's code does not take scale into account, so will not work for 2x images.
Here is a Swift version of the answer by #an0:
func normalizedImage() -> UIImage {
if (self.imageOrientation == UIImageOrientation.Up) {
return self;
}
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale);
let rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
self.drawInRect(rect)
let normalizedImage : UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext();
return normalizedImage;
}
Also in a more general function:
func fixOrientation(img:UIImage) -> UIImage {
if (img.imageOrientation == UIImageOrientation.Up) {
return img;
}
UIGraphicsBeginImageContextWithOptions(img.size, false, img.scale);
let rect = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height)
img.drawInRect(rect)
let normalizedImage : UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext();
return normalizedImage;
}
Swift 3 version:
func fixOrientation(img: UIImage) -> UIImage {
if (img.imageOrientation == .up) {
return img
}
UIGraphicsBeginImageContextWithOptions(img.size, false, img.scale)
let rect = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height)
img.draw(in: rect)
let normalizedImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return normalizedImage
}
Solution for Swift 3.1 for orientation issue while capturing the image from Camera.
I have updated the solution given by jake and Metal Heart
UIImage extension
//MARK:- Image Orientation fix
extension UIImage {
func fixOrientation() -> UIImage {
// No-op if the orientation is already correct
if ( self.imageOrientation == UIImageOrientation.up ) {
return self;
}
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
var transform: CGAffineTransform = CGAffineTransform.identity
if ( self.imageOrientation == UIImageOrientation.down || self.imageOrientation == UIImageOrientation.downMirrored ) {
transform = transform.translatedBy(x: self.size.width, y: self.size.height)
transform = transform.rotated(by: CGFloat(Double.pi))
}
if ( self.imageOrientation == UIImageOrientation.left || self.imageOrientation == UIImageOrientation.leftMirrored ) {
transform = transform.translatedBy(x: self.size.width, y: 0)
transform = transform.rotated(by: CGFloat(Double.pi / 2.0))
}
if ( self.imageOrientation == UIImageOrientation.right || self.imageOrientation == UIImageOrientation.rightMirrored ) {
transform = transform.translatedBy(x: 0, y: self.size.height);
transform = transform.rotated(by: CGFloat(-Double.pi / 2.0));
}
if ( self.imageOrientation == UIImageOrientation.upMirrored || self.imageOrientation == UIImageOrientation.downMirrored ) {
transform = transform.translatedBy(x: self.size.width, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
}
if ( self.imageOrientation == UIImageOrientation.leftMirrored || self.imageOrientation == UIImageOrientation.rightMirrored ) {
transform = transform.translatedBy(x: self.size.height, y: 0);
transform = transform.scaledBy(x: -1, y: 1);
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
let ctx: CGContext = CGContext(data: nil, width: Int(self.size.width), height: Int(self.size.height),
bitsPerComponent: self.cgImage!.bitsPerComponent, bytesPerRow: 0,
space: self.cgImage!.colorSpace!,
bitmapInfo: self.cgImage!.bitmapInfo.rawValue)!;
ctx.concatenate(transform)
if ( self.imageOrientation == UIImageOrientation.left ||
self.imageOrientation == UIImageOrientation.leftMirrored ||
self.imageOrientation == UIImageOrientation.right ||
self.imageOrientation == UIImageOrientation.rightMirrored ) {
ctx.draw(self.cgImage!, in: CGRect(x: 0,y: 0,width: self.size.height,height: self.size.width))
} else {
ctx.draw(self.cgImage!, in: CGRect(x: 0,y: 0,width: self.size.width,height: self.size.height))
}
// And now we just create a new UIImage from the drawing context and return it
return UIImage(cgImage: ctx.makeImage()!)
}
}
Swift 2.0
//MARK:- Image Orientation fix
extension UIImage {
func fixOrientation() -> UIImage {
// No-op if the orientation is already correct
if ( self.imageOrientation == UIImageOrientation.Up ) {
return self;
}
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
var transform: CGAffineTransform = CGAffineTransformIdentity
if ( self.imageOrientation == UIImageOrientation.Down || self.imageOrientation == UIImageOrientation.DownMirrored ) {
transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
}
if ( self.imageOrientation == UIImageOrientation.Left || self.imageOrientation == UIImageOrientation.LeftMirrored ) {
transform = CGAffineTransformTranslate(transform, self.size.width, 0)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
}
if ( self.imageOrientation == UIImageOrientation.Right || self.imageOrientation == UIImageOrientation.RightMirrored ) {
transform = CGAffineTransformTranslate(transform, 0, self.size.height);
transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2));
}
if ( self.imageOrientation == UIImageOrientation.UpMirrored || self.imageOrientation == UIImageOrientation.DownMirrored ) {
transform = CGAffineTransformTranslate(transform, self.size.width, 0)
transform = CGAffineTransformScale(transform, -1, 1)
}
if ( self.imageOrientation == UIImageOrientation.LeftMirrored || self.imageOrientation == UIImageOrientation.RightMirrored ) {
transform = CGAffineTransformTranslate(transform, self.size.height, 0);
transform = CGAffineTransformScale(transform, -1, 1);
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
let ctx: CGContextRef = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height),
CGImageGetBitsPerComponent(self.CGImage), 0,
CGImageGetColorSpace(self.CGImage),
CGImageGetBitmapInfo(self.CGImage).rawValue)!;
CGContextConcatCTM(ctx, transform)
if ( self.imageOrientation == UIImageOrientation.Left ||
self.imageOrientation == UIImageOrientation.LeftMirrored ||
self.imageOrientation == UIImageOrientation.Right ||
self.imageOrientation == UIImageOrientation.RightMirrored ) {
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage)
} else {
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage)
}
// And now we just create a new UIImage from the drawing context and return it
return UIImage(CGImage: CGBitmapContextCreateImage(ctx)!)
}
}
Use of this UIImage Extension in your code:
let fixOrientationImage=chosenImage.fixOrientation()
place this in your delegate methods of image picker like this
Swift 3.1
//MARK: Image Picker Delegates
func imagePickerController(
_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : Any]){
let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
profileImg.contentMode = .scaleAspectFill
let fixOrientationImage=chosenImage.fixOrientation()
profileImg.image = fixOrientationImage
dismiss(animated: true, completion: nil)
}
Swift 2.0
//MARK: Image Picker Delegates
func imagePickerController(
picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : AnyObject])
{
let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
profileImg.contentMode = .ScaleAspectFill
**//Fix the image orientation**
let fixOrientationImage=chosenImage.fixOrientation()
profileImg.image = fixOrientationImage
dismissViewControllerAnimated(true, completion: nil)
}
Swift 4.x/5.0 version of #an0 's solution:
extension UIImage {
func upOrientationImage() -> UIImage? {
switch imageOrientation {
case .up:
return self
default:
UIGraphicsBeginImageContextWithOptions(size, false, scale)
draw(in: CGRect(origin: .zero, size: size))
let result = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return result
}
}
}
in swift ;)
UPDATE SWIFT 3.0 :D
func sFunc_imageFixOrientation(img:UIImage) -> UIImage {
// No-op if the orientation is already correct
if (img.imageOrientation == UIImageOrientation.up) {
return img;
}
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
var transform:CGAffineTransform = CGAffineTransform.identity
if (img.imageOrientation == UIImageOrientation.down
|| img.imageOrientation == UIImageOrientation.downMirrored) {
transform = transform.translatedBy(x: img.size.width, y: img.size.height)
transform = transform.rotated(by: CGFloat(M_PI))
}
if (img.imageOrientation == UIImageOrientation.left
|| img.imageOrientation == UIImageOrientation.leftMirrored) {
transform = transform.translatedBy(x: img.size.width, y: 0)
transform = transform.rotated(by: CGFloat(M_PI_2))
}
if (img.imageOrientation == UIImageOrientation.right
|| img.imageOrientation == UIImageOrientation.rightMirrored) {
transform = transform.translatedBy(x: 0, y: img.size.height);
transform = transform.rotated(by: CGFloat(-M_PI_2));
}
if (img.imageOrientation == UIImageOrientation.upMirrored
|| img.imageOrientation == UIImageOrientation.downMirrored) {
transform = transform.translatedBy(x: img.size.width, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
}
if (img.imageOrientation == UIImageOrientation.leftMirrored
|| img.imageOrientation == UIImageOrientation.rightMirrored) {
transform = transform.translatedBy(x: img.size.height, y: 0);
transform = transform.scaledBy(x: -1, y: 1);
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
let ctx:CGContext = CGContext(data: nil, width: Int(img.size.width), height: Int(img.size.height),
bitsPerComponent: img.cgImage!.bitsPerComponent, bytesPerRow: 0,
space: img.cgImage!.colorSpace!,
bitmapInfo: img.cgImage!.bitmapInfo.rawValue)!
ctx.concatenate(transform)
if (img.imageOrientation == UIImageOrientation.left
|| img.imageOrientation == UIImageOrientation.leftMirrored
|| img.imageOrientation == UIImageOrientation.right
|| img.imageOrientation == UIImageOrientation.rightMirrored
) {
ctx.draw(img.cgImage!, in: CGRect(x:0,y:0,width:img.size.height,height:img.size.width))
} else {
ctx.draw(img.cgImage!, in: CGRect(x:0,y:0,width:img.size.width,height:img.size.height))
}
// And now we just create a new UIImage from the drawing context
let cgimg:CGImage = ctx.makeImage()!
let imgEnd:UIImage = UIImage(cgImage: cgimg)
return imgEnd
}
I used this page when designing my app that takes pictures and I found that the following method will correct the orientation and use less memory and processor than previous answers:
CGImageRef cgRef = image.CGImage;
image = [[UIImage alloc] initWithCGImage:cgRef scale:1.0 orientation:UIImageOrientationUp];
This basically just rewraps the actual image data with a new orientation. I was using #an0's code but it makes a new image in memory which can be taxing on a 3264x2448 image that you might get from a camera.
If you enable editing, then the edited image (as opposed to the original) will be oriented as expected:
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.allowsEditing = YES;
// set delegate and present controller
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *photo = [info valueForKey:UIImagePickerControllerEditedImage];
// do whatever
}
Enabling editing allows the user to resize and move the image before tapping "Use Photo"
I achieve this by writing below a few lines of code
extension UIImage {
public func correctlyOrientedImage() -> UIImage {
guard imageOrientation != .up else { return self }
UIGraphicsBeginImageContextWithOptions(size, false, scale)
draw(in: CGRect(origin: .zero, size: size))
let normalizedImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return normalizedImage
}
}
This what I have found for fixing orientation issue
UIImage *initialImage = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
NSData *data = UIImagePNGRepresentation(self.initialImage);
UIImage *tempImage = [UIImage imageWithData:data];
UIImage *fixedOrientationImage = [UIImage imageWithCGImage:tempImage.CGImage
scale:initialImage.scale
orientation:self.initialImage.imageOrientation];
initialImage = fixedOrientationImage;
EDIT:
UIImage *initialImage = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
NSData *data = UIImagePNGRepresentation(self.initialImage);
initialImage = [UIImage imageWithCGImage:[UIImage imageWithData:data].CGImage
scale:initialImage.scale
orientation:self.initialImage.imageOrientation];
Here’s a solution that doesn’t change the colorspace of the original image. If you want to normalize the orientation of a grayscale image, you are out of luck with all solutions based on UIGraphicsBeginImageContextWithOptions because it creates a context in the RGB colorspace. Instead, you have to create a context with the same properties as the original image and draw:
extension UIImage {
static let rotatedOrentations: [UIImage.Orientation] = [.left, .leftMirrored, .right, .rightMirrored]
func normalizedImage() -> UIImage {
if imageOrientation == .up {
return self
}
let image = self.cgImage!
let swapOrientation = UIImage.rotatedOrentations.contains(imageOrientation)
let width = swapOrientation ? image.height : image.width
let height = swapOrientation ? image.width : image.height
let context = CGContext(data: nil, width: width, height: height, bitsPerComponent: image.bitsPerComponent, bytesPerRow: image.bytesPerRow, space: image.colorSpace!, bitmapInfo: image.bitmapInfo.rawValue)!
let flipVertical = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: CGFloat(height));
context.concatenate(flipVertical)
UIGraphicsPushContext(context)
self.draw(at: .zero)
UIGraphicsPopContext()
return UIImage(cgImage: context.makeImage()!)
}
}
Update for Swift 3.1 based on Sourabh Sharma's answer, with code clean up.
extension UIImage {
func fixedOrientation() -> UIImage {
if imageOrientation == .up { return self }
var transform:CGAffineTransform = .identity
switch imageOrientation {
case .down, .downMirrored:
transform = transform.translatedBy(x: size.width, y: size.height).rotated(by: .pi)
case .left, .leftMirrored:
transform = transform.translatedBy(x: size.width, y: 0).rotated(by: .pi/2)
case .right, .rightMirrored:
transform = transform.translatedBy(x: 0, y: size.height).rotated(by: -.pi/2)
default: break
}
switch imageOrientation {
case .upMirrored, .downMirrored:
transform = transform.translatedBy(x: size.width, y: 0).scaledBy(x: -1, y: 1)
case .leftMirrored, .rightMirrored:
transform = transform.translatedBy(x: size.height, y: 0).scaledBy(x: -1, y: 1)
default: break
}
let ctx = CGContext(data: nil, width: Int(size.width), height: Int(size.height),
bitsPerComponent: cgImage!.bitsPerComponent, bytesPerRow: 0,
space: cgImage!.colorSpace!, bitmapInfo: cgImage!.bitmapInfo.rawValue)!
ctx.concatenate(transform)
switch imageOrientation {
case .left, .leftMirrored, .right, .rightMirrored:
ctx.draw(cgImage!, in: CGRect(x: 0, y: 0, width: size.height,height: size.width))
default:
ctx.draw(cgImage!, in: CGRect(x: 0, y: 0, width: size.width,height: size.height))
}
return UIImage(cgImage: ctx.makeImage()!)
}
}
Picker delegate method example:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
guard let originalImage = info[UIImagePickerControllerOriginalImage] as? UIImage else { return }
let fixedImage = originalImage.fixedOrientation()
// do your work
}
Here's UIImage extension for swift:
extension UIImage {
func fixOrientation() -> UIImage {
// No-op if the orientation is already correct
if ( self.imageOrientation == UIImageOrientation.Up ) {
return self;
}
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
var transform: CGAffineTransform = CGAffineTransformIdentity
if ( self.imageOrientation == UIImageOrientation.Down || self.imageOrientation == UIImageOrientation.DownMirrored ) {
transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
}
if ( self.imageOrientation == UIImageOrientation.Left || self.imageOrientation == UIImageOrientation.LeftMirrored ) {
transform = CGAffineTransformTranslate(transform, self.size.width, 0)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
}
if ( self.imageOrientation == UIImageOrientation.Right || self.imageOrientation == UIImageOrientation.RightMirrored ) {
transform = CGAffineTransformTranslate(transform, 0, self.size.height);
transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2));
}
if ( self.imageOrientation == UIImageOrientation.UpMirrored || self.imageOrientation == UIImageOrientation.DownMirrored ) {
transform = CGAffineTransformTranslate(transform, self.size.width, 0)
transform = CGAffineTransformScale(transform, -1, 1)
}
if ( self.imageOrientation == UIImageOrientation.LeftMirrored || self.imageOrientation == UIImageOrientation.RightMirrored ) {
transform = CGAffineTransformTranslate(transform, self.size.height, 0);
transform = CGAffineTransformScale(transform, -1, 1);
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
var ctx: CGContextRef = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height),
CGImageGetBitsPerComponent(self.CGImage), 0,
CGImageGetColorSpace(self.CGImage),
CGImageGetBitmapInfo(self.CGImage));
CGContextConcatCTM(ctx, transform)
if ( self.imageOrientation == UIImageOrientation.Left ||
self.imageOrientation == UIImageOrientation.LeftMirrored ||
self.imageOrientation == UIImageOrientation.Right ||
self.imageOrientation == UIImageOrientation.RightMirrored ) {
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage)
} else {
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage)
}
// And now we just create a new UIImage from the drawing context and return it
return UIImage(CGImage: CGBitmapContextCreateImage(ctx))!
}
}
Based on MetalHeart2003's earlier work..
Here is an UIImage extension in Swift 2 based on the accepted answer by #Anomie. It uses a clearer switch case. It also takes the optional value returned by CGBitmapContextCreateImage() into consideration.
extension UIImage {
func rotateImageByOrientation() -> UIImage {
// No-op if the orientation is already correct
guard self.imageOrientation != .Up else {
return self
}
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
var transform = CGAffineTransformIdentity;
switch (self.imageOrientation) {
case .Down, .DownMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
case .Left, .LeftMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, 0)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
case .Right, .RightMirrored:
transform = CGAffineTransformTranslate(transform, 0, self.size.height)
transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2))
default:
break
}
switch (self.imageOrientation) {
case .UpMirrored, .DownMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, 0)
transform = CGAffineTransformScale(transform, -1, 1)
case .LeftMirrored, .RightMirrored:
transform = CGAffineTransformTranslate(transform, self.size.height, 0)
transform = CGAffineTransformScale(transform, -1, 1)
default:
break
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
let ctx = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height),
CGImageGetBitsPerComponent(self.CGImage), 0,
CGImageGetColorSpace(self.CGImage),
CGImageGetBitmapInfo(self.CGImage).rawValue)
CGContextConcatCTM(ctx, transform)
switch (self.imageOrientation) {
case .Left, .LeftMirrored, .Right, .RightMirrored:
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage)
default:
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage)
}
// And now we just create a new UIImage from the drawing context
if let cgImage = CGBitmapContextCreateImage(ctx) {
return UIImage(CGImage: cgImage)
} else {
return self
}
}
}
I have experienced this issue with images taken from camera or saved in camera roll which are taken from camera. Images downloaded in photo library from safari browser does not rotate when uploaded.
I was able to solve this issue by making the image data as JPEG before uploading.
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
let data = UIImageJPEGRepresentation(image, 1.0)
We can now use the data for uploading and the image will not get rotated after upload.
Hope this will work.
If I understand, what you want to do is disregard the orientation of the UIImage? If so then you could do this:-
//image is your original image
image = [UIImage imageWithCGImage:[image CGImage]
scale:[image scale]
orientation: UIImageOrientationUp];
or in Swift :-
image = UIImage(CGImage: image.CGImage!, scale: image.scale, orientation:.Up)
It solved my cropping issue.. Hope, this is what you're looking for..
Swift 3 version based on #jake1981 who've taken it from #MetalHeart2003
extension UIImage {
func fixOrientation() -> UIImage {
// No-op if the orientation is already correct
if ( self.imageOrientation == UIImageOrientation.up ) {
return self;
}
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
var transform: CGAffineTransform = CGAffineTransform.identity
if ( self.imageOrientation == UIImageOrientation.down || self.imageOrientation == UIImageOrientation.downMirrored ) {
transform = transform.translatedBy(x: self.size.width, y: self.size.height)
transform = transform.rotated(by: CGFloat(M_PI))
}
if ( self.imageOrientation == UIImageOrientation.left || self.imageOrientation == UIImageOrientation.leftMirrored ) {
transform = transform.translatedBy(x: self.size.width, y: 0)
transform = transform.rotated(by: CGFloat(M_PI_2))
}
if ( self.imageOrientation == UIImageOrientation.right || self.imageOrientation == UIImageOrientation.rightMirrored ) {
transform = transform.translatedBy(x: 0, y: self.size.height);
transform = transform.rotated(by: CGFloat(-M_PI_2));
}
if ( self.imageOrientation == UIImageOrientation.upMirrored || self.imageOrientation == UIImageOrientation.downMirrored ) {
transform = transform.translatedBy(x: self.size.width, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
}
if ( self.imageOrientation == UIImageOrientation.leftMirrored || self.imageOrientation == UIImageOrientation.rightMirrored ) {
transform = transform.translatedBy(x: self.size.height, y: 0);
transform = transform.scaledBy(x: -1, y: 1);
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
let ctx: CGContext = CGContext(data: nil, width: Int(self.size.width), height: Int(self.size.height),
bitsPerComponent: self.cgImage!.bitsPerComponent, bytesPerRow: 0,
space: self.cgImage!.colorSpace!,
bitmapInfo: self.cgImage!.bitmapInfo.rawValue)!
ctx.concatenate(transform)
if ( self.imageOrientation == UIImageOrientation.left ||
self.imageOrientation == UIImageOrientation.leftMirrored ||
self.imageOrientation == UIImageOrientation.right ||
self.imageOrientation == UIImageOrientation.rightMirrored ) {
ctx.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: self.size.height, height: self.size.width))
} else {
ctx.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height))
}
// And now we just create a new UIImage from the drawing context and return it
return UIImage(cgImage: ctx.makeImage()!)
}
}
#an0, thanks for the answer!
The only thing is autoreleasepool:
func fixOrientation(img: UIImage) -> UIImage? {
let result: UIImage?
if img.imageOrientation == .up {
result = img
} else {
result = autoreleasepool { () -> UIImage? in
UIGraphicsBeginImageContextWithOptions(img.size, false, img.scale)
let rect = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height)
img.draw(in: rect)
let normalizedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return normalizedImage
}
}
return result
}
Here is the Swift-4.2 code for automatic fix your image orientation
Returns UIImage
func AutofixImageOrientation(_ image: UIImage)->UIImage {
UIGraphicsBeginImageContext(image.size)
image.draw(at: .zero)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage ?? image
}
I transposed this into Xamarin:
private static UIImage FixImageOrientation(UIImage image)
{
if (image.Orientation == UIImageOrientation.Up)
{
return image;
}
var transform = CGAffineTransform.MakeIdentity();
float pi = (float)Math.PI;
switch (image.Orientation)
{
case UIImageOrientation.Down:
case UIImageOrientation.DownMirrored:
transform = CGAffineTransform.Translate(transform, image.Size.Width, image.Size.Height);
transform = CGAffineTransform.Rotate(transform, pi);
break;
case UIImageOrientation.Left:
case UIImageOrientation.LeftMirrored:
transform = CGAffineTransform.Translate(transform, image.Size.Width, 0);
transform = CGAffineTransform.Rotate(transform, pi / 2);
break;
case UIImageOrientation.Right:
case UIImageOrientation.RightMirrored:
transform = CGAffineTransform.Translate(transform, 0, image.Size.Height);
transform = CGAffineTransform.Rotate(transform, -(pi / 2));
break;
}
switch (image.Orientation)
{
case UIImageOrientation.UpMirrored:
case UIImageOrientation.DownMirrored:
transform = CGAffineTransform.Translate(transform, image.Size.Width, 0);
transform = CGAffineTransform.Scale(transform, -1, 1);
break;
case UIImageOrientation.LeftMirrored:
case UIImageOrientation.RightMirrored:
transform = CGAffineTransform.Translate(transform, image.Size.Height, 0);
transform = CGAffineTransform.Scale(transform, -1, 1);
break;
}
var ctx = new CGBitmapContext(null, (nint)image.Size.Width, (nint)image.Size.Height, image.CGImage.BitsPerComponent,
image.CGImage.BytesPerRow, image.CGImage.ColorSpace, image.CGImage.BitmapInfo);
ctx.ConcatCTM(transform);
switch (image.Orientation)
{
case UIImageOrientation.Left:
case UIImageOrientation.LeftMirrored:
case UIImageOrientation.Right:
case UIImageOrientation.RightMirrored:
ctx.DrawImage(new CGRect(0, 0, image.Size.Height, image.Size.Width), image.CGImage);
break;
default:
ctx.DrawImage(new CGRect(0, 0, image.Size.Width, image.Size.Height), image.CGImage);
break;
}
var cgimg = ctx.ToImage();
var img = new UIImage(cgimg);
ctx.Dispose();
ctx = null;
cgimg.Dispose();
cgimg = null;
return img;
}

Resources