iOS UIImage Effects

xArtx

macrumors 6502a
Original poster
Mar 30, 2012
764
1
Hi Guys,
I want to display a short title screen animation as an intro.
Rather than use an array of images stored in my bundle,
and setting a timer to animate the frames, repeat x-number of times, etc.
I have loaded a single image, and used a timer where I can do something
to the image dynamically, and then set it back to the frame,
or I could still do it the usual way, and load different images for the animation
as my timer fires.

What I want to happen, is apply some effect to the image frame by frame,
until the image is destroyed, and then decrement it's transparency to zero.
One example would be to pixellate the image for each frame, until it was
such a mess that you can no longer make out the original image,
but if I were to animate this with any style at all it would require a lot of
images in my bundle if it weren't handled dynamically.

Is there some iOSsy way to slightly mess an image and reuse the result?
I can, and have done this before, by changing data in a bitmap for each frame,
but I have not written the effect I want this time
(making every pixel looking at the colour of it's neighbors or something).
It would be a waste of time, and I don't think I would learn anything putting
in that work, if there is an easy way to do it.

Thanks, Art.
 

Duncan C

macrumors 6502a
Jan 21, 2008
853
0
Northern Virginia
Hi Guys,
I want to display a short title screen animation as an intro.
Rather than use an array of images stored in my bundle,
and setting a timer to animate the frames, repeat x-number of times, etc.
I have loaded a single image, and used a timer where I can do something
to the image dynamically, and then set it back to the frame,
or I could still do it the usual way, and load different images for the animation
as my timer fires.

What I want to happen, is apply some effect to the image frame by frame,
until the image is destroyed, and then decrement it's transparency to zero.
One example would be to pixellate the image for each frame, until it was
such a mess that you can no longer make out the original image,
but if I were to animate this with any style at all it would require a lot of
images in my bundle if it weren't handled dynamically.

Is there some iOSsy way to slightly mess an image and reuse the result?
I can, and have done this before, by changing data in a bitmap for each frame,
but I have not written the effect I want this time
(making every pixel looking at the colour of it's neighbors or something).
It would be a waste of time, and I don't think I would learn anything putting
in that work, if there is an easy way to do it.

Thanks, Art.

Wherever possible you want to avoid redrawing your image every frame. That maximizes the hit on the CPU and data exchange between the CPU and GPU. You are better off using Core Image or some other GPU-based approach to do the data manipulation for you.

Any ready-made solution is going to use the graphics hardware rather than the CPU.

I believe there is a pixellate Core Image filter. You might want to survey Core Image filters before you get too far into doing this yourself.

It would also be possible to do whatever you want using OpenGL, but the learning curve for OpenGL is VERY steep.

You could also, as you say, write code to alter the bitmap data directly, but expect that to be slower and much more CPU-intensive than using graphics APIs like Core Image or OpenGL.
 

xArtx

macrumors 6502a
Original poster
Mar 30, 2012
764
1
I think I'm wanting to draw circles on it as well, this will be fun...
It's only an intro, I was trying to cheap out.
 

xArtx

macrumors 6502a
Original poster
Mar 30, 2012
764
1
This is no good because it copies the image?
Code:
- (UIImage *)DrawCircleOnImage:(UIImage *)image
{
	UIGraphicsBeginImageContext(image.size);
	[image drawAtPoint:CGPointZero];
	CGContextRef ctx = UIGraphicsGetCurrentContext();
	[[UIColor yellowColor] setStroke];
    
	// 7 pixels from circle border
	CGRect circleRect = CGRectMake(422, 312,136,136);
	circleRect = CGRectInset(circleRect, 7, 7);
    
	CGContextStrokeEllipseInRect(ctx, circleRect);
	UIImage *retImage = UIGraphicsGetImageFromCurrentImageContext();
	UIGraphicsEndImageContext();
	return retImage;
}
 

xArtx

macrumors 6502a
Original poster
Mar 30, 2012
764
1
I would recommend that you don't delay your users from being able to use your app.
I can't do that this time.
It's for the emulator I've mentioned in another thread,
it's not my app holding it up (the iOS boot screen isn't shown for long),
it's the emulator loading from floppy disk.
After seeing what I did last night I would make the choice to leave it there though.

The disk file is linear of course, but the emulator still uses a floppy disk interface
in every sense.
It still has to seek the file to the correct tracks and sectors when it reads or
writes that file.

So what I've done so far is drawn concentric circles over a 3.5inch floppy
disk graphic representing the current track being accessed,
It's a very nice effect, I want to go the whole way and divide those
tracks into sectors too, and only display the current arc of the circle.

Tell me I'm not creative :)
 

Duncan C

macrumors 6502a
Jan 21, 2008
853
0
Northern Virginia
I can't do that this time.
It's for the emulator I've mentioned in another thread,
it's not my app holding it up (the iOS boot screen isn't shown for long),
it's the emulator loading from floppy disk.
After seeing what I did last night I would make the choice to leave it there though.

The disk file is linear of course, but the emulator still uses a floppy disk interface
in every sense.
It still has to seek the file to the correct tracks and sectors when it reads or
writes that file.

So what I've done so far is drawn concentric circles over a 3.5inch floppy
disk graphic representing the current track being accessed,
It's a very nice effect, I want to go the whole way and divide those
tracks into sectors too, and only display the current arc of the circle.

Tell me I'm not creative :)
Look at using a CAShapeLayer and manipulating the path that is assigned to the layer. This is very powerful and very efficient. You can get all kinds of animation effects.
 

xArtx

macrumors 6502a
Original poster
Mar 30, 2012
764
1
Rough idea since the app might not make it:


I am going to submit it before doing all of the work I'm prepared to do for that reason.


Look at using a CAShapeLayer and manipulating the path that is assigned to the layer. This is very powerful and very efficient. You can get all kinds of animation effects.
I will, & thanks, but more interested in improvements for my GPS app when I get back to it
than worrying about an intro screen for this one...

If this does get in, I'm sure I can contribute something to the emulator.
I'm in my element there.
 
Last edited by a moderator:

Twimfy

macrumors 6502a
Sep 11, 2011
881
227
UK
I have to ask, why not create the animation in something a little easier and then just load a small video file using MPMoviePlayer?
 

xArtx

macrumors 6502a
Original poster
Mar 30, 2012
764
1
I have to ask, why not create the animation in something a little easier and then just load a small video file using MPMoviePlayer?
Because it isn't an animation, it's the real position of the drive head,
and the read speed varies depending on the speed of the device.
 

Twimfy

macrumors 6502a
Sep 11, 2011
881
227
UK
Because it isn't an animation, it's the real position of the drive head,
and the read speed varies depending on the speed of the device.
Ah I see, apologies, I missed that in your explanation.
 

xArtx

macrumors 6502a
Original poster
Mar 30, 2012
764
1
Ah I see, apologies, I missed that in your explanation.
I have learned a bit.
The disk file is always 880K, no matter how much information is on the disk,
the file always contains the full disk structure.
It has it's own boot block, and file allocation table that cannot be dodged
just because you have a fast computer.

I say "can't be dodged" for emulation.
For a single bundled game which is the only way that will work for App Store,
it would be possible to bypass the boot by loading a snapshot of all of the
emulated computer's RAM and register contents when the game has already loaded.
That would be a linear file.

I am working on a better visual reason not to bypass the boot.