// // ElisEffect.m // Elis Colors // // Created by 柳 on 09/09/15. // Copyright 2009 __MyCompanyName__. All rights reserved. // #import "ElisEffect.h" @implementation ElisEffect // Elisでは、種類がエフェクトを隠蔽する! - (id)initWithName:(NSString*)aname { [super init]; filter = [[CIFilter filterWithName:aname] retain]; [filter setDefaults]; params = [[NSMutableDictionary alloc] init]; attrs = [filter attributes]; generator = YES; colors = [[NSMutableArray alloc] init]; vecs = [[NSMutableArray alloc] init]; affine = [[NSMutableArray alloc] init]; // アフィン変換なエフェクトなんて一つしか使わないのに、これってどうなの。 NSDictionary* inputKeys = [filter inputKeys]; id key, input; for(key in inputKeys){ if([key isEqualToString:@"inputImage"]){ generator = NO; continue; } input = [attrs valueForKey:key]; if([[[attrs valueForKey:key] valueForKey:kCIAttributeClass] isEqualToString:@"CIColor"]){ [self setEffectTrueValueForTime: [NSString stringWithFormat:@"%@ %@", key, @"red"] value:1.0 time:QTZeroTime]; [self setEffectTrueValueForTime: [NSString stringWithFormat:@"%@ %@", key, @"green"] value:1.0 time:QTZeroTime]; [self setEffectTrueValueForTime: [NSString stringWithFormat:@"%@ %@", key, @"blue"] value:1.0 time:QTZeroTime]; [colors addObject:key]; [colors addObject:[NSString stringWithFormat:@"%@ %@", key, @"red"]]; [colors addObject:[NSString stringWithFormat:@"%@ %@", key, @"green"]]; [colors addObject:[NSString stringWithFormat:@"%@ %@", key, @"blue"]]; } else if([[[attrs valueForKey:key] valueForKey:kCIAttributeClass] isEqualToString:@"CIVector"]){ [self setEffectTrueValueForTime: [NSString stringWithFormat:@"%@ %@", key, @"X"] value:[[input valueForKey:kCIAttributeDefault] X] time:QTZeroTime]; [self setEffectTrueValueForTime: [NSString stringWithFormat:@"%@ %@", key, @"Y"] value:[[input valueForKey:kCIAttributeDefault] Y] time:QTZeroTime]; [vecs addObject:key]; [vecs addObject:[NSString stringWithFormat:@"%@ %@", key, @"X"]]; [vecs addObject:[NSString stringWithFormat:@"%@ %@", key, @"Y"]]; } else if([[[attrs valueForKey:key] valueForKey:kCIAttributeClass] isEqualToString:@"NSAffineTransform"]){ // [self setEffectTrueValueForTime: // [NSString stringWithFormat:@"%@ %@", key, @"Position X"] value:0.0 time:QTZeroTime]; [self setEffectTrueValueForTime: [NSString stringWithFormat:@"%@ %@", key, @"Scale"] value:1.0 time:QTZeroTime]; [self setEffectTrueValueForTime: [NSString stringWithFormat:@"%@ %@", key, @"Angle"] value:0.0 time:QTZeroTime]; [affine addObject:key]; // [affine addObject:[NSString stringWithFormat:@"%@ %@", key, @"Position X"]]; [affine addObject:[NSString stringWithFormat:@"%@ %@", key, @"Scale"]]; [affine addObject:[NSString stringWithFormat:@"%@ %@", key, @"Angle"]]; } else if([[[attrs valueForKey:key] valueForKey:kCIAttributeClass] isEqualToString:@"NSNumber"]){ [self setEffectTrueValueForTime:key value:[[input valueForKey:kCIAttributeDefault] floatValue] time:QTZeroTime]; } } name = [attrs valueForKey:kCIAttributeFilterDisplayName]; // [inputKeys release]; return self; } - (void)setEffectValue:(NSString*)key value:(id)v { [filter setValue:v forKey:key]; } // valueは0.0 ~ 1.0。 - (void)setEffectValueForTime:(NSString *)key value:(float)v time:(QTTime)time { ElisKeyframe *k; float max, min; if([colors indexOfObject:key] != NSNotFound){ max = 255.0; min = 0.0; }else if([vecs indexOfObject:key] != NSNotFound){ max = ProjectMovieSize.size.width*2; min = -ProjectMovieSize.size.width*2; }else if([affine indexOfObject:key] != NSNotFound){ if([key isEqualToString:@"inputTransform Angle"]){ max = ANGLE_MAX; min = ANGLE_MIN; } else { max = 5.0; min = 0.1; } }else{ max = [[[attrs valueForKey:key] valueForKey:kCIAttributeSliderMax] floatValue]; min = [[[attrs valueForKey:key] valueForKey:kCIAttributeSliderMin] floatValue]; } // 適切な値へマップする。 v = (max - min)*v + min; if([params valueForKey:key]){ k = [params valueForKey:key]; [k setValueForTime:v time:time]; } else{ k = [[ElisKeyframe alloc] init]; [k setValueForTime:v time:time]; [params setValue:k forKey:key]; } } // valueは生の値を渡す。 - (void)setEffectTrueValueForTime:(NSString *)key value:(float)v time:(QTTime)time { ElisKeyframe *k; if([params valueForKey:key]){ k = [params valueForKey:key]; [k setValueForTime:v time:time]; } else{ k = [[ElisKeyframe alloc] init]; [k setValueForTime:v time:time]; [params setValue:k forKey:key]; } } - (float)getEffectValue:(NSString*)key forTime:(QTTime)time { float max, min; if([colors indexOfObject:key] != NSNotFound){ max = 255.0; min = 0.0; }else if([vecs indexOfObject:key] != NSNotFound){ max = ProjectMovieSize.size.width*2; min = -ProjectMovieSize.size.width*2; }else if([affine indexOfObject:key] != NSNotFound){ if([key isEqualToString:@"inputTransform Angle"]){ max = ANGLE_MAX; min = ANGLE_MIN; } else { max = 5.0; min = 0.1; } }else{ max = [[[attrs valueForKey:key] valueForKey:kCIAttributeSliderMax] floatValue]; min = [[[attrs valueForKey:key] valueForKey:kCIAttributeSliderMin] floatValue]; } if([params valueForKey:key]) return ([[params valueForKey:key] getValueForTime:time] - min)/(max - min); return 0; } - (float)getEffectTrueValue:(NSString*)key forTime:(QTTime)time { if([params valueForKey:key]) return [[params valueForKey:key] getValueForTime:time]; return 0; } - (void)setInputImage:(CIImage*)cm { if(!generator) [filter setValue:cm forKey:@"inputImage"]; } - (CIImage*)getImage:(QTTime)time { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; NSString *key, *sub; CIColor *col; CIVector* vec; int i, size = [colors count]; for(i = 0; i < size; i += 4){ key = [colors objectAtIndex:i]; col = [CIColor colorWithRed:[[params valueForKey:[colors objectAtIndex:i+1]] getValueForTime:time]/255.0 green:[[params valueForKey:[colors objectAtIndex:i+2]] getValueForTime:time]/255.0 blue:[[params valueForKey:[colors objectAtIndex:i+3]] getValueForTime:time]/255.0]; [filter setValue:col forKey:key]; } size = [vecs count]; for(i = 0; i < size; i += 3){ key = [vecs objectAtIndex:i]; vec = [CIVector vectorWithX:[[params valueForKey:[vecs objectAtIndex:i+1]] getValueForTime:time] Y:[[params valueForKey:[vecs objectAtIndex:i+2]] getValueForTime:time]]; [filter setValue:vec forKey:key]; } size = [affine count]; for(i = 0; i < size; i += 3){ key = [affine objectAtIndex:i]; NSAffineTransform* aft = [NSAffineTransform transform]; [aft scaleBy:[[params valueForKey:[affine objectAtIndex:i+1]] getValueForTime:time]]; [aft rotateByDegrees:[[params valueForKey:[affine objectAtIndex:i+2]] getValueForTime:time]*ANGLE_MAX*2]; [filter setValue:aft forKey:key]; } for(key in params){ if([colors indexOfObject:key] == NSNotFound && [vecs indexOfObject:key] == NSNotFound && [affine indexOfObject:key] == NSNotFound) [filter setValue:[NSNumber numberWithFloat:[[params valueForKey:key] getValueForTime:time]] forKey:key]; } [pool release]; return [filter valueForKey:@"outputImage"]; } - (NSMutableDictionary*)getParamDictionary { return params; } - (NSString*)getName { return name; } - (void)removeKeyframe:(NSString*)key { float v = [[params valueForKey:key] getValueForTime:QTZeroTime]; ElisKeyframe* k = [[ElisKeyframe alloc] init]; [k setValueForTime:v time:QTZeroTime]; [params setValue:k forKey:key]; } @end