Scrollview Images creates issue - ios

I am pick Images using Camera in my app & try to show in horizontal scrollview.
But the images are overlapping
My code
-(IBAction)act_photo:(id)sender
{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
//picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:picker animated:YES completion:NULL];
}
#pragma mark - Image Picker via Camera
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *chosenImage = info[UIImagePickerControllerOriginalImage];
[picker dismissViewControllerAnimated:YES completion:^{
[arr_images insertObject:chosenImage atIndex:0];
[self scrollImages_Setup2];
}];
}
-(void)scrollImages_Setup2
{
for (int k=0; k<arr_images.count; k++) {
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake((CGRectGetWidth(scl.frame) * k) + CGRectGetWidth(scl.frame), 0, CGRectGetWidth(scl.frame), CGRectGetHeight(scl.frame))];
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.image=[arr_images objectAtIndex:k] ;
[scl addSubview:imageView];
}
scl.contentSize = CGSizeMake((CGRectGetWidth(scl.frame) * arr_images.count)+CGRectGetWidth(scl.frame), CGRectGetHeight(scl.frame));
}
Problem
Image1
Image 2
As shown above first I was taken Landscape Image2 & then I was taken Portrait Image 1 .
but as you see, Image 1 has background of Image2.
I think this is because there is something going wrong with scrollview?
Possiblity 2(mostly) Scrollview keeps strong reference of Imageview evenif it is deleted from array
Let me know how to solve this?
Help me to solve this
Thanks

You need to set Y value in you loop, your image Y value same any time,

Each time you take a new image, your completion-Handler puts the new image as the first element into your array and then calls [self scrollImages_Setup2]; where you iterate over all elements in your array and add them as new subviews to your scrollview.
When you take the first image (Image1) it's getting added to the array and then added as and subview to your scrollview. When you take the second image (Image2) it's getting added to the array as the first element. So then there are two elements in the array (Image2 and Image1) which are both getting added as subview to the scrollview. But Image1 has already been added to the scrollview, so that's causing your problem.
A solution to your problem could be either to always add only the new image and calculate the x position with the number of elements in your array, or to always remove all subviews before you add and layout all images again.

Related

UIImageView image is stretching when i am using rounded corners.

