Resizing Images

Has anyone done any work on resizing images in iOS? I need to resize images that my users capture with their iPhone camera before uploading them to our services. Our services won’t accept an image larger than 10Mb and modern iPhone cameras often return images much larger than this size. Plus it would just take too long and not suit my app’s purposes to upload very large images.

I currently use @Jason King 's excellent iOSKit which has a ScaleImage method using various declares. The problem I’m having is that the images become a little “blocky” / over-sampled after being resized. My users have asked why I don’t just resize the image dimensions, such as the iOS Mail app does when it offers you a choice between small, medium or large image sizes, rather than reducing the quality of the image. I’m not specifically reducing the quality, but something in the UIGraphics methods might be.

I was wondering whether anyone else has had to tackle this issue and whether there might be another way?

I am going to ‘have a go’ here because nobody else has. The whole iOS thing is pretty new but image manipulation is an old subject for me. I took a look at iOSKit ScaleImage because I am toying with iOSKit’s camera support. Essentially it just does a resize and allows you to specify how to interpolate (the rules on what pixel value to use when you scale) - this alone should not cause your image to become blocky unless you are scaling to a very (very!) small size. The scaled image at this point is just a bitmap, there is no compression other than the compression of the original image. So I suspect that if your image is getting ‘blocky’ then it is as a result of whatever you are using to save the scaled image since this is where any compression will be introduced. Check if there is a quality setting in the method call that takes the scaled image and converts to jpeg (or whatever image compression you are using).

With regard to ‘dimensions’ many image files incorporate a pixels per inch (ppi/ dpi) or other measure of dimension. The ppi can be used to size the image for screen or print. For example a 96 pixel high x 96 pixel wide image could be shown as a one inch square on a 96 dpi device but would need to be scaled approx 3x to display as 1 ince on a 300 dpi printer. Just changing the dimensions for an image by changing the pixels per inch will not reduce the file size - What the Mail app could be doing is scale the image and perhaps adjust the ppi so that the same sized image will display but using less pixels, this will have the effect of reducing the bitmap size. Any compression will apply further reduction in size but will lose ‘quality’ if the quality is too low then the image will become visibly ‘blocky’ (mosaic effect).

My guess is that it is not the scaling that is causing the mosaic effect - this would only happen if the image was scaled by an extreme amount although you should check that the scaling is not too extreme, that being good take a look at whatever is compressing the image and check any quality settings. If the images are photographs then jpeg will work best, if they are ‘flatter’ like documents then you can use gif or lzw tiff and single colour (line art) images can use 1bit formats. If you want the best images and you know that you only have 10Mb ‘to spend’ then you could write a method that keeps reducing the size and compression until the 10Mb size is reached, it will be slower to work it out than just using fixed values but you will always get the best image for your 10Mb limit.

HTH

Unrelated to resizing, how are your users getting 10Mb pictures?
My iPhone 6 averages 2-3Mb
My D3000 RAWs average 10Mb

[quote=227813:@Tim Parnell]Unrelated to resizing, how are your users getting 10Mb pictures?
My iPhone 6 averages 2-3Mb
My D3000 RAWs average 10Mb[/quote]

That’s a very good question and you’re right about those sizes - my iPhone 6s images are about the same size as yours. I use the following code to convert an iOSImage into a JPEG in a memory block:

Declare function UIImageJPEGRepresentation lib UIKitLib (obj_id as ptr) as ptr
dim d as new Foundation.NSData(UIImageJPEGRepresentation(image.Handle))

dim mb as MemoryBlock
mb = d.DataMb

You may want to have a look at https://forum.xojo.com/9403-scale-quality-of-canvas-control/0

I don’t know if we have pixel in 64 bit but if so, the algorithms should be fairly easy to port.

Yeah I should explain that the reason I don’t use the native Xojo function to save an iOSImage is that it doesn’t preserved EXIF data, resulting in images that might be upside down depending on how the user held their phone when they took the photo.

OK I think I’ve solved this one. I’ve removed the UIImageJPEGRepresentation declare as I think this was re-processing an image that I had already converted to JPEG. The image sizes are now much more like they should be and the quality is also good. Thanks for the contributions. Sometimes you just need to “talk” these things through. :wink: