UniversalTransTestViewController.h
#import <UIKit/UIKit.h> #import "ImageProcess.h" #define KFrame 20 @class ImageProcess; @interface UniversalTransTestViewController : UIViewController { UIImage *fromImage; UIImage *toImage; UIImage *ruleImage; UIImage *DestImage; UIImageView *drawImageView; ImageProcess *imgS1Proc; ImageProcess *imgS2Proc; ImageProcess *imgRuleProc; ImageProcess *imgDestProc; NSCondition *timerCondition; unsigned char *pixelDataS1; unsigned char *pixelDataS2; unsigned char *pixelDataRule; unsigned char *pixelDataDest; int pixelPosition[480][320]; int bank[480][320]; BOOL isRunning; NSTimer *timer; float countTime; int lim; } - (void)initImageView:(UIImage *)image; - (void)setTransAtLayer:(int)index method:(NSString *)method time:(int)time rule:(NSString *)ruleImageName; - (void)processImage; @end
UniversalTransTestViewController.m
#import "UniversalTransTestViewController.h" @implementation UniversalTransTestViewController - (void)viewDidLoad { fromImage = [UIImage imageNamed:@"Car2.jpg"]; toImage = [UIImage imageNamed:@"Car1.jpg"]; DestImage = nil; isRunning = YES; timerCondition = [[NSCondition alloc]init]; [self initImageView:fromImage]; [self setTransAtLayer:0 method:@"universal" time:2000 rule:@"r2.png"]; } - (void)initImageView:(UIImage *)image { drawImageView = [[UIImageView alloc] initWithImage:fromImage]; drawImageView.frame = CGRectMake((self.view.bounds.size.width - fromImage.size.width) / 2, (self.view.bounds.size.height - fromImage.size.height) / 2, fromImage.size.width, fromImage.size.height); CGAffineTransform rotate = CGAffineTransformMakeRotation(-1.57); drawImageView.transform = rotate; [self.view addSubview:drawImageView]; [drawImageView release]; } - (void)setTransAtLayer:(int)index method:(NSString *)method time:(int)time rule:(NSString *)ruleImageName { if([method isEqualToString:@"universal"]) { ruleImage = [UIImage imageNamed:ruleImageName]; countTime = 0; lim = 0; imgS1Proc = [[ImageProcess alloc] initWithImage:fromImage]; imgS2Proc = [[ImageProcess alloc] initWithImage:toImage]; imgRuleProc = [[ImageProcess alloc] initWithImage:ruleImage]; imgDestProc = [[ImageProcess alloc] initWithImage:fromImage]; pixelDataS1 = [imgS1Proc GetBegin]; pixelDataS2 = [imgS2Proc GetBegin]; pixelDataRule = [imgRuleProc GetBegin]; pixelDataDest = [imgDestProc GetBegin]; for (int i = 0; i < 480; i++) for (int j = 0; j < 320; j++) { pixelPosition[i][j] = (j * 480 + i) << 2; bank[i][j] = 0; } [NSThread detachNewThreadSelector:@selector(transImage) toTarget:self withObject:nil]; timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(TimerClock:) userInfo:nil repeats:YES]; [timer fire]; } } - (void)TimerClock:(id)sender { [timerCondition broadcast]; } - (void)transImage { isRunning = YES; while (countTime < 2300) { [timerCondition wait]; lim += 255 / (2 * KFrame); [self processImage]; countTime += 1000 / KFrame; } [timer invalidate]; isRunning = NO; } - (void)processImage { NSLog(@"begin"); for (int i = 0; i < 480; i++) { for (int j = 0; j < 320; j++) { if(bank[i][j] < 1) { int count = pixelPosition[i][j]; if(pixelDataRule[count] < lim) { pixelDataDest[count] = pixelDataS2[count]; pixelDataDest[count + 1] = pixelDataS2[count + 1]; pixelDataDest[count + 2] = pixelDataS2[count + 2]; bank[i][j]++; } } } } NSLog(@"end"); if(DestImage != nil) [DestImage release]; DestImage = [imgDestProc getImage]; [self performSelectorOnMainThread:@selector(ChangeImage) withObject:nil waitUntilDone:NO]; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { static int num = 0; if(isRunning == NO) { countTime = 0; lim = 0; [imgDestProc release]; imgDestProc = [[ImageProcess alloc] initWithImage:fromImage]; for (int i = 0; i < 480; i++) for (int j = 0; j < 320; j++) { bank[i][j] = 0; } [imgRuleProc release]; switch (num) { case 0: imgRuleProc = [[ImageProcess alloc] initWithImage:[UIImage imageNamed:@"r1.png"]]; break; case 1: imgRuleProc = [[ImageProcess alloc] initWithImage:[UIImage imageNamed:@"r2.png"]]; break; case 2: imgRuleProc = [[ImageProcess alloc] initWithImage:[UIImage imageNamed:@"r3.png"]]; break; case 3: imgRuleProc = [[ImageProcess alloc] initWithImage:[UIImage imageNamed:@"r5.png"]]; break; default: imgRuleProc = [[ImageProcess alloc] initWithImage:[UIImage imageNamed:@"r5.png"]]; break; } num++; if(num > 3) num = 0; pixelDataRule = [imgRuleProc GetBegin]; pixelDataDest = [imgDestProc GetBegin]; [NSThread detachNewThreadSelector:@selector(transImage) toTarget:self withObject:nil]; timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(TimerClock:) userInfo:nil repeats:YES]; } } - (void)ChangeImage { [drawImageView setImage:DestImage]; } - (void)dealloc { [imgS1Proc release]; [imgS2Proc release]; [imgRuleProc release]; [imgDestProc release]; [super dealloc]; } @end
ImageProcess.h
#import <Foundation/Foundation.h> @interface ImageProcess : NSObject { CGContextRef context; // bitmap context unsigned char *pixelData; // bitmap data pointer int width, height; // bitmap width and height } - (id) initWithImage: (UIImage *) image; // initialize and load image - (unsigned char *)colorAtX:(int)x y:(int)y; // get pixel color - (unsigned char *)GetBegin; - (UIImage *)getImage; // get image - (void)dealloc; // dealloc @end
ImageProcess.m
#import "ImageProcess.h" @implementation ImageProcess // create BitmapContext with UIImage and use 'pixelData' as the data pointer - (id) initWithImage: (UIImage *) image { self = [super init]; if(!self) { return nil; } CGColorSpaceRef colorSpace; int bitmapByteCount; int bitmapBytesPerRow; // bitmap settings context = NULL; width = image.size.width; height = image.size.height; bitmapBytesPerRow = (width * 4); bitmapByteCount = (bitmapBytesPerRow * height); // create color space colorSpace = CGColorSpaceCreateDeviceRGB(); // create data pointer free(pixelData); pixelData = malloc(bitmapByteCount); // create bitmap context CGContextRelease(context); context = CGBitmapContextCreate (pixelData, width, height, 8, bitmapBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast); CGColorSpaceRelease(colorSpace); // draw image data to context CGContextDrawImage(context, CGRectMake(0, 0, width, height), image.CGImage); pixelData = CGBitmapContextGetData(context); return self; } - (unsigned char *)colorAtX:(int)x y:(int)y { return & (pixelData[(y * width + x) << 2]); } - (unsigned char *)GetBegin { return pixelData; } - (UIImage *)getImage { CGImageRef cgImg = CGBitmapContextCreateImage(context); UIImage *localImg = [[[UIImage alloc] initWithCGImage:cgImg] autorelease]; CGImageRelease(cgImg); return localImg; } - (void)dealloc { [super dealloc]; free(pixelData); CGContextRelease(context); } @end
示例图: