UIImagePickerControllerEditedImage get nil - ios

Hey guys I'm doing some image editing with UIImagePickerController. Here is some code in imagePickerController:didFinishPickingMediaWithInfo:
UIImage *editedImg = [info objectForKey:UIImagePickerControllerEditedImage];
UIImageView *imgView = [[UIImageView alloc] initWithImage:editedImg];
CGRect imgFrm = imgView.frame;
float rate = imgFrm.size.height / imgFrm.size.width;
imgFrm.size.width = size;
imgFrm.size.height = size * rate;
imgFrm.origin.x = 0;
imgFrm.origin.y = (size - imgFrm.size.height) / 2;
[imgView setFrame:imgFrm];
UIView *cropView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, size, size)];
[cropView setBackgroundColor:[UIColor blackColor]];
[cropView addSubview:imgView];
UIImage *croppedImg = [MyUtil createUIImageFromUIView:cropView];
The above is to set the image in a size*size view and draw a image from a view when the height of the image returned by picker is smaller than size.
Here is the code of createUIImageFromUIView:(UIView*)view :
+ (UIImage *)createUIImageFromUIView:(UIView *)view
{
UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, 2.0);
CGContextRef ctx = UIGraphicsGetCurrentContext();
[view.layer renderInContext:ctx];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return viewImage;
}
My problem is : when debugging, the 'editedImg'(defined in first line) just shows 'nil'. But, the following code works well. I get the corpView(shows 'nil' too) correctly and get cropped image and can encode it to base64 encoded string for sending to server side. I just want to know why the editedImg is nil(returned by [info objectForKey:UIImagePickerControllerEditedImage], but when I choose to print the info in debug mode, the output is not nil in the console)?

The editdImg gets nil, try:
UIImage *editedImg = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
Get file sizeļ¼š
- (long long) fileSizeAtPath:(NSString*) filePath{
NSFileManager* manager = [NSFileManager defaultManager];
if ([manager fileExistsAtPath:filePath]){
return [[manager attributesOfItemAtPath:filePath error:nil] fileSize];
}
return 0;
}
Best wishes!

After some searching I accidentally found this : string value always shows nil in objective-c
This is the reason why I always see 'nil' in debug mode while the code works well.

You can get your cropped image size by
UIImage *croppedImg = [MyUtil createUIImageFromUIView:cropView];
NSData *dataForImage = UIImagePNGRepresentation(croppedImg);
Now you can check length
if (dataForImage.length)
{
}

Related

UIImage from file always nil

I am making a document scanning app
the document that is scanned is stored in a temp file within the application structure and the path of this file stored in a NSString variable
This image is passed to a UIImageView which successfully loads
[self.cameraViewController captureImageWithCompletionHander:^(NSString *imageFilePath)
{
UIImageView *captureImageView = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:imageFilePath]];
captureImageView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.7];
captureImageView.frame = CGRectOffset(weakSelf.view.bounds, 0, -weakSelf.view.bounds.size.height);
captureImageView.alpha = 1.0;
captureImageView.contentMode = UIViewContentModeScaleAspectFit;
captureImageView.userInteractionEnabled = YES;
[weakSelf.view addSubview:captureImageView];
Then want to convert the image to base64 ready for upload. In order to do this i will call the following which accepts a UIImage object
- (NSString *)encodeToBase64String:(UIImage *)image {
return [UIImagePNGRepresentation(image) base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
}
The value of the imageFilePath variable is
/private/var/mobile/Containers/Data/Application/79C28B96-275D-48F1-B701-CABD699C388D/tmp/ipdf_img_1447880304.jpeg
To fetch the image from the file i used this
UIImage *img = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:imageFilePath ofType:nil]];
base64String = [self encodeToBase64String:img];
The problem is that the UIImage object is always nill (or nill). At first i though that the problem could be the path, but the image loads within the UIImageView.
Can someone please help me with the figuring out why this does not return the image stored within the imageFilePath variable
Replace:
UIImage *img = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:imageFilePath ofType:nil]];
with:
UIImage *img = [UIImage imageWithContentsOfFile:imageFilePath];
You are not loading the image from the bundle.
Also, make sure you are not trying to use the full path across executions of the app. Only persist relative paths since the path to the app's sandbox can change over time.

How to capture only visible image using AVCapture iOS

I am using AVCapture to capture the images from camera.Everything works fine except this issue.
I need the final captured image as same like which is visible in camera.But the image shows more area(which is not like visible in camera).How can i get the same visible image as final stillImageOutput?
Any help would be highly appreciated.
use your view/imageview object name instead of contentScrollview. This will help you to render the view and provide you an image.
for reference:https://charangiri.wordpress.com/2014/09/18/how-to-render-screen-taking-screen-shot-programmatically/
- (UIImage *) createScreenshotOfCompleteScreen
{
UIImage* image = nil;
UIGraphicsBeginImageContext(contentScrollview.contentSize);
{
CGPoint savedContentOffset = contentScrollview.contentOffset;
CGRect savedFrame = contentScrollview.frame;
contentScrollview.contentOffset = CGPointZero;
contentScrollview.frame = CGRectMake(0, 0, contentScrollview.contentSize.width, contentScrollview.contentSize.height);
if ([[NSString versionofiOS] intValue]>=7)
{
[contentScrollview drawViewHierarchyInRect:contentScrollview.bounds afterScreenUpdates:YES];
}
else
{
[contentScrollview.layer renderInContext: UIGraphicsGetCurrentContext()];
}
image = UIGraphicsGetImageFromCurrentImageContext();
contentScrollview.contentOffset = savedContentOffset;
contentScrollview.frame = savedFrame;
}
UIGraphicsEndImageContext();
return image;
}

How to resize image pixel size programmatically

