6

I have calculated image size in bytes by converting image into NSData and its data length got wrong value.

    NSData *data = UIImageJPEGRepresentation(image,0.5);
    NSLog(@"image size in bytes %lu",(unsigned long)data.length);
Nagendra
  • 357
  • 2
  • 13
  • What are you getting for a `.length` value? If 0, is `data` non-`nil`? – Todd Lehman Jun 02 '14 at 04:57
  • I got non-zero value. e.g. I converted image of size 2,18,169 bytes to NSData and got data length of 127201 bytes. – Nagendra Jun 02 '14 at 05:57
  • When you say “image of size 218169 bytes” do you mean that the UIImage was that size? How did you create the UIImage and how did you measure its size? In any case, could it be possible that the loss/shrinkage is due to the compression quality setting of 0.5? What happens when you pass 1.0 instead of 0.5? 0.75? 0.25? – Todd Lehman Jun 02 '14 at 07:42
  • NSData *data = UIImageJPEGRepresentation(image,1); NSLog(@"bytes of ImageData is %lu",(unsigned long)data.length); if(data.length <= 204800){ }else{ data = UIImageJPEGRepresentation(image,1); while (data.length / 1000 >= 200) { image = [self imageWithImage:image andWidth:image.size.width/2 andHeight:image.size.height/2]; data = UIImageJPEGRepresentation(image,1); } NSData *data1 = UIImageJPEGRepresentation(image,1); NSLog(@"image size after compression %lu",(unsigned long)data1.length); } – Nagendra Jun 02 '14 at 09:17
  • please check the code given. I need to send an image to server and it should be less than 200KB. for that I converted UIImage to data and checking length of data is less than or equal to 204800. if length is greater than 204800 image has to be compressed. I have given image of size 218169bytes(shown in details), its data of length returns 127201bytes so the condition fails. – Nagendra Jun 02 '14 at 09:27
  • I see. Well, that could actually be correct. A JPEG compression quality setting of 1.0 doesn't necessarily cause the original lossless image to be produced on output. I believe it is still capable of compressing somewhat (in this case about 58% of original size). – Todd Lehman Jun 02 '14 at 17:52
  • Is the input image a JPEG file as well? – YogevSitton Jun 07 '14 at 05:41
  • yes. its a JPEG image – Nagendra Jun 08 '14 at 00:17
  • So there is nothing wrong at all. The imagem was compressed, so the size should be smaller, isn't it? – VitorMM Jun 08 '14 at 15:22
  • of course, I tried with UIImagePNGRepresenation property also. It didn't return exact value. When I convert an image into nsdata and its length should be equal to size of image in byte, isn't it?? – Nagendra Jun 09 '14 at 03:57

1 Answers1

1

Actually, the UIImage.length function here is not returning the wrong value, its just the result of the lossy conversion/reversion from a UIImage to NSData.

Setting the compressionQuality to the lowest compression possible of 1.0 in UIImageJpegRepresentation will not return the original image. Although the image metadata is stripped in this process, the function can and usually will yield an object larger than the original. Note that this increase in filesize does NOT increase the quality of the image from the compressed original either. Jpegs are highly compressed to begin with, which is why they are used so often, and the function is uncompressing it and then recompressing it. Its kind of like getting botox after age has stretched your body out, it might look similar to the original, but the insides are just not as as good as they used to be.

You could use a lower compressionQuality conditionally on larger files, close to 1.0, as the quality will drop off quickly. Other than that, depending on the final purpose of your images, the only other option would be to resize the image or adjust its resolution, perhaps in addition to adjusting the compression ratio. This change will exponentially curtail data usage. Web and mobile usage typically don't need the resolution as something like images meant for digital print.

You can write some code that adjusts each image and NSData representation only as much as needed to fit its individual data constraint.

Ataraxia64
  • 11
  • 2