24

I would like to apply a filter to a photo from the user's library then write it back to disk. I'm using UIImageJPEGRepresentation. This function takes a UIImage and a compressionQuality value between 0.0 and 1.0. Because I want to preserve the original quality, I set it to 1.0. But I found this actually creates an image file that's larger in file size than the original, somewhat significantly larger even. I noticed in Apple's Sample Photo Editing Extension app they always set the quality to 0.9. I tried that and it does output a file size close to the original photo file size. This doesn't make sense to me. Can someone explain this? Is it appropriate to always use 0.9? Does the iOS camera compress it using that value and thus 0.9 is the original quality? Or why isn't 0.9 actually 1.0, if there's nothing that's better quality?

NSData *renderedJPEGData = UIImageJPEGRepresentation(image, 0.9f);
Jordan H
  • 52,571
  • 37
  • 201
  • 351
  • 2
    0.9 will result in loss of quality in the image - there is some level of compression being applied, so you will be losing data. If you need to preserve the original quality, then use UIImagePNGRepresentation. JPG is a lossy format. Using PNG will result in a larger file size, but the saved results will be the same quality as the input image. – rickerbh Oct 13 '14 at 02:10
  • @rickerbh But photos taken with the iPhone camera are output as JPEG not PNG – Jordan H Oct 13 '14 at 04:39
  • 3
    Sure. But if you want to retain the same quality you shouldn't re-encode the image with a lossy format. If you're happy with some quality loss (which would typically not be noticed by humans viewing the image), use JPG. I typically use a value like 0.7 as I find it usually results in an image that isn't terrible, but usually gives a good file size saving. If you want to see more about recompression, check out the "Recompression" section at http://www.ampsoft.net/webdesign-l/jpeg-compression.html – rickerbh Oct 13 '14 at 04:47
  • I would like to add one more point here. I did save `NSData` return from `UIImageJPEGRepresentation()` and save it to document directory, Also create `UIImage`object from this data and save it to photo library. Both have same image data but images generated have different sizes (size difference >50 Kb). Also i haven't provide an extension for that. Not able to figure out what happens. May be while saving image in photo library it will provide some quality expansion or similar. – Kampai Oct 13 '14 at 06:24
  • @rickerbh Sorry I'm just now getting to this. Using `UIImagePNGRepresentation` results in an error: `Error Domain=NSCocoaErrorDomain Code=-1 "The operation couldn’t be completed. (Cocoa error -1.` Here's how I wrote it out to disk: `pngData.writeToURL(contentEditingOutput.renderedContentURL, options: NSDataWritingOptions.AtomicWrite, error: &error)` Know what's going on? – Jordan H Oct 27 '14 at 02:48
  • @Joey This seems like a different question. You should post a new question and post the relevant code, including how you generate the file system URL. – rickerbh Oct 27 '14 at 23:04

3 Answers3

2

This is an old question and you've probably worked this out for yourself, but if anyone's still interested, this might help.

(I'm not a JPEG expert)

UIImageJPEGRepresentation isn't taking into consideration how the image may have been compressed in the past, it's just compressing the image that it has at the time.

You mention a photo that's "from the user's library". The user could have any image in their library, compressed at any compressionQuality.

To try to keep the image at the same file size, you'd need to know how it was originally saved, and even if you use the same compressionQuality, you will likely result in a different file size because the data that's being compressed is different.

As for using a compressionQuality of 0.9 for saving images, it depends on how much you value the quality of your image versus how much you space you want to use. 0.7 seems to be often suggested as a good balance.

I'm not sure how much the iOS camera app compresses the image (if at all) and I'm not sure that it is guaranteed to be the best possible quality. If it is using 0.9, you could always create an app that takes a photo and compresses it less before saving.

I hope that helps.

Josh Paradroid
  • 1,172
  • 18
  • 45
0

FWIW, I converted the same 600x800 image using AsJPEG() with these compressions to see the sizes & gauge the visible quality loss:
1.0: 642KB
0.9: 212KB
0.7: 144KB
0.5: 86KB

Visible quality didn't suffer much, even at 0.5 (!). I'll be using these on a webpage where visible perfection isn't critical, so I'll use 0.5 to gain the benefit of the small (13%) filesize.
Of course, your mileage may vary :)

dlchambers
  • 3,511
  • 3
  • 29
  • 34
-5

You can convert image in PNG representation for original image quality.

UIImagePNGRepresentation(image)
New-Learner
  • 229
  • 1
  • 3
  • 15