Joel Derfner
Joel Derfner

Reputation: 2207

How do I create a UIImage bigger than the device screen?

I'm working on an iPhone app that can create pictures and post them to Facebook and Instagram.

The correct size for Facebook photos seems to be 350x350, and indeed this code creates a 350x350 image exactly how I want:

-(UIImage *)createImage {
    UIImageView *v = [[UIImageView alloc] initWithFrame:CGRectMake(0, screenHeight/2-349, 349, 349)];
    v.image = [UIImage imageNamed:@"backgroundForFacebook.png"];  //"backgroundForFacebook.png" is 349x349.

    //This code adds some text to the image.

    CGSize dimensions = CGSizeMake(screenWidth, screenHeight);
    CGSize imageSize = [self.ghhaiku.text sizeWithFont:[UIFont fontWithName:@"Georgia"
                                                                       size:mediumFontSize]
                                     constrainedToSize:dimensions lineBreakMode:0];
    int textHeight = imageSize.height+16;
    UITextView *tv = [self createTextViewForDisplay:self.ghhaiku.text];
    tv.frame = CGRectMake((screenWidth/2)-(self.textWidth/2),s creenHeight/3.5,
                          self.textWidth/2 + screenWidth/2, textHeight*2);
    [v addSubview:tv];

    //End of text-adding code

    CGRect newRect = CGRectMake(0, screenHeight/2-349, 349, 349);
    UIGraphicsBeginImageContext(newRect.size);
    [[v layer] renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *myImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    [v removeFromSuperview];
    return myImage;
}

But when I use the same code to create an Instagram image, which needs to be 612x612, I get the text only, no background image:

-(UIImage *)createImageForInstagram {
    UIImageView *v = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 612, 612)];
    v.image = [UIImage imageNamed:@"backgroundForInstagram.png"];  //"backgroundForInstagram.png" is 612x612.

    //...text-adding code...

    CGRect newRect = CGRectMake(0, 0, 612, 612);
    UIGraphicsBeginImageContext(newRect.size);
    [[v layer] renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *myImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    [v removeFromSuperview];
    return myImage;
}

What am I doing wrong, and how do I fix it?

(While I'm at it, I'll also say that I'm very new to using graphic contexts, so if there's any awkwardness in the code I'd appreciate your pointing it out.)

EDIT: Now I've reduced the two methods to one, and this time I don't even get the text. Argh!

-(UIImage *)addTextToImage:(UIImage *)myImage withFontSize:(int)sz {
    NSString *string=self.displayHaikuTextView.text;
    NSString *myWatermarkText = [string stringByAppendingString:@"\n\n\t--haiku.com"];
    NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:[UIFont fontWithName:@"Georgia" 
                                                                                     size:sz],
                                                                     NSFontAttributeName, 
                                                                     nil];
    NSAttributedString *attString = [[NSAttributedString alloc] initWithString:myWatermarkText attributes:attrs];
    UIGraphicsBeginImageContextWithOptions(myImage.size,NO,1.0);
    [myImage drawAtPoint: CGPointZero];
    NSString *longestLine = ghv.listOfLines[1];
    CGSize sizeOfLongestLine = [longestLine sizeWithFont:[UIFont fontWithName:@"Georgia" size:sz]];
    CGSize siz = CGSizeMake(sizeOfLongestLine.width, sizeOfLongestLine.height*5);
    [attString drawAtPoint: CGPointMake(myImage.size.width/2 - siz.width/2, myImage.size.height/2-siz.height/2)];
    myImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return myImage;
}

When I pass the arguments [UIImage imageNamed:"backgroundForFacebook.png"] (an image 349x349) and 12, everything is fine. I get the picture. When I pass the arguments [UIImage imageNamed:"backgroundForInstagram.png"] (an image 612x612) and 24, nothing doing.

Right now I'm just putting the text on the smaller image (@"backgroundForFacebook.png") and then resizing it, but that makes the text blurry, which I don't like.

EDIT: Just to cover the basics, here are images of 1) the method in which I call this method (to check the spelling) and 2) the Supporting Files and the Build Phases (to show the image is actually there). I also tried assigning longestLine a non-variable NSString. No luck. :(

enter image description here

build phases

enter image description here

FURTHER EDIT: Okay, logging the size and scale of the images as I go during addTextToImage: above, here's what I get for the smaller image, the one that's working:

2013-02-04 22:24:09.588 GayHaikuTabbed[38144:c07] 349.000000, 349.000000, 1.000000

And here's what I get for the larger image--it's a doozy.

Feb  4 22:20:36 Joels-MacBook-Air.local GayHaikuTabbed[38007] <Error>: CGContextGetFontRenderingStyle: invalid context 0x0
Feb  4 22:20:36 Joels-MacBook-Air.local GayHaikuTabbed[38007] <Error>: CGContextSetFillColorWithColor: invalid context 0x0

//About thirty more of these.

Feb  4 22:20:36 Joels-MacBook-Air.local GayHaikuTabbed[38007] <Error>: CGBitmapContextCreate: unsupported parameter combination: 0 integer bits/component; 0 bits/pixel; 0-component color space; kCGImageAlphaNoneSkipLast; 2448 bytes/row.
Feb  4 22:20:36 Joels-MacBook-Air.local GayHaikuTabbed[38007] <Error>: CGContextDrawImage: invalid context 0x0
Feb  4 22:20:36 Joels-MacBook-Air.local GayHaikuTabbed[38007] <Error>: CGBitmapContextCreateImage: invalid context 0x0

Upvotes: 2

Views: 943

Answers (3)

john.k.doe
john.k.doe

Reputation: 7563

i always back up to the obvious questions:

  • is your image actually properly called/spelled backgroundForInstagram.png?
  • have you properly added it to your project?
  • when added, did it copied to the device in the copy steps of the build phases?
  • what's in the ghv at the time of the call in the edited code?
  • what's in item[1] of ghv.lines at the time of that rendering?

these are the things i would look at in terms of debugging this code.

Upvotes: 0

Mutawe
Mutawe

Reputation: 6524

Try This

-(UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
//UIGraphicsBeginImageContext(newSize);
UIGraphicsBeginImageContextWithOptions(newSize, NO, 10.0);//  10.0 means 10 time bigger
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}

Upvotes: 0

Aaron Brager
Aaron Brager

Reputation: 66244

Step through the code. After you create myImage, go into the console and look at myImage.size and myImage.scale. Multiply the size numbers by the scale.

If your background image is Retina-quality, your image is actually 1224 x 1224.

From the UIImage docs:

You should avoid creating UIImage objects that are greater than 1024 x 1024 in size. Besides the large amount of memory such an image would consume, you may run into problems when using the image as a texture in OpenGL ES or when drawing the image to a view or layer. This size restriction does not apply if you are performing code-based manipulations, such as resizing an image larger than 1024 x 1024 pixels by drawing it to a bitmap-backed graphics context. In fact, you may need to resize an image in this manner (or break it into several smaller images) in order to draw it to one of your views.

If your image is actually 612 pixels (not points) but your code is rendering it as 1224 pixels, you can just change the scale property to 1.0.

If your image is actually 1224 pixels, you'll need to do something else, like

  • put your code on a bitmap-backed graphics context (i.e., calling UIGraphicsBeginImageContext around the offending code)
  • displaying a smaller version to the user

However, if your image is for Instagram, it should not be 1224 x 1224 :-)

Update: I noticed your app is haiku-related, so here is the answer in haiku format:

Big UIImage?

Bitmap-backed graphics context

Or shrink to 612

Upvotes: 1

Related Questions