3

Problem Resume:

I take a photo with camera or chose one from the library, then add some UITextFields to it (next to UIImageView with the chosen picture), create one UIImage of it all, and then I want to share this, particularly on Facebook and on Twitter. I am able to do this, however the quality of the image drops significantly. How can I adjust the code so that the quality stays on top?


Long description with code and images

First of all, I chose between camera and library. Then, after I pick an image in some way, I get it with

- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info

method, where I assign the image to my global UIImage *chosenImage, with which I use it afterwards.

Then, I add the chosenImage to the UIImageView, and as a sibling, I add an UITextField, like this:

UIImageView *chosenImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, actualHeight - 50)];
[chosenImageView setBackgroundColor:[UIColor clearColor]];
[chosenImageView setContentMode:UIViewContentModeScaleAspectFill];
[chosenImageView setClipsToBounds:YES];
[chosenImageView setImage:chosenImage];        

UITextField *textFieldName = [[UITextField alloc] initWithFrame:CGRectMake(15, 15, 290, 30)];
[textFieldName setBackgroundColor:[UIColor blueColor]];
[textFieldName setDelegate:self];
[textFieldName setTag:-1];
[textFieldName setText:textName];
[textFieldName sizeToFit];
[textFieldName setContentScaleFactor:2.0];

[pageView addSubview:textFieldName];
[pageView addSubview:chosenImageView];

After this, I have a 'share this!' button which, after clicked, presents the possibility to share the image to Facebook and Twitter. I then get the UIImage *imageToShare with this method to convert the UIView to UIImage (which seems to be working alright, imho):

- (UIImage *)changeViewToImage:(UIView *)view 
{

    UIGraphicsBeginImageContextWithOptions([view bounds].size, NO, 0);
    [[view layer] renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}


It seems that the quality of the shared picture is the same for Facebook and Twitter, and the same in this case means really bad.

the code I use for twitter sharing:

SLComposeViewController *tweetSheet = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
[tweetSheet setInitialText:@""];
[tweetSheet addImage:imageToShare];

[tweetSheet setCompletionHandler:^(SLComposeViewControllerResult result) {

    [self dismissViewControllerAnimated:YES completion:nil];

}];

[self presentViewController:tweetSheet animated:YES completion:nil];

and the code I use for Facebook share:

NSDictionary *params = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:UIImagePNGRepresentation(imageToShare), imageDescription, nil] forKeys:[NSArray arrayWithObjects:@"source", @"message", nil]];

[FBRequestConnection startWithGraphPath:@"me/photos" parameters:params HTTPMethod:@"POST" completionHandler:^(FBRequestConnection *connection, id result, NSError *error)
{
     [[[UIAlertView alloc] initWithTitle:@"Success!" message:@"Your photo was successfully posted to your Facebook Wall" delegate:nil cancelButtonTitle:@"Ok :)" otherButtonTitles:nil, nil] show];

     [self returnFromShareView];

}];


However, I've added some code to save the imageToShare to the documents:

NSData *data = UIImagePNGRepresentation(imageToShare);

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0]; //Get the docs directory
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"currentImage.png"]; //Add the file name
[data writeToFile:filePath atomically:YES]; //Write the file

and when I look it up there, it looks fairly fine! Which really makes me wonder why I don't use an envelope with printed picture (the one saved to the documents, of course!), and don't send it to Menlo Park, CA and South of Market, CA instead of trying to solve this ridiculous issue.


Now come the pictures!

umh.. So after I tried to upload the images here, the uploading thingy turned the .png image to horrible quality as well!!! Aagh, I thought stackOverflow is with me!

Anyways, here are the pictures (uploaded here), and corresponding links, which shows the actual images, on my server (which I hope won't destroy them as well)


Picture uploaded to Facebook: Facebook image on my server Facebook picture


Picture uploaded to Twitter: Twitter image on my server Twitter picture


Picture from the documents: Picture from the documents on my server (there is a huge difference!) Documents image

So, does anybody know what settings should I chose for the image in the code to make the quality (even after .jpg compression, which is done everywhere it seems, even here) at least somehow better? And as it seems to me, it happens only on the solid background with text on it (when I tried to upload an image without the background, it looked better, but there must be a way how to make it look better with background as well)

Thanks!

EDIT As it turns out, the problem might not be with the sharing stuff, but with the jpeg compression itself. As it states here in the answer: Facebook: Ways to preserve image quality of uploaded images?,

"JPEG is not suitable for images with text, large blocks of color, or simple shapes, because crisp lines will blur and colors can shift. http://graphicssoft.about.com/od/graphicformats/f/summary.htm "

So I guess there is no solution, as Facebook, Twitter and even stack.imgur use jpeg compression, and as long as there will be an 'image with text, large blocks of color, or simple shapes', it'll come badly. Too bad.

Community
  • 1
  • 1
Gyfis
  • 1,174
  • 1
  • 14
  • 35
  • Did you tried to use `UIImageJPEGRepresentation (UIImage *image, CGFloat compressionQuality);`? That allows you to change quality of image by changing compression rate. – Ömer Faruk Almalı May 01 '14 at 19:36
  • I did try that indeed, and it was to no good. Also, one would guess that using PNG representation should create a high-enough quality image, pretty much the same as JPEG representation with compressionQuality equal to one hundred percent, yet it failed as well. – Gyfis Jun 09 '14 at 14:51
  • Similar question: http://stackoverflow.com/q/10966089/448734 – Bryan Jan 17 '15 at 19:28

1 Answers1

0

JPEG compression works best for continuous tone imagery such as photos. It dos not work well with areas of solid color and sharp traditions such as text. Png/Gif works much better. There are some formats that deal with this better such as Google WebP which Facebook considered using but abandoned.

You best best is to stick with JPEG and play with the JPEG encoding setting but there are a few things you can do. Adjust your font either with the built in iOS fonts or use your own custom font. Since sharp transition of solid color cause a problem, avoid using Serif fonts. Also the fatter the font and larger it is the better. IOS supports custom fonts so play around with different open source fonts and find one at the biggest size you can accept. Follow this article

http://codewithchris.com/common-mistakes-with-adding-custom-fonts-to-your-ios-app/.

Another thing that help is anti aliasing. This is where the edge colors are blurred making the text seem more readable(over simplification). The text will not be anti aliased and you can not easily force anti aliasing but you could fake it. Create the text at a larger size (2 to 3x) in a separate image with transparency and scale it down before adding it over the picture. The image interpolation will blur the images giving you a poor mans anti aliasing.

David Berger
  • 766
  • 5
  • 10