diff --git a/package.json b/package.json index ab56963d1..b5c18c725 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/apache/cordova-plugin-camera" + "url": "https://github.com/niou-ns/cordova-plugin-camera" }, "keywords": [ "cordova", diff --git a/src/ios/CDVCamera.m b/src/ios/CDVCamera.m index d03cfd875..328a72e04 100644 --- a/src/ios/CDVCamera.m +++ b/src/ios/CDVCamera.m @@ -42,7 +42,7 @@ Licensed to the Apache Software Foundation (ASF) under one SEL s1 = NSSelectorFromString(@"cdv_base64EncodedString"); SEL s2 = NSSelectorFromString(@"base64EncodedString"); SEL s3 = NSSelectorFromString(@"base64EncodedStringWithOptions:"); - + if ([data respondsToSelector:s1]) { NSString* (*func)(id, SEL) = (void *)[data methodForSelector:s1]; return func(data, s1); @@ -66,7 +66,7 @@ + (instancetype) createFromTakePictureArguments:(CDVInvokedUrlCommand*)command pictureOptions.quality = [command argumentAtIndex:0 withDefault:@(50)]; pictureOptions.destinationType = [[command argumentAtIndex:1 withDefault:@(DestinationTypeFileUri)] unsignedIntegerValue]; pictureOptions.sourceType = [[command argumentAtIndex:2 withDefault:@(UIImagePickerControllerSourceTypeCamera)] unsignedIntegerValue]; - + NSNumber* targetWidth = [command argumentAtIndex:3 withDefault:nil]; NSNumber* targetHeight = [command argumentAtIndex:4 withDefault:nil]; pictureOptions.targetSize = CGSizeMake(0, 0); @@ -81,10 +81,10 @@ + (instancetype) createFromTakePictureArguments:(CDVInvokedUrlCommand*)command pictureOptions.saveToPhotoAlbum = [[command argumentAtIndex:9 withDefault:@(NO)] boolValue]; pictureOptions.popoverOptions = [command argumentAtIndex:10 withDefault:nil]; pictureOptions.cameraDirection = [[command argumentAtIndex:11 withDefault:@(UIImagePickerControllerCameraDeviceRear)] unsignedIntegerValue]; - + pictureOptions.popoverSupported = NO; pictureOptions.usesGeolocation = NO; - + return pictureOptions; } @@ -109,7 +109,7 @@ + (void)initialize - (NSURL*) urlTransformer:(NSURL*)url { NSURL* urlToTransform = url; - + // for backwards compatibility - we check if this property is there SEL sel = NSSelectorFromString(@"urlTransformer"); if ([self.commandDelegate respondsToSelector:sel]) { @@ -120,7 +120,7 @@ - (NSURL*) urlTransformer:(NSURL*)url urlToTransform = urlTransformer(url); } } - + return urlToTransform; } @@ -139,16 +139,16 @@ - (BOOL)popoverSupported - (void)takePicture:(CDVInvokedUrlCommand*)command { self.hasPendingOperation = YES; - + __weak CDVCamera* weakSelf = self; [self.commandDelegate runInBackground:^{ - + CDVPictureOptions* pictureOptions = [CDVPictureOptions createFromTakePictureArguments:command]; pictureOptions.popoverSupported = [weakSelf popoverSupported]; pictureOptions.usesGeolocation = [weakSelf usesGeolocation]; pictureOptions.cropToSize = NO; - + BOOL hasCamera = [UIImagePickerController isSourceTypeAvailable:pictureOptions.sourceType]; if (!hasCamera) { NSLog(@"Camera.getPicture: source type %lu not available.", (unsigned long)pictureOptions.sourceType); @@ -181,12 +181,12 @@ - (void)takePicture:(CDVInvokedUrlCommand*)command CDVCameraPicker* cameraPicker = [CDVCameraPicker createFromPictureOptions:pictureOptions]; weakSelf.pickerController = cameraPicker; - + cameraPicker.delegate = weakSelf; cameraPicker.callbackId = command.callbackId; // we need to capture this state for memory warnings that dealloc this object cameraPicker.webView = weakSelf.webView; - + // Perform UI operations on the main thread dispatch_async(dispatch_get_main_queue(), ^{ // If a popover is already open, close it; we only want one at a time. @@ -279,7 +279,7 @@ - (void)navigationController:(UINavigationController *)navigationController will { if([navigationController isKindOfClass:[UIImagePickerController class]]){ UIImagePickerController* cameraPicker = (UIImagePickerController*)navigationController; - + if(![cameraPicker.mediaTypes containsObject:(NSString*)kUTTypeImage]){ [viewController.navigationItem setTitle:NSLocalizedString(@"Videos", nil)]; } @@ -339,7 +339,7 @@ - (void)popoverControllerDidDismissPopover:(id)popoverController - (NSData*)processImage:(UIImage*)image info:(NSDictionary*)info options:(CDVPictureOptions*)options { NSData* data = nil; - + switch (options.encodingType) { case EncodingTypePNG: data = UIImagePNGRepresentation(image); @@ -355,12 +355,12 @@ - (NSData*)processImage:(UIImage*)image info:(NSDictionary*)info options:(CDVPic if (controllerMetadata) { self.data = data; self.metadata = [[NSMutableDictionary alloc] init]; - + NSMutableDictionary* EXIFDictionary = [[controllerMetadata objectForKey:(NSString*)kCGImagePropertyExifDictionary]mutableCopy]; if (EXIFDictionary) { [self.metadata setObject:EXIFDictionary forKey:(NSString*)kCGImagePropertyExifDictionary]; } - + if (IsAtLeastiOSVersion(@"8.0")) { [[self locationManager] performSelector:NSSelectorFromString(@"requestWhenInUseAuthorization") withObject:nil afterDelay:0]; } @@ -375,7 +375,7 @@ - (NSData*)processImage:(UIImage*)image info:(NSDictionary*)info options:(CDVPic default: break; }; - + return data; } @@ -384,13 +384,13 @@ - (NSString*)tempFilePath:(NSString*)extension NSString* docsPath = [NSTemporaryDirectory()stringByStandardizingPath]; NSFileManager* fileMgr = [[NSFileManager alloc] init]; // recommended by Apple (vs [NSFileManager defaultManager]) to be threadsafe NSString* filePath; - + // generate unique file name int i = 1; do { filePath = [NSString stringWithFormat:@"%@/%@%03d.%@", docsPath, CDV_PHOTO_PREFIX, i++, extension]; } while ([fileMgr fileExistsAtPath:filePath]); - + return filePath; } @@ -403,13 +403,13 @@ - (UIImage*)retrieveImage:(NSDictionary*)info options:(CDVPictureOptions*)option } else { image = [info objectForKey:UIImagePickerControllerOriginalImage]; } - + if (options.correctOrientation) { image = [image imageCorrectedForCaptureOrientation]; } - + UIImage* scaledImage = nil; - + if ((options.targetSize.width > 0) && (options.targetSize.height > 0)) { // if cropToSize, resize image and crop to target size, otherwise resize to fit target without cropping if (options.cropToSize) { @@ -417,8 +417,11 @@ - (UIImage*)retrieveImage:(NSDictionary*)info options:(CDVPictureOptions*)option } else { scaledImage = [image imageByScalingNotCroppingForSize:options.targetSize]; } - } - + } else if (options.allowsEditing && [info objectForKey:UIImagePickerControllerEditedImage]) { + scaledImage = [image imageCropWithoutScale:info]; + } + + return (scaledImage == nil ? image : scaledImage); } @@ -442,11 +445,11 @@ - (CDVPluginResult*)resultForImage:(CDVPictureOptions*)options info:(NSDictionar image = [self retrieveImage:info options:options]; NSData* data = [self processImage:image info:info options:options]; if (data) { - + NSString* extension = options.encodingType == EncodingTypePNG? @"png" : @"jpg"; NSString* filePath = [self tempFilePath:extension]; NSError* err = nil; - + // save file if (![data writeToFile:filePath options:NSAtomicWrite error:&err]) { result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[err localizedDescription]]; @@ -460,7 +463,7 @@ - (CDVPluginResult*)resultForImage:(CDVPictureOptions*)options info:(NSDictionar { image = [self retrieveImage:info options:options]; NSData* data = [self processImage:image info:info options:options]; - + if (data) { result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:toBase64(data)]; } @@ -469,12 +472,12 @@ - (CDVPluginResult*)resultForImage:(CDVPictureOptions*)options info:(NSDictionar default: break; }; - + if (saveToPhotoAlbum && image) { ALAssetsLibrary* library = [ALAssetsLibrary new]; [library writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)(image.imageOrientation) completionBlock:nil]; } - + return result; } @@ -488,10 +491,10 @@ - (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingM { __weak CDVCameraPicker* cameraPicker = (CDVCameraPicker*)picker; __weak CDVCamera* weakSelf = self; - + dispatch_block_t invoke = ^(void) { __block CDVPluginResult* result = nil; - + NSString* mediaType = [info objectForKey:UIImagePickerControllerMediaType]; if ([mediaType isEqualToString:(NSString*)kUTTypeImage]) { result = [self resultForImage:cameraPicker.pictureOptions info:info]; @@ -499,14 +502,14 @@ - (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingM else { result = [self resultForVideo:info]; } - + if (result) { [weakSelf.commandDelegate sendPluginResult:result callbackId:cameraPicker.callbackId]; weakSelf.hasPendingOperation = NO; weakSelf.pickerController = nil; } }; - + if (cameraPicker.pictureOptions.popoverSupported && (cameraPicker.pickerPopoverController != nil)) { [cameraPicker.pickerPopoverController dismissPopoverAnimated:YES]; cameraPicker.pickerPopoverController.delegate = nil; @@ -529,7 +532,7 @@ - (void)imagePickerControllerDidCancel:(UIImagePickerController*)picker { __weak CDVCameraPicker* cameraPicker = (CDVCameraPicker*)picker; __weak CDVCamera* weakSelf = self; - + dispatch_block_t invoke = ^ (void) { CDVPluginResult* result; if ([ALAssetsLibrary authorizationStatus] == ALAuthorizationStatusAuthorized) { @@ -537,9 +540,9 @@ - (void)imagePickerControllerDidCancel:(UIImagePickerController*)picker } else { result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"has no access to assets"]; } - + [weakSelf.commandDelegate sendPluginResult:result callbackId:cameraPicker.callbackId]; - + weakSelf.hasPendingOperation = NO; weakSelf.pickerController = nil; }; @@ -552,11 +555,11 @@ - (CLLocationManager*)locationManager if (locationManager != nil) { return locationManager; } - + locationManager = [[CLLocationManager alloc] init]; [locationManager setDesiredAccuracy:kCLLocationAccuracyNearestTenMeters]; [locationManager setDelegate:self]; - + return locationManager; } @@ -565,15 +568,15 @@ - (void)locationManager:(CLLocationManager*)manager didUpdateToLocation:(CLLocat if (locationManager == nil) { return; } - + [self.locationManager stopUpdatingLocation]; self.locationManager = nil; - + NSMutableDictionary *GPSDictionary = [[NSMutableDictionary dictionary] init]; - + CLLocationDegrees latitude = newLocation.coordinate.latitude; CLLocationDegrees longitude = newLocation.coordinate.longitude; - + // latitude if (latitude < 0.0) { latitude = latitude * -1.0f; @@ -582,7 +585,7 @@ - (void)locationManager:(CLLocationManager*)manager didUpdateToLocation:(CLLocat [GPSDictionary setObject:@"N" forKey:(NSString*)kCGImagePropertyGPSLatitudeRef]; } [GPSDictionary setObject:[NSNumber numberWithFloat:latitude] forKey:(NSString*)kCGImagePropertyGPSLatitude]; - + // longitude if (longitude < 0.0) { longitude = longitude * -1.0f; @@ -592,7 +595,7 @@ - (void)locationManager:(CLLocationManager*)manager didUpdateToLocation:(CLLocat [GPSDictionary setObject:@"E" forKey:(NSString*)kCGImagePropertyGPSLongitudeRef]; } [GPSDictionary setObject:[NSNumber numberWithFloat:longitude] forKey:(NSString*)kCGImagePropertyGPSLongitude]; - + // altitude CGFloat altitude = newLocation.altitude; if (!isnan(altitude)){ @@ -604,7 +607,7 @@ - (void)locationManager:(CLLocationManager*)manager didUpdateToLocation:(CLLocat } [GPSDictionary setObject:[NSNumber numberWithFloat:altitude] forKey:(NSString *)kCGImagePropertyGPSAltitude]; } - + // Time and date NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"HH:mm:ss.SSSSSS"]; @@ -612,7 +615,7 @@ - (void)locationManager:(CLLocationManager*)manager didUpdateToLocation:(CLLocat [GPSDictionary setObject:[formatter stringFromDate:newLocation.timestamp] forKey:(NSString *)kCGImagePropertyGPSTimeStamp]; [formatter setDateFormat:@"yyyy:MM:dd"]; [GPSDictionary setObject:[formatter stringFromDate:newLocation.timestamp] forKey:(NSString *)kCGImagePropertyGPSDateStamp]; - + [self.metadata setObject:GPSDictionary forKey:(NSString *)kCGImagePropertyGPSDictionary]; [self imagePickerControllerReturnImageResult]; } @@ -625,7 +628,7 @@ - (void)locationManager:(CLLocationManager*)manager didFailWithError:(NSError*)e [self.locationManager stopUpdatingLocation]; self.locationManager = nil; - + [self imagePickerControllerReturnImageResult]; } @@ -633,26 +636,26 @@ - (void)imagePickerControllerReturnImageResult { CDVPictureOptions* options = self.pickerController.pictureOptions; CDVPluginResult* result = nil; - + if (self.metadata) { CGImageSourceRef sourceImage = CGImageSourceCreateWithData((__bridge CFDataRef)self.data, NULL); CFStringRef sourceType = CGImageSourceGetType(sourceImage); - + CGImageDestinationRef destinationImage = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)self.data, sourceType, 1, NULL); CGImageDestinationAddImageFromSource(destinationImage, sourceImage, 0, (__bridge CFDictionaryRef)self.metadata); CGImageDestinationFinalize(destinationImage); - + CFRelease(sourceImage); CFRelease(destinationImage); } - + switch (options.destinationType) { case DestinationTypeFileUri: { NSError* err = nil; NSString* extension = self.pickerController.pictureOptions.encodingType == EncodingTypePNG ? @"png":@"jpg"; NSString* filePath = [self tempFilePath:extension]; - + // save file if (![self.data writeToFile:filePath options:NSAtomicWrite error:&err]) { result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[err localizedDescription]]; @@ -671,16 +674,16 @@ - (void)imagePickerControllerReturnImageResult default: break; }; - + if (result) { [self.commandDelegate sendPluginResult:result callbackId:self.pickerController.callbackId]; } - + self.hasPendingOperation = NO; self.pickerController = nil; self.data = nil; self.metadata = nil; - + if (options.saveToPhotoAlbum) { ALAssetsLibrary *library = [ALAssetsLibrary new]; [library writeImageDataToSavedPhotosAlbum:self.data metadata:self.metadata completionBlock:nil]; @@ -700,14 +703,14 @@ - (UIViewController*)childViewControllerForStatusBarHidden { return nil; } - + - (void)viewWillAppear:(BOOL)animated { SEL sel = NSSelectorFromString(@"setNeedsStatusBarAppearanceUpdate"); if ([self respondsToSelector:sel]) { [self performSelector:sel withObject:nil afterDelay:0]; } - + [super viewWillAppear:animated]; } @@ -717,7 +720,7 @@ + (instancetype) createFromPictureOptions:(CDVPictureOptions*)pictureOptions; cameraPicker.pictureOptions = pictureOptions; cameraPicker.sourceType = pictureOptions.sourceType; cameraPicker.allowsEditing = pictureOptions.allowsEditing; - + if (cameraPicker.sourceType == UIImagePickerControllerSourceTypeCamera) { // We only allow taking pictures (no video) in this API. cameraPicker.mediaTypes = @[(NSString*)kUTTypeImage]; @@ -729,7 +732,7 @@ + (instancetype) createFromPictureOptions:(CDVPictureOptions*)pictureOptions; NSArray* mediaArray = @[(NSString*)(pictureOptions.mediaType == MediaTypeVideo ? kUTTypeMovie : kUTTypeImage)]; cameraPicker.mediaTypes = mediaArray; } - + return cameraPicker; } diff --git a/src/ios/UIImage+CropScaleOrientation.h b/src/ios/UIImage+CropScaleOrientation.h index 31bc42ff0..8443bacf4 100644 --- a/src/ios/UIImage+CropScaleOrientation.h +++ b/src/ios/UIImage+CropScaleOrientation.h @@ -6,9 +6,9 @@ to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - + http://www.apache.org/licenses/LICENSE-2.0 - + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -21,9 +21,10 @@ @interface UIImage (CropScaleOrientation) +- (UIImage*)imageCropWithoutScale:(NSDictionary*)info; - (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize; - (UIImage*)imageCorrectedForCaptureOrientation; - (UIImage*)imageCorrectedForCaptureOrientation:(UIImageOrientation)imageOrientation; - (UIImage*)imageByScalingNotCroppingForSize:(CGSize)targetSize; -@end \ No newline at end of file +@end diff --git a/src/ios/UIImage+CropScaleOrientation.m b/src/ios/UIImage+CropScaleOrientation.m index a66a5d88d..aa1740dca 100644 --- a/src/ios/UIImage+CropScaleOrientation.m +++ b/src/ios/UIImage+CropScaleOrientation.m @@ -6,9 +6,9 @@ Licensed to the Apache Software Foundation (ASF) under one to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - + http://www.apache.org/licenses/LICENSE-2.0 - + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -21,6 +21,57 @@ Licensed to the Apache Software Foundation (ASF) under one @implementation UIImage (CropScaleOrientation) +- (UIImage*) imageCropWithoutScale:(NSDictionary*)info +{ + UIImage* image = nil; + image = [info objectForKey:UIImagePickerControllerOriginalImage]; + CGSize size = image.size; + + // crop the crop rect that the user selected + CGRect cropRect = [[info objectForKey:UIImagePickerControllerCropRect] + CGRectValue]; + + // create a graphics context of the correct size + UIGraphicsBeginImageContext(cropRect.size); + CGContextRef context = UIGraphicsGetCurrentContext(); + + // correct for image orientation + UIImageOrientation orientation = [image imageOrientation]; + if(orientation == UIImageOrientationUp) { + CGContextTranslateCTM(context, 0, size.height); + CGContextScaleCTM(context, 1, -1); + cropRect = CGRectMake(cropRect.origin.x, + -cropRect.origin.y, + cropRect.size.width, + cropRect.size.height); + } else if(orientation == UIImageOrientationRight) { + CGContextScaleCTM(context, 1.0, -1.0); + CGContextRotateCTM(context, -M_PI/2); + size = CGSizeMake(size.height, size.width); + cropRect = CGRectMake(cropRect.origin.y, + cropRect.origin.x, + cropRect.size.height, + cropRect.size.width); + } else if(orientation == UIImageOrientationDown) { + CGContextTranslateCTM(context, size.width, 0); + CGContextScaleCTM(context, -1, 1); + cropRect = CGRectMake(-cropRect.origin.x, + cropRect.origin.y, + cropRect.size.width, + cropRect.size.height); + } + // draw the image in the correct place + CGContextTranslateCTM(context, -cropRect.origin.x, -cropRect.origin.y); + CGContextDrawImage(context, + CGRectMake(0,0, size.width, size.height), + image.CGImage); + // and pull out the cropped image + UIImage *croppedImage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + return croppedImage; +} + - (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize { UIImage* sourceImage = self; @@ -34,11 +85,11 @@ - (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize 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; // scale to fit height } else { @@ -46,7 +97,7 @@ - (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize } scaledWidth = width * scaleFactor; scaledHeight = height * scaleFactor; - + // center the image if (widthFactor > heightFactor) { thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5; @@ -54,21 +105,21 @@ - (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5; } } - + UIGraphicsBeginImageContext(targetSize); // this will crop - + CGRect thumbnailRect = CGRectZero; thumbnailRect.origin = thumbnailPoint; thumbnailRect.size.width = scaledWidth; thumbnailRect.size.height = scaledHeight; - + [sourceImage drawInRect:thumbnailRect]; - + newImage = UIGraphicsGetImageFromCurrentImageContext(); if (newImage == nil) { NSLog(@"could not scale image"); } - + // pop the context to get back to the default UIGraphicsEndImageContext(); return newImage; @@ -78,47 +129,47 @@ - (UIImage*)imageCorrectedForCaptureOrientation:(UIImageOrientation)imageOrienta { float rotation_radians = 0; bool perpendicular = false; - + switch (imageOrientation) { case UIImageOrientationUp : rotation_radians = 0.0; break; - + case UIImageOrientationDown: rotation_radians = M_PI; // don't be scared of radians, if you're reading this, you're good at math break; - + case UIImageOrientationRight: rotation_radians = M_PI_2; perpendicular = true; break; - + case UIImageOrientationLeft: rotation_radians = -M_PI_2; perpendicular = true; break; - + default: break; } - + UIGraphicsBeginImageContext(CGSizeMake(self.size.width, self.size.height)); CGContextRef context = UIGraphicsGetCurrentContext(); - + // Rotate around the center point CGContextTranslateCTM(context, self.size.width / 2, self.size.height / 2); CGContextRotateCTM(context, rotation_radians); - + CGContextScaleCTM(context, 1.0, -1.0); float width = perpendicular ? self.size.height : self.size.width; float height = perpendicular ? self.size.width : self.size.height; CGContextDrawImage(context, CGRectMake(-width / 2, -height / 2, width, height), [self CGImage]); - + // Move the origin back since the rotation might've change it (if its 90 degrees) if (perpendicular) { CGContextTranslateCTM(context, -self.size.height / 2, -self.size.width / 2); } - + UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; @@ -140,11 +191,11 @@ - (UIImage*)imageByScalingNotCroppingForSize:(CGSize)targetSize CGFloat targetHeight = targetSize.height; CGFloat scaleFactor = 0.0; CGSize scaledSize = targetSize; - + if (CGSizeEqualToSize(imageSize, targetSize) == NO) { CGFloat widthFactor = targetWidth / width; CGFloat heightFactor = targetHeight / height; - + // opposite comparison to imageByScalingAndCroppingForSize in order to contain the image within the given bounds if (widthFactor > heightFactor) { scaleFactor = heightFactor; // scale to fit height @@ -153,20 +204,20 @@ - (UIImage*)imageByScalingNotCroppingForSize:(CGSize)targetSize } scaledSize = CGSizeMake(MIN(width * scaleFactor, targetWidth), MIN(height * scaleFactor, targetHeight)); } - + // If the pixels are floats, it causes a white line in iOS8 and probably other versions too scaledSize.width = (int)scaledSize.width; scaledSize.height = (int)scaledSize.height; - + UIGraphicsBeginImageContext(scaledSize); // this will resize - + [sourceImage drawInRect:CGRectMake(0, 0, scaledSize.width, scaledSize.height)]; - + newImage = UIGraphicsGetImageFromCurrentImageContext(); if (newImage == nil) { NSLog(@"could not scale image"); } - + // pop the context to get back to the default UIGraphicsEndImageContext(); return newImage;