i am creating app using facebook. if i am trying to upload photo to facebook means i got following message any give idea for solve that
"The provided user_generated photo for an OG action must be at least 480px in both dimensions"
I use a function like follow to get an image with any size.
Original image should big than you wanted.(ps:You can try an image little)
+ (UIImage *)thumbnailWithImageWithoutScale:(UIImage *)image size:(CGSize)wantSize
{
UIImage * targetImage;
if (nil == image) {
targetImage = nil;
}else{
CGSize size = image.size;
CGRect rect;
if (wantSize.width/wantSize.height > size.width/size.height) {
rect.size.width = wantSize.height*size.width/size.height;
rect.size.height = wantSize.height;
rect.origin.x = (wantSize.width - rect.size.width)/2;
rect.origin.y = 0;
} else{
rect.size.width = wantSize.width;
rect.size.height = wantSize.width*size.height/size.width;
rect.origin.x = 0;
rect.origin.y = (wantSize.height - rect.size.height)/2;
}
UIGraphicsBeginImageContext(wantSize);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [[UIColor clearColor] CGColor]);
UIRectFill(CGRectMake(0, 0, wantSize.width, wantSize.height));//clear background
[image drawInRect:rect];
targetImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
return targetImage;
}
You must provide a bigger image, with at least 480px width and height.
Your image is apparently smaller than 480px wide or tall. The problem is either that the original image is too small, or you're retrieving it incorrectly. You could, theoretically resize the image to make it bigger, but that will result in pixelation that is probably undesirable.
You should show us how you're retrieving the image. For example, when I want to pick a photo from my library, I'll use the code adapted from Picking an Item from the Photo Library from the Camera Programming Topics for iOS:
UIImagePickerController *mediaUI = [[UIImagePickerController alloc] init];
mediaUI.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
// To instead show the controls to allow user to trim image, set this to YES;
// If no cropping available, set this to NO.
mediaUI.allowsEditing = YES;
mediaUI.delegate = delegate;
And then, you obviously have to implement the didFinishPickingMediaWithInfo:
#pragma mark - UIImagePickerControllerDelegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];
UIImage *originalImage, *editedImage, *imageToUse;
// Handle a still image picked from a photo album
if (CFStringCompare ((CFStringRef) mediaType, kUTTypeImage, 0) == kCFCompareEqualTo) {
editedImage = (UIImage *) [info objectForKey:UIImagePickerControllerEditedImage];
originalImage = (UIImage *) [info objectForKey:UIImagePickerControllerOriginalImage];
if (editedImage) {
imageToUse = editedImage;
} else {
imageToUse = originalImage;
}
NSLog(#"image size = %#", NSStringFromCGSize(imageToUse.size));
if (imageToUse.size.width < 480 || imageToUse.size.height < 480)
{
[[[UIAlertView alloc] initWithTitle:nil
message:#"Please select image that is at least 480 x 480"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil] show];
}
else
{
// do something with imageToUse
}
}
[picker dismissViewControllerAnimated: YES completion:nil];
}

Can the new tintColor property of UIImageview in iOS 7 be used for animating images?

tintColor is a life saver, it takes app theming to a whole new (easy) level.
//the life saving bit is the new UIImageRenderingModeAlwaysTemplate mode of UIImage
UIImage *templateImage = [[UIImage imageNamed:#"myTemplateImage"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
imageView.image = templateImage;
//set the desired tintColor
imageView.tintColor = color;
The above code will "paint" the image's non-transparent parts according to the UIImageview's tint color which is oh so cool.No need for core graphics for something simple like that.
The problem I face is with animations.
Continuing from the above code:
//The array with the names of the images we want to animate
NSArray *imageNames = #[#"1",#"2"#"3"#"4"#"5"];
//The array with the actual images
NSMutableArray *images = [NSMutableArray new];
for (int i = 0; i < imageNames.count; i++)
{
[images addObject:[[UIImage imageNamed:[imageNames objectAtIndex:i]] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]];
}
//We set the animation images of the UIImageView to the images in the array
imageView.animationImages = images;
//and start animating the animation
[imageView startAnimating];
The animation is performed correctly but the images use their original color (i.e. the color used in the gfx editing application) instead of the UIImageView's tintColor.
I am about to try to perform the animation myself (by doing something a little bit over the top like looping through the images and setting the UIImageView's image property with a NSTimer delay so that the human eye can catch it).
Before doing that I'd like to ask if the tintColor property of UIImageView is supposed to support what I'm trying to do with it i.e use it for animations.
Thanks.
Rather than animate the images myself, I decided to render the individual frames using a tint color and then let UIImage do the animation. I created a category on UIImage with the following methods:
+ (instancetype)animatedImageNamed:(NSString *)name tintColor:(UIColor *)tintColor duration:(NSTimeInterval)duration
{
NSMutableArray *images = [[NSMutableArray alloc] init];
short index = 0;
while ( index <= 1024 )
{
NSString *imageName = [NSString stringWithFormat:#"%#%d", name, index++];
UIImage *image = [UIImage imageNamed:imageName];
if ( image == nil ) break;
[images addObject:[image imageTintedWithColor:tintColor]];
}
return [self animatedImageWithImages:images duration:duration];
}
- (instancetype)imageTintedWithColor:(UIColor *)tintColor
{
CGRect imageBounds = CGRectMake( 0, 0, self.size.width, self.size.height );
UIGraphicsBeginImageContextWithOptions( self.size, NO, self.scale );
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM( context, 0, self.size.height );
CGContextScaleCTM( context, 1.0, -1.0 );
CGContextClipToMask( context, imageBounds, self.CGImage );
[tintColor setFill];
CGContextFillRect( context, imageBounds );
UIImage *tintedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return tintedImage;
}
It works just like + [UIImage animatedImageNamed:duration:] (including looking for files named "image0", "image1", etc) except that it also takes a tint color.
Thanks to this answer for providing the image tinting code: https://stackoverflow.com/a/19152722/321527
.tintColor can probably handle it. I use NSTimers for UIButton's setTitleColor method all the time. Here's an example.
UPDATED: Tested and works on iPhone 5s iOS 7.1!
- (void)bringToMain:(UIImage *)imageNam {
timer = [NSTimer scheduledTimerWithTimeInterval:.002
target:self
selector:#selector(animateTint)
userInfo:nil
repeats:YES];
}
- (void)animateTint {
asd += 1.0f;
[imageView setTintColor:[UIColor colorWithRed:((asd/100.0f) green:0.0f blue:0.0f alpha:1.0f]];
if (asd == 100) {
asd = 0.0f
[timer invalidate];
}
}

UIImageView is not always shown

I'm debugging a problem with an imageView not being shown.
imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:imageName]];
NSLog(#"imageView right after initialization is: %#", imageView);
imageView.frame = CGRectMake(2, 0, 316, 45);
imageView.layer.zPosition = zPos;
NSLog(#"imageView after running the setters: %#", imageView);
[self.view addSubview:imageView];
The weird part is that sometimes the imageView gets displayed, sometimes it's not (about 75% of the time it's displayed).
imageView is not accessed anywhere except the code above.
What I noticed is that when the imageView is not displayed, the first log statement shows that:
imageView right after initialization is: <UIImageView: 0x9eaa760;
frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <CALayer:
0x9ec04a0>>
When the image view is displayed:
imageView right after initialization is: <UIImageView: 0xaa61ad0;
frame = (0 0; 644 88); opaque = NO; userInteractionEnabled = NO; layer
= <CALayer: 0xaa61330&rt;&rt;
EDITED:
I ran tens of tests, the imageView always behaves the same: when it is not shown, the initial frame is (0 0; 0 0). When it's not, it's always some other value.
P.S. I'm not using ARC.
In your log of the UIImageView it show frame = (0 0; 0 0); This means that the view will not be shown since it has a height and width of 0. Which indicates that the image has no size or is nil.
The cause of this is most probably because the image your are trying to load is not found:
You should check wether the image is found or not:
UIImage *image = [UIImage imageNamed:imageName];
if (!image) {
NSLog(#"Image could not be found: %#", imageName);
}
imageView = [[UIImageView alloc] initWithImage:image];
Meaning that even if you change the frame you will still see nothing since there is no image loaded.
Why don't you set the frame first and set the image next?
imageView = [UIImageView alloc]initWithFrame:CGRectMake(0,0,35,35)];
[imageView setImage:[UIImage imageNamed:#"img.png"]];
In addition to rckoenes answer you must always check if the image exists within your bundle path first:
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *documentsDirectory
= [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)
objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:imageName];
if([fileManager fileExistsAtPath:path])
{
UIImage *image = [UIImage imageNamed:imageName];
if (!image) {
NSLog(#"Image could not be found: %#", imageName);
}
imageView = [[UIImageView alloc] initWithImage:image];
} else {
NSLog(#"%# is not included in the app file bundle!", imageName);
}
that way you'll know if the problem is b/c you don't have the file in the first place.. or b/c there is something wrong with file that prevents iOS from loading it.

Resources