1

I am new to Objective-C, but I need to write a fast method, which will divide an UIImage into square blocks of fixed size, and then mix them. I have already implemented it in the following way:

  1. Get UIImage
  2. Represent it as PNG
  3. Convert it to RGBA8 unsigned char array
  4. For each block, calculate it's coordinates, then xor each pixel with pixel from block that gets replaced
  5. Assemble that RGBA8 meat back into a new UIImage
  6. Return it

It works as intended, but it is extremely slow. It takes about 12 seconds to process single 1024x768 PNG on iPhone 4S. Inspector shows that methods somehow connected to PNGRepresentation, eat up about 50% of total run time.

Will it possibly be faster, if I use Quartz2D here somehow? I am now simply trying to copy/paste a single rectangle from and to my _image, but I don't know how to go further. It returns an UIImage with the _image provided as is, without the blockLayer pasted inside it:

UIGraphicsBeginImageContextWithOptions(CGSizeMake(width, height), YES, 1.0);
CGContextRef context                     = UIGraphicsGetCurrentContext();

/* Start drawing */

//Draw in my image first
[_image drawAtPoint:CGPointMake(0,0) blendMode:kCGBlendModeNormal alpha:1.0];

//Here I am trying to make a 400x400 square, starting presumably at the origin
CGLayerRef blockLayer = CGLayerCreateWithContext(context, CGSizeMake(400, 400), NULL);
//Then I attempt to draw it back at the middle
CGContextDrawLayerAtPoint(context, CGPointMake(1024/2, 768/2), blockLayer);

CGContextSaveGState(context);

/* End drawing */

//Make UIImage from context
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

return newImage;
Kai
  • 424
  • 5
  • 16

1 Answers1

2

You can follow these steps to do what you need:

  • Load the image
  • Split it up into squareshow?
  • Create a CALayer for each image, setting the location to the place of the square in the image before shuffling
  • Go through the layers, and set their positions to their target locations after shuffling
  • Watch the squares moving to their new placeswhat if you don't want the animation?
Community
  • 1
  • 1
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Hmm, but what about the speed? There are usually 12000+ squares 8 by 8 pixels each. – Kai Jul 03 '12 at 19:20
  • @Kai 12000 I did not realize the fragments are that small. For hundreds of layers this should be OK, but I am not certain that it would work for 12000; I would not be surprised if this turns out to be too slow. Did you try running your algorithm against off-screen against a bitmap? – Sergey Kalinichenko Jul 03 '12 at 19:31
  • Yes I did it in my production code, where I manipulate a raw byte array. There, the block coordinate remapping logic is very fast, but data preparing function uses a lot of time for decompressing/compressing PNG data. I think that there might be a faster way to crop and paste squares inside of a UIImage. – Kai Jul 03 '12 at 19:52