views:

85

answers:

2

I am working with images of size 2 to 4MB. I am working with images of resolution 1200x1600 by performing scaling, translation and rotation operations. I want to add another image on that and save it to photo album. My app is crashing after i successfully edit one image and save to photos. Its happening because of images size i think. I want to maintain the 90% of resolution of the images.

I am releasing some images when i get memory warning. But still it crashes as i am working with 2 images of size 3MB each and context of size 1200x1600 and getting a image from the context at the same time.

Is there any way to compress images and work with it?

+3  A: 

I doubt it. Even compressing and decompressing an image without doing anything to it loses information. I suspect that any algorithms to manipulate compressed images would be hopelessly lossy.

Having said that, it may be technically possible. For instance, rotating a Fourier transform also rotates the original image. But practical image compression isn't usually as simple as just computing a Fourier transform.

Alternatively, you could write piecemeal algorithms that chop the image up into bite-sized pieces, transform the pieces and reassemble them afterwards. You might also provide a real-time view of the process by applying the same transform to a smaller version of the full image.

Marcelo Cantos
Why downvote a perfectly good answer? At least have the decency to leave a comment
pheelicks
A: 

The key will be never to full decode the entire image into memory at full size.

  1. If you need to display the image, there's no reason to do that at full size -- the display on the iPhone is too small to take advantage of that. For image objects that are for display, decode the image in scaled down form.

  2. For processing, you will need to write custom code that works on a stream of pixels rather than an in-memory array. I don't know if this is available on the iPhone already, but you can write it yourself by writing to the libpng library API directly.

For example, your code right now probably looks something like this (pseudo code)

img = ReadImageFromFile("image.png")
img2 = RotateImage(img, 90)
SaveImage(img2, "image2.png")

The key thing to understand, is that in this case, img is not the data in the PNG file (2MB), but the fully uncompressed image (~6mb). RotateImage (or whatever it's called) returns another image of about this same size. If you are scaling up, it's even worse.

You want code that looks more like this (but there might not be any API's for you to do it -- you might have to write it yourself)

imgPixelGetter = PixelDecoderFromFile("image.png")
imgPixelSaver = OpenImageForAppending("image2.png") 
w = imgPixelGetter.Width
h = imgPixelGetter.Height

// set up a 90 degree rotate
imgPixelSaver.Width = h
imgPixelSaver.Height = w

// read each vertical scanline of pixels
for (x = 0; x < w; ++x) {
    pixelRect = imgPixelGetter.ReadRect(x, 0, 1, h) // x, y, w, h
    pixelRect.Rotate(90); // it's now got a width of h and a height of 1
    imgPixelSaver.AppendScanLine(pixelRect)
}

In this algorithm, you never had the entire image in memory at once -- you read it out piece by piece and saved it. You can write similar algorithms for scaling and cropping.

The tradeoff is that it will be slower than just decoding it into memory -- it depends on the image format and the code that's doing the ReadRect(). Unfortunately, PNG is not designed for this kind of access to the pixels.

Lou Franco