I am using UITableViewCell as UITableView Header. I am using the below code to make rounded corners for UIImageView.
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
if(section==0){
static NSString *simpleTableIdentifier = #"ContactDetailsHeaderTableViewCell";
ContactDetailsHeaderTableViewCell *cell = (ContactDetailsHeaderTableViewCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ContactDetailsHeaderTableViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
..................
.................
UIImage *img = [UIImage imageWithContentsOfFile:getImagePath];
//rounded corners
cell.profilePicImgView.clipsToBounds = YES;
UIGraphicsBeginImageContextWithOptions(cell.profilePicImgView.bounds.size, NO, 1.0);
// Add a clip before drawing anything, in the shape of an rounded rect
[[UIBezierPath bezierPathWithRoundedRect:cell.profilePicImgView.bounds
cornerRadius:60.0] addClip];
// Draw your image
[img drawInRect:cell.profilePicImgView.bounds];
// Get the image, here setting the UIImageView image
cell.profilePicImgView.image = UIGraphicsGetImageFromCurrentImageContext();
// end drawing
UIGraphicsEndImageContext();
.............
.............
}
Below is the output
The image inside the UIImageView is stretching, if i am not using the rounded corners then the image is looking properly. I have tried lot of code sample from StackOverflow but none of them are working.
A problem in your code is that you use dequeueReusableCellWithIdentifier to dequeue headers. You should use dequeueReusableHeaderFooterViewWithIdentifier instead, and base your header views on the designated class UITableViewHeaderFooterView. They are separate classes and are recycled differently when you navigate the table view.
Issue is that your image is not perfectly round thats why it looks like stretched image.
The issue is in following line...
[[UIBezierPath bezierPathWithRoundedRect:cell.profilePicImgView.bounds
cornerRadius:60.0] addClip];
Here you are setting cornerRadius:, if you want image view in complete round shape then your need to set cornerRadius: to cell.profilePicImgView.bounds.height/2 or may be .width/2.
You can make round corner in another way as below...
cell.profilePicImgView.image = //set image here
//Make image view round shape
cell.profilePicImgView.layer.cornerRadius = cell.profilePicImgView.bounds.height/2
//clip the bounds of image view
cell.profilePicImgView.clipsToBounds = YES;
Is your UIImageView is of fixed size?
Please check it the same. If not given fixed size, then you need to give cornerRadius of your ImageView as cell.profilePicImgView.bounds.height/2.
Also try to give contentMode = AspectFill.
Why are you making image round? You should make imageview round and you're done. You not need to do anything with image!
to make image view round you need to set it'e corner radius like,
yourImageView.layer.cornerRadius = yourImageView.frame.size.height/2;
yourImageView.clipsToBounds = YES;
yourImageView.contentMode = UIViewContentModeScaleAspectFill
yourImageView.image = [UIImage imageNamed:#"yourImageHere"];
Make sure that your image view's height and width is equal I mean it must be square to get exact round.
Second thing your approach to create header is wrong! You are dequeuing tableview cell in viewForHeaderInSection. This is wrong! Instead of this take or create one view (as xib or you can add view in storyboard beneath the main view) or create view programmatically and add your image view in that view and return that view from viewForHeaderInSection.
use this for rounding corner the image by increasing and decreasing the value as i am using small image currently borderColor is white
-(UIImageView*)SetupLayoutsImg:(UIImageView*)img{
UIColor* borderColor=[UIColor colorWithRed:244.0/255.0f green:244.0/255.0f blue:244.0/255.0f alpha:1.0/1.0f];
int borderwidth=1.0f;
int bottomViewRadius=10.0f;
img.layer.cornerRadius = bottomViewRadius; // this value vary as per your desire
img.contentMode = UIViewContentModeScaleAspectFill
img.layer.borderWidth=borderwidth;
img.layer.borderColor=borderColor.CGColor;
img.clipsToBounds = YES;
return img;
}
-(UIButton*)SetupLayoutsButtons:(UIButton*)Btn{
UIColor* borderColor=[UIColor colorWithRed:244.0/255.0f green:244.0/255.0f blue:244.0/255.0f alpha:1.0/1.0f];
int borderwidth=1.0f;
int buttonRadius=25.0f;
Btn.layer.cornerRadius = buttonRadius; // this value vary as per your desire
Btn.layer.borderWidth=borderwidth;
Btn.layer.borderColor=borderColor.CGColor;
Btn.clipsToBounds = YES;
return Btn;
}
How to use it by just calling it in uitableView delegate viewForHeaderInSection i am using it in cellForRowAtIndexPath like this
tableCellinside.cateImage=[self SetupLayoutsImg:tableCellinside.cateImage];
cateImage is my UIImageView you can use it like this s
cell.profilePicImgView=[self SetupLayoutsImg:cell.profilePicImgView];
Figured out the issue, posting the answer so it may help others. Its not related to rounded corners code. The rounded corners code is working fine. In UIImagePickerController i have set allowsEditing = YES but in didFinishPickingMediaWithInfo i was using UIImagePickerControllerOriginalImage so later i changed it to UIImagePickerControllerEditedImage. Now its working fine. I am able to get the rounded corners image without any stretch.
-(void)capturePhoto{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:picker animated:YES completion:NULL];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
/* earlier i have used UIImagePickerControllerOriginalImage in the place of UIImagePickerControllerEditedImage so it was not working properly*/
UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
............
............
[picker dismissViewControllerAnimated:YES completion:NULL];
}

Show taken images from camera in a ScrollView

I have a simple application with only one button.
When user clicks on it, he can take a pictures, click "Done" in the camera and then can save it and see it on the ScrollView.
However, when he is taking another picture and clicking "Done" in the camera, the new picture overwrites the previous one and he can see only the picture that he has taken.
I want to save all these pictures and then if the user takes 4-5 pictures, he can see all of them by scrolling them.
Here is my code, im not sure why it is not working.
- (IBAction)Camera:(id)sender {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:picker animated:YES completion:NULL];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
NSMutableArray *images = [NSMutableArray arrayWithCapacity:[info count]];
for (UIView *v in [_scrollView subviews]) {
[v removeFromSuperview];
}
[self dismissViewControllerAnimated:YES completion:nil];
UIImage* image=[info valueForKey:#"UIImagePickerControllerEditedImage"];
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
UIImageView *imageview = [[UIImageView alloc] initWithImage:image];
[_scrollView addSubview:imageview];
[images addObject:image];
self.chosenImages = images;
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
[_scrollView setPagingEnabled:YES];
}
And in header i have an array of chosenImages
#property (nonatomic, copy) NSArray *chosenImages;
There are lots of things wrong with your code. Every time the user picks an image, you remove all the subviews from your scroll view, then add just the single selected image.
You have an array chosenImages which you might use to hold all the selected images, but you replace it with a new array, images, which only contains the single newly selected image.
You allocate images as a mutable array with enough capacity for the count of the info dictionary you get in didFinishPickingMediaWithInfo, but there's no point to doing that. The count of that dictionary is going to be the number of key/value pairs in the dictionary, which does not reflect the number of images the user selected (I believe the number of images the user selected will always be 1, ignoring the different formats like the original image and the (possible) edited image.)
I would suggest leaving the previous images in your scroll view, tracking the number and placement of those images, and simply adding a new image to the scroll view after the user picks.
You might think about using a UIPageViewController in page scroll mode rather than a raw scroll view. It manages paged scrolling much better than a scrollview will. There is a sample app from Apple called PhotoScroller (link) that even supports tiled rendering of the images, pinch-to-zoom, and panning around an image. It would be pretty easy to stitch that code into your app for handling these images. (You might not decide to deal with the tiled images - I adapted the PhotoScroller code, with tiled image support, into a client project, and generating the image tiles is a fair amount of work.)
Assuming that self.chosenImages is of NSMutableArray type, try this
[self.chosenImages addObjectsFromArray:images]
instead of
self.chosenImages = images;
and if it isn't mutable, you can always set it like so:
NSMutableArray *newArray = [self.chosenImages mutableCopy];
newArray = [newArray addObjectsFromArray:images];
self.chosenImages = [newArray copy];

Objective-C Camera Crop Size

I have a routine that I use to trigger the camera to take a photo. After the camera takes the photo the user is then given an option to crop the image by default before the delegate passes me back the UIImage. Is there any way that I can pass in a dynamic CGRect to make this default crop area a specific size? One thing I should mention is that the application is a landscape iPad application.
Here is a code sample:
-(void)triggerCamera:(id)sender
{
UIImagePickerController *camera = [[UIImagePickerController alloc] init];
camera.delegate = self;
camera.allowsEditing = YES;
camera.sourceType = UIImagePickerControllerSourceTypeCamera;
//pass in some sort of CGRect ??
[self presentViewController:camera animated:YES completion:NULL];
}
-(void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info {
UIImage *img = [info objectForKey: UIImagePickerControllerOriginalImage];
//process my image further
}
Unfortunately you can't set crop size. I was dealing with same problem over 2 years ago and I got stuck with creating my own viewController for cropping image.
Maybe take a look at GKImagePicker on GitHub. This project hasn't had much activity in the past few months (maybe more), but could be worth a shot. It even comes with an option to have a resizable crop area. I have not tried it myself, but the implementation looks to be pretty simple:
self.imagePicker = [[GKImagePicker alloc] init];
self.imagePicker.cropSize = CGSizeMake(320, 90);
self.imagePicker.delegate = self;
[self presentModalViewController:self.imagePicker.imagePickerController animated:YES];

How can I display a UIImage in a UIImageView?

I am playing around with Xcode 5 and storyboarding. I'm at the point where I have captured a UIImage using the camera, but I can't figure out how to display the image on the phone after I've captured it. I have specified an IBOutlet UIImageView and set it's value to the image that I captured from the camera, but that doesn't seem to do anything at all.
This is my interface:
#interface HCViewController ()
#property (nonatomic, retain) IBOutlet UIImageView *image;
#end
And this is my didFinishPickingWithMediaInfo method:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
// Get the picture from the camera
UIImage *imageFromCamera = [info objectForKey:UIImagePickerControllerEditedImage];
// Set the IBOutlet UIImageView to the picture from the camera
// This does nothing as far as I can tell
self.image = [[UIImageView alloc] initWithImage:imageFromCamera];
// Let's take a closer look at this
NSLog(#"%#", self.image);
// Close the camera view controller
[self dismissViewControllerAnimated:YES completion:nil];
}
This is what I see in the logger for self.image:
2013-09-10 17:17:45.169 YourMom[6136:60b] <UIImageView: 0x1556fdc0; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <CALayer: 0x155d5b10>>
My storyboard has a View Controller with two different scenes that can be swiped back and forth. Both of the scenes have a "View" with an "Image View" as a sub-item. The Image Views each have "Referencing Outlets" that seem to be connected to the image variable that I defined in my interface. However, simply setting the value of image doesn't change the phone display.
After reading this SO question: How can I change the image displayed in an UIImageView programmatically? I tried [self.image setImage:image], but that didn't appear to do anything either. How do I tell Xcode that I want image to show up in the view?
Your mistake is in this:
self.image = [[UIImageView alloc] initWithImage:imageFromCamera];
Because you are using Storyboard your UIImageView will be initialized for you. By executing this line of code you are throwing away an old UIImageView and replacing it with a new UIImageView that has no frame.
You just need to do this:
[self.image setImage:imageFromCamera]
Also, you might be getting the wrong image from info. Try UIImagePickerControllerOriginalImage instead of UIImagePickerControllerEditedImage.
Hope this is helpful, cheers!
UIImage View has an property called image.
This property is of type UIImage.
So if you have an UIImage, then you can set the property as follows:
imageView.image = image;
// this is your delegate method to set the image taken from your camera
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
// Get the picture from the camera
UIImage *imageFromCamera = [info objectForKey:UIImagePickerControllerEditedImage];
// alloc image view as you have to set it image on it
UIImageView *imgView = [[UIImageView alloc]init];
imgView.image = imageFromCamera;
// you can also set the image on button like this
UIImage *imageFromCamera = [info objectForKey:UIImagePickerControllerEditedImage];
// imgBtn is UIButton property
[self.imgBtn setImage:imageFromCamera forState:UIControlStateNormal];
// Let's take a closer look at this
NSLog(#"%#", self.image);
// Close the camera view controller
[self dismissViewControllerAnimated:YES completion:nil];
}
You can try this code to display your image.
imageView.image : UIImage = UIImage(named: "YourImageName")
Hope this can help you with your problems.

Custom Overlay with UIImagePickerControllerSourceTypeSavedPhotosAlbum

I need to let the user select a photo from the Photo Library and be able to size and crop their image while using an Overlay image. Using UIImagePickerControllerSourceTypeCamera with cameraOverlayView is fine, but UIImagePickerControllerSourceTypeSavedPhotosAlbum does not support that property.
Strangely enough, when I add the overlay view as a subView with alpha set at half, the overlay appears on the Photo selection screen, but this wont fly with Apple's approval process.
-(void)choosePhotoDialog:(id)sender
{
UIBarButtonItem * barThing = (UIBarButtonItem*)sender;
OverlayView * overlay = [[OverlayView alloc] initWithFrame: CGRectMake(0, 0, SCREEN_WIDTH_IPHONE, SCREEN_HEIGTH_IPHONE)
andPhotoOverlay: [dict objectForKey:#"imageUrl"]];
[overlay setUserInteractionEnabled: NO];
UIImagePickerController * picker = [[UIImagePickerController alloc] init];
switch (barThing.tag)
{
case 0: [picker setSourceType: UIImagePickerControllerSourceTypeCamera];
[picker setShowsCameraControls: YES];
[picker setCameraOverlayView: overlay];
break;
case 1: [picker setSourceType: UIImagePickerControllerSourceTypeSavedPhotosAlbum];
[picker.view addSubview: overlay];
[overlay setAlpha: 0.5f];
break;
}
[picker setDelegate: self];
[picker setAllowsEditing: YES];
[picker setNavigationBarHidden: YES];
[picker setWantsFullScreenLayout: YES];
[self presentModalViewController:picker animated:YES];
[picker release];
}
Question
What is the correct way to allow a user to select a photo from the PhotoLibrary with an Overlay using UIImagePickerControllerSourceTypeSavedPhotosAlbum?
Resolved
Basically, I needed to write 3 separate classes and combine them to create my own custom photo editing view, which also saves pinch / zoom / rotate edits.
I ended up writing several classes:
An OverlayView class which is a UIView and simply retrieves the .png image with transparency and is the bottom-most layer.
An InteractiveWallpaper class which is a UIImageView and handles all of the touch events, including the transformation events.
And finally, an EditingView class which is a UIViewController. This adds the 2 views previously mentioned as well as saves the photo that the user edited.
This also allowed me to customize the behavior of the view. When the user touches the imported photo, the top-most photo decreases it's alpha value, allowing the user to still see the overlay while the imported photo is more visible.

Resources