Having problems splitting up UIImageView into smaller images - iphone

I'm trying to take a UIImageView, resize that image and display it. Then i want to break up that image into smaller pieces and display them.
The resized image displays correctly but it appears that the "split up" images are too big; i'm thinking they are coming from the original (slightly bigger) image. The following screenshot shows the resized image on the left and the a column of split up images from the left hand side.
The fact that the resized image is displaying correctly and the smaller ones aren't has me confused. Any ideas would be appreciated - or even an alternative. Here is my code:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
width = imgOriginal.frame.size.width;
height = imgOriginal.frame.size.height;
whratio = width/height;
[self getOriginalImageInfo];
[self resizeImage];
resizedImage = [self resizeImage];
}
-(void) getOriginalImageInfo {
lblWidth.text = [NSString stringWithFormat:#"%0.2f", width];
lblHeight.text = [NSString stringWithFormat:#"%0.2f", height];
lblWHRatio.text = [NSString stringWithFormat:#"%0.2f", whratio];
}
-(UIImageView*) resizeImage {
if (whratio >= 0.7 && whratio <=0.89) {
imgOriginal.frame = CGRectMake(20, 20, 500, 600);
imgOriginal.autoresizingMask = NO;
float resizedWHRatio = (imgOriginal.frame.size.width)/(imgOriginal.frame.size.height);
lblResizedWidth.text = [NSString stringWithFormat:#"%0.2f", imgOriginal.frame.size.width];
lblResizedHeight.text = [NSString stringWithFormat:#"%0.2f", imgOriginal.frame.size.height];
lblResizedWHRatio.text = [NSString stringWithFormat:#"%0.2f", resizedWHRatio];
return imgOriginal;
}
return nil;
}
- (IBAction)easyPressed:(id)sender {
NSLog(#"Easy button pressed");
CGImageRef original = [resizedImage.image CGImage];
float pieceWidth = (resizedImage.frame.size.width) / 5;
float pieceHeight = (resizedImage.frame.size.height) / 6;
for (int i =0; i<6; i++) {
CGRect rectangle = CGRectMake(0, 0+((float)i*pieceHeight), pieceWidth, pieceHeight);
CGImageRef newTile = CGImageCreateWithImageInRect(original, rectangle);
UIImageView *puzzlePiece = [[UIImageView alloc] initWithFrame:CGRectMake(611, 20+((float)i*pieceHeight), pieceWidth, pieceHeight)];
puzzlePiece.tag = i+1;
puzzlePiece.image = [UIImage imageWithCGImage:newTile];
puzzlePiece.alpha = 0.5;
[puzzlePiece.layer setBorderColor: [[UIColor blackColor] CGColor]];
[puzzlePiece.layer setBorderWidth: 1.0];
[self.view addSubview:puzzlePiece];
}
}

Try applying the same scaling factor to the partial images as you are to the main image!!!
OR
Take the screenshot of the UIImageView being displayed and split that up instead.

Related

Paged UIScrollView with UIImageViews only showing first UIImageVIew

I am working on a paged UIScrollView, but it only wants to show the first UIImageView within it. I add each UIImageView at an offset of the width of the scroll view, so that should create each page. When run, it says the scroll view is the right number of pages, but the images don't show.
Any help would be much appreciated!
int numSlides = NUM_TUTORIAL_SLIDES;
NSString *fileName;
UIImageView *slideImageView;
CGRect slideFrame;
for (int i = 1; i <= numSlides; i++)
{
slideFrame.origin.x = self.tutorialScrollView.frame.size.width * (i-1);
slideFrame.origin.y = 0;
slideFrame.size = self.tutorialScrollView.frame.size;
slideImageView = [[UIImageView alloc] initWithFrame:slideFrame];
if([[AppManager sharedManager] is4inchScreen])
{
fileName = [NSString stringWithFormat:#"Slide%d4in#2x.png", i];
}
else
{
fileName = [NSString stringWithFormat:#"Slide%d#2x.png", i];
}
slideImageView.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:fileName ofType:nil]];
[self.tutorialScrollView addSubview:slideImageView];
[slideImageView release];
}
self.tutorialScrollView.contentSize = CGSizeMake(self.tutorialScrollView.frame.size.width * numSlides, self.tutorialScrollView.frame.size.height);
self.tutorialScrollView.delegate = self;
Maybe change the following code will help
slideImageView.image = [UIImage imageNamed:fileName];
Turns out that the issue had to do with rounding the corners of the scroll view.
I had this code:
//Round header image
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.tutorialScrollView.bounds
byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerTopRight)
cornerRadii:CGSizeMake(DEFAULT_CORNER_RADIUS_HEADER, DEFAULT_CORNER_RADIUS_HEADER)];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.path = maskPath.CGPath;
self.tutorialScrollView.layer.mask = maskLayer;
and apparently that causes issues with the scroll view

fetching image from url is not sharp & clear

I am working on one application where i have to load images from server.
I am trying to load application screenshots from a link of appstore.
I am getting the image but not so sharp & clear. I am fetching the image in background & everything works fine.But the resulted image looks a little blurry. I am testing this image in retina display. Anyone has any idea why it is happening. Any solution will be helpful.
Thanks,
Here is my code for image loading :
// This will create the imageview with required frame & use the url to load the image
-(void)loadAppsScreenShots:(int)i Frame:(CGRect)frame withImageUrl:(NSString *)urlStr
{
UIImageView *appImageView = [[UIImageView alloc] init];
frame.origin.x = 0;
appImageView.frame = frame;
appImageView.tag = i;
sharedImageCache = [ImageCache sharedImageCacheInstance];
UIImage *image1 = [sharedImageCache getCachedImage:[NSString stringWithFormat:#"%#",urlStr]];
if (image1==nil)
{
// Show indicator till image loads
UIActivityIndicatorView *indiView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
indiView.center = CGPointMake(appImageView.frame.size.width/2, appImageView.frame.size.height/2);
[appImageView addSubview:indiView];
[indiView startAnimating];
indiView.hidden = FALSE;
// Show label indicating image loading process
UILabel *loadingLbl = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 25)];
loadingLbl.text = #"";//#"Please wait...";
loadingLbl.center = CGPointMake(appImageView.frame.size.width/2 + 5, appImageView.frame.size.height/2 + 23);
loadingLbl.font = [UIFont fontWithName:#"Helvetica-Bold" size:15.0f];
loadingLbl.textAlignment = UITextAlignmentCenter;
loadingLbl.backgroundColor = [UIColor clearColor];
loadingLbl.textColor = [UIColor whiteColor];
[appImageView addSubview:loadingLbl];
[appImageView sendSubviewToBack:loadingLbl];
loadingLbl.hidden = FALSE;
// Dictionalry to get all objects & pass it to method where we load the data
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:appImageView forKey:#"imageView"];
if (urlStr != nil) {
[dict setObject:urlStr forKey:#"url"];
}
[dict setObject:indiView forKey:#"indi"];
[dict setObject:loadingLbl forKey:#"loadingLbl"];
[self performSelectorInBackground:#selector(loadImageFromURLAndSaveInDocDir:) withObject:dict];
}
else
{
appImageView.image = image1;
}
[[appView viewWithTag:i] addSubview:appImageView];
[appView bringSubviewToFront:appImageView];
appImageView.contentMode = UIViewContentModeScaleAspectFit;
appImageView=nil;
}
-(void)loadImageFromURLAndSaveInDocDir:(NSMutableDictionary *)dict
{
#autoreleasepool
{
UIImageView *cellImageViewObj = [dict objectForKey:#"imageView"];
NSString *url;
UIActivityIndicatorView *indiview = [dict objectForKey:#"indi"];
UILabel *Lbl = [dict objectForKey:#"loadingLbl"];
if ([dict objectForKey:#"url"])
{
url = [dict objectForKey:#"url"];
// fetch the data
NSURL *imgURL = [NSURL URLWithString:url];
NSData *imgData = [NSData dataWithContentsOfURL:imgURL];
NSString *filename = [Utils getFileNameFromURL:url];
// Cache the image
[sharedImageCache cacheImage:[NSString stringWithFormat:#"%#",filename] :imgData];
UIImage *image1 = [[UIImage alloc] initWithData:imgData];
cellImageViewObj.image = image1;
image1=nil;
}
else {
url = #"";
}
// set the content mode & hide the indicator & label
cellImageViewObj.contentMode = UIViewContentModeScaleAspectFit;
[indiview stopAnimating];
indiview.hidden = TRUE;
Lbl.hidden = TRUE;
dict = nil;
}
}
What is wrong am i doing.
The problem is that you are showing the image at its natural size. On a retina device, you need images which are twice as wide and twice as tall as the view they get drawn into.
Say the image is 200x200 and you are going to show it in a 100x100 view. The proper way to do this is:
get a CGImageRef of the data
create a UIImage using the below method and a scale of 2 (for retina)
(UIImage *)imageWithCGImage:(CGImageRef)imageRef scale:(CGFloat)scale orientation:(UIImageOrientation)orientation
The result is an image sized 100x100 but with a scale of two.
That said, since you specify 'UIViewContentModeScaleAspectFit', you may be able to just take the 200x200 image and had it off to the UIImageView, but in this case you must force the imageView to have a frame.size of 100x100.
If the image size is different than imageview, then you can proportionally scale the server image as per your view.
- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize;
- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize {
UIImage *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 ;
}

iOS Code Displays White Field Rather Than Image Series

The code below is supposed to display a series of images in an infinite, connected loop. Instead, it just displays a totally white field. Thanks to Aaron Hayman for getting me this far.
- (void)layoutScrollImages
{
//Arrangement
NSArray *imageViews = [NSArray arrayWithObjects:#"image1.png", #"image2.png", #"image3.png", nil];
CGRect cRect = scrollView1.bounds;
UIImageView *cView;
for (int i = 0; i < imageViews.count; i++)
{
cView = [imageViews objectAtIndex:i];
cView.frame = cRect;
[scrollView1 addSubview:cView];
cRect.origin.x += cRect.size.width;
}
scrollView1.contentSize = CGSizeMake(cRect.origin.x, scrollView1.bounds.size.height);
scrollView1.contentOffset = CGPointMake(scrollView1.bounds.size.width, 0); //should be the center page in a 3 page setup
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
scrollView1.contentOffset = CGPointMake(scrollView.bounds.size.width, 0);
}
FOLLOW UP:
Nothing I'm doing is making any difference. Currently, my code looks like this, but I'm changing everything I can think of to no avail.
- (void)layoutScrollImages
{
//Horizontal arrangement
NSObject *image1 = #"image1.png";
NSObject *image2 = #"image2.png";
NSObject *image3 = #"image3.png";
NSArray *imageViews = [NSArray arrayWithObjects:image1, image2, image3, nil];
CGRect cRect = scrollView1.bounds;
UIImageView *cView;
for (int i = 0; i < imageViews.count; i++)
{
cView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[imageViews objectAtIndex:i]]];
cView.frame = cRect;
[scrollView1 addSubview:cView];
cRect.origin.x += cRect.size.width;
}
scrollView1.contentSize = CGSizeMake(cRect.origin.x, scrollView1.bounds.size.height);
scrollView1.contentOffset = CGPointMake(scrollView1.bounds.size.width, 0); //should be the center page in a 3 page setup
[self layoutScrollImages];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
scrollView1.contentOffset = CGPointMake(scrollView.bounds.size.width, 0);
}
You never initiate a UIImageView. You want to do something like this:
NSArray *imageViews = [NSArray arrayWithObjects:#"image1.png", #"image2.png", #"image3.png", nil];
CGRect cRect;
UIImageView *cView;
for (int i = 0; i < imageViews.count; i++)
{
cView = [[UIImageView alloc] initWithImage:[UIImage imageName:[imageViews objectAtIndex:i]]];
cRect = cView.frame;
cRect.origin.x += scrollView1.frame.size.width;
cView.frame = cRect;
[scrollView1 addSubview:cView];
NSLog(#"imageView bounds: %#", NSStringFromCGRect(cView.frame));
}
Edit:
Try the above and see if anything shows up. Here are some thoughts:
Are you sure that you aren't setting the imageView to have 0 height/width? I threw in an NSLog statement to the loop. It will print the frame of the imageView.
Have you tried adding the images to self.view instead of scrollView1? That would be a good way to make sure that the problem doesn't have to do with the frame of scrollView1. Or use the following:
NSLog(#"imageView bounds: %#", NSStringFromCGRect(scrollView1.frame));

iphone: how to add text above and below the image in the scrollvew?

I would like to add a page number above the image such as "1 of 50" and description of the image below the image in the scrollview.
I have looked at this LINK but still couldn't figure out how to make it happen.
here is my sample code of the images scrollview. Im trying to find a sample that can add text and scroll with the images
NSUInteger i;
for (i = 1; i <= kNumImages; i++)
{
NSString *imageName = [NSString stringWithFormat:#"images%d.jpg", i];
UIImage *image = [UIImage imageNamed:imageName];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
// setup each frame to a default height and width, it will be properly placed when we call "updateScrollList"
CGRect rect = imageView.frame;
rect.size.height = kScrollObjHeight;
rect.size.width = kScrollObjWidth;
imageView.frame = rect;
imageView.tag = i; // tag our images for later use when we place them in serial fashion
[scrollView1 addSubview:imageView];
[imageView release];
}
UPDATE:
const CGFloat kScrollObjHeight = 320;
const CGFloat kScrollObjWidth = 280.0;
const NSUInteger kNumImages = 50;
- (void)layoutScrollImages
{
UIImageView *view = nil;
NSArray *subviews = [scrollView1 subviews];
// reposition all image subviews in a horizontal serial fashion
CGFloat curXLoc = 0;
for (view in subviews)
{
if ([view isKindOfClass:[UIImageView class]] && view.tag > 0)
{
CGRect frame = view.frame;
frame.origin = CGPointMake(curXLoc, 0);
view.frame = frame;
curXLoc += (kScrollObjWidth);
}
}
- (void)viewDidLoad {
self.view.backgroundColor = [UIColor viewFlipsideBackgroundColor];
// 1. setup the scrollview for multiple images and add it to the view controller
//
// note: the following can be done in Interface Builder, but we show this in code for clarity
[scrollView1 setBackgroundColor:[UIColor blackColor]];
[scrollView1 setCanCancelContentTouches:NO];
scrollView1.indicatorStyle = UIScrollViewIndicatorStyleWhite;
scrollView1.clipsToBounds = YES; // default is NO, we want to restrict drawing within our scrollview
scrollView1.scrollEnabled = YES;
// pagingEnabled property default is NO, if set the scroller will stop or snap at each photo
// if you want free-flowing scroll, don't set this property.
scrollView1.pagingEnabled = YES;
// load all the images from our bundle and add them to the scroll view
NSUInteger i;
for (i = 1; i <= kNumImages; i++)
{
NSString *imageName = [NSString stringWithFormat:#"creative%d.jpg", i];
UIImage *image = [UIImage imageNamed:imageName];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
// setup each frame to a default height and width, it will be properly placed when we call "updateScrollList"
CGRect rect = imageView.frame;
rect.size.height = kScrollObjHeight;
rect.size.width = kScrollObjWidth;
imageView.frame = rect;
imageView.tag = i; // tag our images for later use when we place them in serial fashion
[scrollView1 addSubview:imageView];
[imageView release];
}
[self layoutScrollImages];
I wanted to put this but unable to find the correct position or right offset to display at the top
UILabel * topLabel = [[UILabel alloc] init];
topLabel.text = [NSString stringWithFormat:#"%d of %d", i, kNumImages];
rect.origin.x = offset;
rect.size.height = 30; // however large you need the label to be
topLabel.frame = rect;
offset += 30;
I would think something like this would work:
float offset = 0;
for (NSUInteger i = 1; i <= kNumImages; i++)
{
// load up the image
NSString *imageName = [NSString stringWithFormat:#"images%d.jpg", i];
UIImage *image = [UIImage imageNamed:imageName];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
// image.size is important here and used to determine placement
CGRect rect = imageView.frame;
rect.size = image.size;
// create top label, just basic will need to configure other settings like font
UILabel * topLabel = [[UILabel alloc] init];
topLabel.text = [NSString stringWithFormat:#"%d of %d", i, kNumImages];
rect.origin.x = offset;
rect.size.height = 30; // however large you need the label to be
topLabel.frame = rect;
offset += 30; // adding the label height
// set image frame since we now know the location below top label
rect.size = image.size;
rect.origin.x += offset;
imageView.frame = rect;
imageView.tag = i;
offset += image.size.height; // adding image height
// add bottom label below image
UILabel * bottomLabel = [[UILabel alloc] init];
bottomLabel.text = imageName; // just a sample description
rect.origin.x += offset;
rect.size.height = 30; // however large you need the label to be
bottomLabel.frame = rect;
offset += 30; // adding the label height
[scrollView1 addSubview:topLabel];
[scrollView1 addSubview:imageView];
[scrollView1 addSubview:bottomLabel];
[imageView release];
[topLabel release];
[bottomLabel release];
offset += 20; // arbitrary spacing between images
}

Horizontal UIScrollView and hundreds of thumbnail images in iOS?

I need to create a horizontal UIScrollView which to hold hundreds of thumbnail images, just like a slide of thumbnails.
For example, there will be 10 thumbnails showing in a single screen, each of them are horizontally adjacent to each other.
My problem is that I don't know how to make a horizontal UIScrollView to hold the multiple thumbnails which showing at the same time ?
A sample photo is as below. See the bottom part of the screen.
Thanks.
You can add all the thumbnails programatically to your scrollview and use the setContentSize method of UIScrollView. you have to pass 2 values in contentOffset. 1 for width and 1 for height. Please follow link to explore more on this. If you need further help please leave a comment.
Hope it helps.
Please consider Following example.
- (void)setupHorizontalScrollView
{
scrollView.delegate = self;
[self.scrollView setBackgroundColor:[UIColor blackColor]];
[scrollView setCanCancelContentTouches:NO];
scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
scrollView.clipsToBounds = NO;
scrollView.scrollEnabled = YES;
scrollView.pagingEnabled = YES;
NSUInteger nimages = 0;
NSInteger tot=0;
CGFloat cx = 0;
for (; ; nimages++) {
NSString *imageName = [NSString stringWithFormat:#"image%d.jpg", (nimages + 1)];
UIImage *image = [UIImage imageNamed:imageName];
if (tot==15) {
break;
}
if (4==nimages) {
nimages=0;
}
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
CGRect rect = imageView.frame;
rect.size.height = 40;
rect.size.width = 40;
rect.origin.x = cx;
rect.origin.y = 0;
imageView.frame = rect;
[scrollView addSubview:imageView];
[imageView release];
cx += imageView.frame.size.width+5;
tot++;
}
self.pageControl.numberOfPages = nimages;
[scrollView setContentSize:CGSizeMake(cx, [scrollView bounds].size.height)];
}
I suggest you to look at nimbus
Check out bjhomer's HSImageSidebarView project. It lets you load a scrollview horizontally or vertically and load in the images. Super easy to implement.
First of all, at storyboard drag and drop the scroll view and make the outlet of scrollview named scrollView. Two array one is mutable and one is immutable.
#property(nonatomic,strong)IBOutlet UIScrollView *scrollView;
#property(nonatomic,strong)NSMutableArray *images;
#property(nonatomic,strong)NSArray *imagesName;
The immutable array only store the images which we want to show on the scroll view.Make sure UIscrollview delegate is defined.
In viewcontoller.m file in didload function do following code:
imagesName = [[NSArray alloc]initWithObjects:#"centipede.jpg",#"ladybug.jpg",#"potatoBug.jpg",#"wolfSpider.jpg", #"ladybug.jpg",#"potatoBug.jpg",#"centipede.jpg",#"wolfSpider.jpg",nil];
// mutable array used to show the images on scrollview dynamic becaus after one
// image when scroll other will come
images = [[NSMutableArray alloc]init];
scrollView.delegate = self;
scrollView.scrollEnabled = YES;
int scrollWidth = 120;
scrollView.contentSize = CGSizeMake(scrollWidth,80);
int xOffset = 0;
//the loop go till all images will load
for(int index=0; index < [imagesName count]; index++)
{
UIImageView *img = [[UIImageView alloc] init];
// make the imageview object because in scrollview we need image
img.frame = CGRectMake(5+xOffset, 0, 160, 110);
// the offset represent the values, used so that topleft for each image will
// change with(5+xOffset, 0)and the bottomright(160, 110)
NSLog(#"image: %#",[imagesName objectAtIndex:index]);
img.image = [UIImage imageNamed:[imagesName objectAtIndex:index]];
// The image will put on the img object
[images insertObject:img atIndex:index];
// Put the img object at the images array which is mutable array
scrollView.contentSize = CGSizeMake(scrollWidth+xOffset,110);
//scroll view size show after 125 width the scroll view enabled
[scrollView addSubview:[images objectAtIndex:index]];
// set images on scroll view
xOffset += 170;
}
You can calculate content size width of the scrollview as width = number of images * size of each image. Then set contentSize of the scrollview to this width and the height that you want (scrollView.contentSize = CGSizeMake(width, height))