Why is CGsize too small when I use UIImage? - iphone

I'm trying to load an image, then grab the size of it so that I can use it in a resizing algorithm.
when I use the following code in ViewdidLoad
UIImage *image = [UIImage imageNamed:#"photo1.png"];
self.imageView = [[UIImageView alloc] initWithImage:image];
[self.scrollView addSubview:self.imageView];
self.imageView.frame = (CGRect){.origin=CGPointMake(0.0f, 0.0f), .size=image.size};
I then need to grab the frame from viewwillappear
CGSize trial = self.imageView.frame.size;
CGRect scrollViewFrame = self.scrollView.frame;
This is what I get.
Why is the scrollviewframe have a size of 0,0?

Related

Trying to overlap two images and showing a overlapped imaged in a third image

I am trying to overlap two local images and trying to show the overlapped one in third image.
I am using this code but simulator shows nothing.
- (void)viewDidLoad
{
[super viewDidLoad];
image1 = [[UIImage alloc]init];
image1 = [UIImage imageNamed:#"iphone.png"];
imageA = [[UIImageView alloc]initWithImage:image1];
[self merge];
}
-(void)merge
{
CGSize size = CGSizeMake(320, 480);
UIGraphicsBeginImageContext(size);
CGPoint thumbPoint = CGPointMake(0,0);
imageview.image = imageA.image;
[imageA.image drawAtPoint:thumbPoint];
imageB = [[UIImage alloc]init];
imageB = [UIImage imageNamed:#"Favorites.png"];
CGPoint starredPoint = CGPointMake(0, 0);
[imageB drawAtPoint:starredPoint];
UIImage *imageC = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
imageview.image = imageC;
[self.view addSubview:imageview];
}
I can't figure out/don't know where i am making mistake.
Any help would be appreciable.
Remove all the code from every where except the below code in Merge.
-(void)merge
{
CGSize size = CGSizeMake(320, 480);
UIGraphicsBeginImageContext(size);
CGPoint point1 = CGPointMake(0,0);
// The second point has to be some where different than the first point, other wise, the second image will be above the first image, and you wont even know that the two images are there.
CGPoint point2 = CGPointMake(100,100);
UIImage *imageOne = [UIImage imageNamed:#"Image1.png"];
[imageOne drawAtPoint:point1];
UIImage *imageTwo = [UIImage imageNamed:#"Image2.png"];
// If you want the above image to have some blending, then you can do some thing like below.
// [imageTwo drawAtPoint:point2 blendMode:kCGBlendModeMultiply alpha:0.5];
[imageTwo drawAtPoint:point2];
UIImage *imageC = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *iv = [[UIImageView alloc] initWithFrame:CGRectMake(100,100,200,200)];
iv.image=imageC;
[self.view addSubview:iv];
}
here's a general purpose "merge" function wrote as a UIImage category... allows image overlay/underlay.
http://saveme-dot-txt.blogspot.com/2011/06/merge-image-function.html

How can I dynamically set the size of the imageView according to the size of the image

I user Interface Builder to layout my view and image view. I put a imageView on the view and set it as an outlet. The problem is that no matter what size of image (768*1024、1024*700) I set in my program:
self.imageView.image = [UIImage imageNamed:self.filename];
The size to be on the screen is always the size of the imageView I set in the Interface Builder. How can I dynamically set the size of the imageView according to the size of the image? Thanks!
Something like:
UIImageView *imageView = [[UIImageView alloc] init];
UIImage *image = [UIImage imageNamed:#"image.png"];
CGSize imageSize = [image size];
imageView.frame = CGRectMake(0, 0, imageSize.width, imageSize.height);
UIImage *image = [UIImage imageNamed:self.filename];
CGFloat width = image.size.width;
CGFloat height = image.size.height;
self.imageView.frame = CGRectMake(x, y , width, height);
You could subclass your image and do the following override for eachTime a new image is set :
#interface MyImageSubClass : UIImageView;
#end
#implementation MyImageSubClass
- (void)setImage:(UIImage *)image {
// Let the original UIImageView parent class do its job
[super image];
// Now set the frame according to the image size
// and keeping the original position of your image frame
if (image) {
CGRect r = self.frame;
CGSize imageSize = [image size];
self.frame = (r.origin.x, r.origin.y, imageSize.width, imageSize.height);
}
}
#end
UIImage *buttonImage2=[UIImage imageNamed:#"blank_button_blue.png"];
oButton=[[UIButton alloc] init];
// [oButton setImage:buttonImage2 forState:UIControlStateNormal];
[oButton setFrame:CGRectMake(0, 0, buttonImage2.size.width, buttonImage2.size.height)];
UIImage* sourceImage = [UIImage imageNamed:self.filename];;
CGRect rect;
rect.size.width = CGImageGetWidth(sourceImage.CGImage);
rect.size.height = CGImageGetHeight(sourceImage.CGImage);
[ yourimageview setframe:rect];

How to stretch Image to fill the Label Width set in Background in UILabel?

I have simple View based application. I had taken only UILabel on it.
Following is my code in viewDidLoad:
lblBack.textColor = [UIColor blueColor];
UIImage *img = [UIImage imageNamed:#"cn3.png"];
lblBack.backgroundColor = [UIColor colorWithPatternImage:img];
lblBack.text = #"Hello World!!!...";
// UIImageView *imgView = [[UIImageView alloc] initWithImage:img];
//
// CGRect rect = CGRectMake(0, 0, lblBack.frame.size.width, lblBack.frame.size.height);
// [imgView setFrame:rect];
// NSLog(#"Rect : %#",NSStringFromCGRect(rect));
// [img drawInRect:rect];
// imgView.contentMode = UIViewContentModeScaleAspectFill;
// imgView.contentMode = UIViewContentModeScaleAspectFit;
// imgView.contentMode = UIViewContentModeScaleToFill;
// [lblBack addSubview:imgView];
Comments shows some of the things that i have tried. I am getting following output:
In this one image is repeated 3 times. But I want that image should be stretched to fill the Label width.
I have referred some of the previous links that shows me to add Image in background and use clearColor for UILabel. Also seen example of Adding custom view in Background. But all this I dont want to use unless I dont have other solutions...
I just want to perform all things on UILabel only.... no other control except UIImage or UIImageView i want to use..
Dhiren try this code :
UIImage *img = [UIImage imageNamed:#"cab.png"];
CGSize imgSize = testLabel.frame.size;
UIGraphicsBeginImageContext( imgSize );
[img drawInRect:CGRectMake(0,0,imgSize.width,imgSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
testLabel.backgroundColor = [UIColor colorWithPatternImage:newImage];
I have tested this code.
Porting over Maulik's answer to Swift 2.2, you get the following code:
var img: UIImage = UIImage(named: "cabImage")!
var imgSize: CGSize = testLabel.frame.size
UIGraphicsBeginImageContext(imgSize)
img.drawInRect(CGRectMake(0, 0, imgSize.width, imgSize.height))
var newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext();
testLabel.backgroundColor = UIColor(patternImage: newImage)
Personally tested to be working!

How can I resize my UIImage?

Here is the code I am using to resize my UIImage, but unfortunately it isn't working:
UIImage *cellImage = [UIImage imageNamed:#"warning.png"];
CGRect cropRect = CGRectMake(0.0, 0.0, 12.0, 12.0);
CGImageRef croppedImage = CGImageCreateWithImageInRect([cellImage CGImage], cropRect);
UIImageView *myImageView = [[UIImageView alloc] initWithFrame:cropRect];
[myImageView setImage:[UIImage imageWithCGImage:croppedImage]];
CGImageRelease(croppedImage);
Why does this code not work?
Thanks
HI try this:-
UIGraphicsBeginImageContext(CGSizeMake(50,50));
[[UIImage imageNamed:#"warning.png"] drawInRect: CGRectMake(0, 0,50,50)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Are you forgetting to add myImageView as a subview of your main view or another visible view? E.g.
[cell.contentView addSubview:myImageView];
This would explain why nothing appears.
However, CGImageCreateWithImageInRect() crops the image within the rect if your rect is smaller than the image. To resize the UIImage itself, see: The simplest way to resize an UIImage?
However, it's easiest if you just let the UIImageView handle the resizing if you don't actually need the UIImage itself resized.
UIImage *cellImage = [UIImage imageNamed:#"warning.png"];
CGRect cropRect = CGRectMake(0.0, 0.0, 12.0, 12.0);
CGImageRef croppedImage = CGImageCreateWithImageInRect([cellImage CGImage], CGRectMake(0.0f,0.0f,cellImage.size.width,cellImage.size.height));
UIImageView *myImageView = [[UIImageView alloc] initWithFrame:cropRect];
[myImageView setImage:[UIImage imageWithCGImage:croppedImage]];
CGImageRelease(croppedImage);
[cell.contentView addSubview:myImageView];
See:
UITableViewCell Class Reference: contentView
I don't know why that doesn't work but try using UIGraphicsBeginImageContext and UIGraphicsEndImageContext instead, UIGraphicsBeginImageContext takes a size.

How to make something like iPhone Folders?

I'm wanting to know if there's a way I can transform my view to look something like iPhone folders. In other words, I want my view to split somewhere in the middle and reveal a view underneath it. Is this possible?
EDIT:
Per the suggestion below, I could take a screenshot of my application by doing this:
UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Not sure what to do with this, however.
EDIT:2
I've figured out how to add some shadows to my view, and here's what I've achieved (cropped to show relevant part):
EDIT:3
http://github.com/jwilling/JWFolders
the basic thought will be to take a picture of your current state and split it somewhere. Then animate both parts by setting a new frame. I don't know how to take a screenshot programmatically so I can't provide sample code…
EDIT: hey hey it's not looking great but it works ^^
// wouldn't be sharp on retina displays, instead use "withOptions" and set scale to 0.0
// UIGraphicsBeginImageContext(self.view.bounds.size);
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, 0.0);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *f = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGRect fstRect = CGRectMake(0, 0, 320, 200);
CGRect sndRect = CGRectMake(0, 200, 320, 260); // was 0,200,320,280
CGImageRef fImageRef = CGImageCreateWithImageInRect([f CGImage], fstRect);
UIImage *fCroppedImage = [UIImage imageWithCGImage:fImageRef];
CGImageRelease(fImageRef);
CGImageRef sImageRef = CGImageCreateWithImageInRect([f CGImage], sndRect);
UIImage *sCroppedImage = [UIImage imageWithCGImage:sImageRef];
CGImageRelease(sImageRef);
UIImageView *first = [[UIImageView alloc]initWithFrame:fstRect];
first.image = fCroppedImage;
//first.contentMode = UIViewContentModeTop;
UIImageView *second = [[UIImageView alloc]initWithFrame:sndRect];
second.image = sCroppedImage;
//second.contentMode = UIViewContentModeBottom;
UIView *blank = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 460)];
blank.backgroundColor = [UIColor darkGrayColor];
[self.view addSubview:blank];
[self.view addSubview:first];
[self.view addSubview:second];
[UIView animateWithDuration:2.0 animations:^{
second.center = CGPointMake(second.center.x, second.center.y+75);
}];
You can uncomment the two .contentMode lines and the quality will improve but in my case the subview has an offset of 10px or so (you can see it by setting a background color to both subviews)
//EDIT 2: ok found that bug. Had used the whole 320x480 screen, but had to cut off the status bar so it should be 320x460 and all is working great ;)
Instead of taking a snapshot of the view, you could use a separate view for each row of icons. You'll have to do a bit more work with repositioning stuff, but the rows won't be static when the folder is open (in other words, they'll keep redrawing as necessary).
I took relikd's code as a base and made it a bit more dynamic.
You can specify split position and direction when calling the function and I added a boarder to the split images.
#define splitAnimationTime 0.5
- (void)split:(SplitDirection)splitDirection
atYPostition:(int)splitYPosition
withRevealedViewHeight:(int)revealedViewHeight{
// wouldn't be sharp on retina displays, instead use "withOptions" and set scale to 0.0
// UIGraphicsBeginImageContext(self.view.bounds.size);
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, 0.0);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *f = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGRect fullScreenRect = [self getScreenFrameForCurrentOrientation];
CGRect upperSplitRect = CGRectMake(0, 0,fullScreenRect.size.width, splitYPosition);
CGRect lowerSplitRect = CGRectMake(0, splitYPosition, fullScreenRect.size.width, fullScreenRect.size.height-splitYPosition);
CGImageRef upperImageRef = CGImageCreateWithImageInRect([f CGImage], upperSplitRect);
UIImage *upperCroppedImage = [UIImage imageWithCGImage:upperImageRef];
CGImageRelease(upperImageRef);
CGImageRef lowerImageRef = CGImageCreateWithImageInRect([f CGImage], lowerSplitRect);
UIImage *lowerCroppedImage = [UIImage imageWithCGImage:lowerImageRef];
CGImageRelease(lowerImageRef);
UIImageView *upperImage = [[UIImageView alloc]initWithFrame:upperSplitRect];
upperImage.image = upperCroppedImage;
//first.contentMode = UIViewContentModeTop;
UIView *upperBoarder = [[UIView alloc]initWithFrame:CGRectMake(0, splitYPosition, fullScreenRect.size.width, 1)];
upperBoarder.backgroundColor = [UIColor whiteColor];
[upperImage addSubview:upperBoarder];
UIImageView *lowerImage = [[UIImageView alloc]initWithFrame:lowerSplitRect];
lowerImage.image = lowerCroppedImage;
//second.contentMode = UIViewContentModeBottom;
UIView *lowerBoarder = [[UIView alloc]initWithFrame:CGRectMake(0, 0, fullScreenRect.size.width, 1)];
lowerBoarder.backgroundColor = [UIColor whiteColor];
[lowerImage addSubview:lowerBoarder];
int reveledViewYPosition = splitYPosition;
if(splitDirection==SplitDirectionUp){
reveledViewYPosition = splitYPosition - revealedViewHeight;
}
UIView *revealedView = [[UIView alloc]initWithFrame:CGRectMake(0, reveledViewYPosition, fullScreenRect.size.width, revealedViewHeight)];
revealedView.backgroundColor = [UIColor scrollViewTexturedBackgroundColor];
[self.view addSubview:revealedView];
[self.view addSubview:upperImage];
[self.view addSubview:lowerImage];
[UIView animateWithDuration:splitAnimationTime animations:^{
if(splitDirection==SplitDirectionUp){
upperImage.center = CGPointMake(upperImage.center.x, upperImage.center.y-revealedViewHeight);
} else { //assume down
lowerImage.center = CGPointMake(lowerImage.center.x, lowerImage.center.y+revealedViewHeight);
}
}];
}
This means I can call it like this:
[self split:SplitDirectionUp atYPostition:500 withRevealedViewHeight:200];
I used these conveniance functions in the updated split function:
- (CGRect)getScreenFrameForCurrentOrientation {
return [self getScreenFrameForOrientation:[UIApplication sharedApplication].statusBarOrientation];
}
- (CGRect)getScreenFrameForOrientation:(UIInterfaceOrientation)orientation {
UIScreen *screen = [UIScreen mainScreen];
CGRect fullScreenRect = screen.bounds;
BOOL statusBarHidden = [UIApplication sharedApplication].statusBarHidden;
//implicitly in Portrait orientation.
if(orientation == UIInterfaceOrientationLandscapeRight || orientation == UIInterfaceOrientationLandscapeLeft){
CGRect temp = CGRectZero;
temp.size.width = fullScreenRect.size.height;
temp.size.height = fullScreenRect.size.width;
fullScreenRect = temp;
}
if(!statusBarHidden){
CGFloat statusBarHeight = 20;
fullScreenRect.size.height -= statusBarHeight;
}
return fullScreenRect;
}
and this enum:
typedef enum SplitDirection
{
SplitDirectionDown,
SplitDirectionUp
}SplitDirection;
Adding a return to normaal function and adding the arrow would be a great addition.