ラベル CoreImage の投稿を表示しています。 すべての投稿を表示
ラベル CoreImage の投稿を表示しています。 すべての投稿を表示

2011年1月1日土曜日

Quartz Composer / 床に反射した画

動機
床に反射した画ってどうやってつくるんだろ?


調べた
Quartz ComposerのMusic VisualizerのサンプルであるClub Lisa.qtz(/Developer/Library/Quartz Composer/Examples/Music Visualizers/Club Lisa.qtz)のあれを参考にすればよさそう.


やってみた
肝心なところだけ抜き出すとこんな感じだ(と思う).

(CIからつながっている下側のSpriteのY Positionは-1)

CIのコードがこんな感じだった.

kernel vec4 reflection(sampler image, float brightness, float position)
{
vec2 v = samplerCoord(image);
vec2 s = samplerSize(image);

v.y = s.y - v.y;

vec4 pixel = sample(image, v);
float p = 1. - v.y/(position*s.y);
return vec4(pixel * p * brightness);
}



結果



pmd: 'Lat式ミクVer2.3_White.pmd'(Lat様)('VPVP wiki - モデルデータ/VOCALOID関連'より),
vmd: '恋愛サーキュレーション-ミク.vmd '(せっけんP様)('VPVP wiki - モーションデータ/ダンス')より) ,
感謝 )
動画の場合は'Render in Image'で画を作ってくればよいと思うが,ただそれだとY軸方向の移動で足と影がはなれてしまうのでそのあたり,賢くCropしてくれてY軸の位置情報も出力する道具立てが必要か…ちょっとめんどくさい印象.
方針が間違っているのかしら.

2008年10月19日日曜日

波紋のトランジション

こちらのエントリーをみて,以前書いたこれサンプルが,どれくらい簡単に変更できるか興味がわいたのでやってみた.

まぁ,想像の範囲内,一応以下のように'createTransitionFilter'メソッドだけ変更すればできた.
Transition.m
- (void)createTransitionFilter {
[_transitionFilter release];
_transitionFilter = nil;

_transitionFilter = [[CIFilter filterWithName:@"CIRippleTransition"] retain];
[_transitionFilter setDefaults];
[_transitionFilter setValue:_initialImage
forKey:@"inputImage"];
[_transitionFilter setValue:_finalImage
forKey:@"inputTargetImage"];
[_transitionFilter setValue:_inputShadingImage
forKey:@"inputShadingImage"];
NSRect rect = [_delegate bounds];
[_transitionFilter setValue:[CIVector vectorWithX:rect.origin.x
Y:rect.origin.y
Z:rect.size.width
W:rect.size.height]
forKey:@"inputExtent"];
[_transitionFilter setValue:[CIVector vectorWithX:NSMidX(rect)
Y:NSMidY(rect)
Z:0
W:0]
forKey:@"inputCenter"];
[_transitionFilter setValue:[NSNumber numberWithInt:30]
forKey:@"inputWidth"];
[_transitionFilter setValue:[NSNumber numberWithInt:50]
forKey:@"inputScale"];

}

変更

変更


参考
トランジションフィルタ (Transition Filters)
http://developer.apple.com/jp/documentation/GraphicsImaging/Conceptual/CoreImaging/ci_filters/chapter_5_section_14.html


間違いがあればご指摘いただければ幸いです.

2007年12月8日土曜日

CIFilterのサンプルをつくる.

トランジションでやったのでサンプル的にシンプルなことをやろうと思って作り始めた.
が,CIImageからNSImageの作り方って?みたいなところではまってた.

10.5からはNSBitmapImageRepinitWithCIImage:が付いたということでこれを使ってみた.
とりあえず"BoxBlur".



サンプル (10.5用)
http://y30.net/pg/cocoa_prj/CIFilter_Blur.zip



NSImage* inImage= [[NSImage alloc]
initWithContentsOfFile:@"/Library/Desktop Pictures/Nature/Earth.jpg"];
NSBitmapImageRep* inBitmap= [NSBitmapImageRep imageRepWithData:[inImage TIFFRepresentation]];
[inImage release];

CIImage *inCIImage= [[CIImage alloc] initWithBitmapImageRep:inBitmap];
[inBitmap release];

CIFilter* _blurFilter= [CIFilter filterWithName:@"CIBoxBlur"];
[_blurFilter setDefaults];
[_blurFilter setValue:[NSNumber numberWithInt:20] forKey:@"inputRadius"];

[_blurFilter setValue:inCIImage forKey:@"inputImage"];
CIImage* outCIImage = [_blurFilter valueForKey:@"outputImage"];

NSBitmapImageRep* outBitmap=[[NSBitmapImageRep alloc] initWithCIImage:outCIImage];
[outCIImage release];
NSImage* outImage= [[NSImage alloc] initWithData:[outBitmap TIFFRepresentation]];


他のCIFilterはこちらを参照ください.
Core Image Filter Reference
http://developer.apple.com/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html


変換はいちいちNSBitmapImageRep経由なのは間違っているからだろうか?
NSImage -> NSBitmapImageRep -> CIImage
CIImage -> NSBitmapImageRep -> NSImage

#教えてエラい人.

ちなみに描画するだけならCIImagedrawAtPoint:fromRect:operation:fraction:を呼べば良いです.

2007年7月7日土曜日

トランジションをつくろう.

無駄な作業になりそうだが…
すでにあるトランジションフィルタが気に入らなかったので…

フィルタを2つにした.
1.重ねる画像をズームブラーで動きを付ける.
2.背景画像に最小合成で(白を背景にして)合成.

ブラーの具合を時間にあわせて変化させてみた.


@implementation Transition
...
- (void)createTransitionFilter {
{
[_transitionFilter release];
_transitionFilter = nil;
NSRect rect = [_delegate bounds];
_transitionFilter = [[CIFilter filterWithName:@"CIMinimumCompositing"] retain];
[_transitionFilter setDefaults];
[_transitionFilter setValue:_baseImage forKey:@"inputBackgroundImage"];
}
{
[_transitionFilter2 release];
_transitionFilter2 = nil;
NSRect rect = [_delegate bounds];
_transitionFilter2 = [[CIFilter filterWithName:@"CIZoomBlur"] retain];
[_transitionFilter2 setDefaults];
[_transitionFilter2 setValue:_overlayImage forKey:@"inputImage"];
[_transitionFilter2 setValue:[CIVector vectorWithX:NSMidX(rect) Y:NSMidY(rect) Z:0 W:0] forKey:@"inputCenter"];
}
}
- (void)draw:(NSRect)viewRect {
NSRect rect = [_delegate bounds];
float time = [_animation currentValue];
if ([self reverse]) {
time= 1.0 - time;
}
[_transitionFilter2 setValue:[NSNumber numberWithFloat:(time * 50.0)+10] forKey:@"inputAmount"];
[_transitionFilter setValue:[_transitionFilter2 valueForKey:@"outputImage"] forKey:@"inputImage"];
CIImage * outputCIImage = [_transitionFilter valueForKey:@"outputImage"];
[outputCIImage drawInRect:rect fromRect:NSMakeRect(0, rect.size.height, rect.size.width, -rect.size.height) operation:NSCompositeSourceOver fraction:1.0];
}


#すでに目的を見失っている気がする…

2007年7月4日水曜日

NSViewからNSVIewへのトランジションをCoreImageで/ 6

追記(2008/10/06): サンプルプロジェクトを作った.エントリーと異なる部分もあるが許してください.


具体的な描画部

@implementation TransitionView

- (void)drawRect:(NSRect)rect {
if ([transition isAnimating]==YES) {
[transition draw:[[[self selectedTabViewItem] view] bounds]];
}
}

@end


アニメーション中はtransition側で描かせます

@implementation Transition

- (BOOL)isAnimating {
return (_animation!=nil);
}

- (void)draw:(NSRect)viewRect {
NSRect rect = [_delegate bounds];
float time = [_animation currentValue];
[_transitionFilter setValue:[NSNumber numberWithFloat:time] forKey:@"inputTime"];
CIImage * outputCIImage = [_transitionFilter valueForKey:@"outputImage"];
[outputCIImage drawInRect:rect fromRect:NSMakeRect(0, rect.size.height, rect.size.width, -rect.size.height) operation:NSCompositeSourceOver fraction:1.0];
}

@end

NSAnimationのcurrentValueにてtime変数値を作成.
そのtime変数値をCIFilterに入れて中間画像を得ています.

完結.

NSViewからNSVIewへのトランジションをCoreImageで/ 5

追記(2008/10/06): サンプルプロジェクトを作った.エントリーと異なる部分もあるが許してください.



@interface Transition : NSObject {

NSAnimation *_animation;
id _delegate;

}

#define TRANSITION_DURATION 0.75

@implementation Transition

- (void)reset {
[_initialImage release];
[_finalImage release];
[_transitionFilter release];
[_animation release];
_initialImage = nil;
_finalImage = nil;
_transitionFilter = nil;
_animation = nil;//これの有無でアニメーション中かどうかを判定していします 6参照
}
- (void)start {

//フィルタの作成 4を参照.
...
if(_transitionFilter!=nil) {
_animation = [[TransitionAnimation alloc] initWithDuration:TRANSITION_DURATION animationCurve:NSAnimationEaseInOut];
[_animation setDelegate:_delegate];
[_animation startAnimation];
[self reset];
}
}


_delegateはTransitionViewのインスタンス.


@interface TransitionAnimation : NSAnimation
@end
@implementation TransitionAnimation
- (void)setCurrentProgress:(NSAnimationProgress)progress {
[super setCurrentProgress:progress];
[[self delegate] display]; //[self delegate]==transitionView
}
@end

NSViewからNSVIewへのトランジションをCoreImageで/ 4

追記(2008/10/06): サンプルプロジェクトを作った.エントリーと異なる部分もあるが許してください.


Filter設定部
ここではページめくりのトランジション.

@class CIImage;
@class CIFilter;

@interface Transition : NSObject {

CIImage *_inputShadingImage;
CIFilter *_transitionFilter;

}
@end
@implementation Transition

- (void)start {
[self createTransitionFilter];

//アニメーションのスタート 5を参照
}
- (void)createTransitionFilter {
[_transitionFilter release];
_transitionFilter = nil;
NSRect rect = [_delegate bounds];
_transitionFilter = [[CIFilter filterWithName:@"CIPageCurlTransition"] retain];
[_transitionFilter setDefaults];
[_transitionFilter setValue:_initialImage forKey:@"inputImage"];
[_transitionFilter setValue:_finalImage forKey:@"inputTargetImage"];
[_transitionFilter setValue:_initialImage forKey:@"inputBacksideImage"];
[_transitionFilter setValue:_inputShadingImage forKey:@"inputShadingImage"];
[_transitionFilter setValue:[NSNumber numberWithFloat:M_PI_4] forKey:@"inputAngle"];
[_transitionFilter setValue:[CIVector vectorWithX:rect.origin.x Y:rect.origin.y Z:rect.size.width W:rect.size.height] forKey:@"inputExtent"];
}

@end


"_inputShadingImage"にいれる画像だがよくわからないが表現上大切らしい.
Core Image Fun Houseの画像から転用してみてはどうだろう.とりあえず用意してリソースからゲットしてみる.
    NSBundle *bundle = [NSBundle mainBundle];
NSData *shadingBitmapData = [NSData dataWithContentsOfFile:[bundle pathForResource:@"restrictedshine" ofType:@"tiff"]];
_inputShadingImage = [[[NSBitmapImageRep alloc] initWithData:shadingBitmapData] autorelease];

NSViewからNSVIewへのトランジションをCoreImageで/ 3

追記(2008/10/06): サンプルプロジェクトを作った.エントリーと異なる部分もあるが許してください.


でTransitionクラス.NSViewの画像キャプチャー部


@class CIImage;

@interface Transition : NSObject {

CIImage *_finalImage;
CIImage *_initialImage;

}
@end
@implementation Transition

- (void)captureViewForInitialView:(NSView*)view {
CIImage * image = [self createCoreImage:view];
[_initialImage release];
_initialImage = [image retain];
}
- (void)captureViewForFinalView:(NSView*)view {
CIImage * image = [self createCoreImage:view];
[_finalImage release];
_finalImage = [image retain];
}
- (CIImage *)createCoreImage:(NSView *)view {
NSBitmapImageRep *bitmap= [view bitmapImageRepForCachingDisplayInRect:[view bounds]];
[view cacheDisplayInRect:[view bounds] toBitmapImageRep:bitmap]; //important
CIImage *img= [[CIImage alloc] initWithBitmapImageRep:bitmap];
return img;
}

@end

NSViewからNSVIewへのトランジションをCoreImageで/ 2

追記(2008/10/06): サンプルプロジェクトを作った.エントリーと異なる部分もあるが許してください.



@interface TransitionView : NSTabView

@end
@implementation TransitionView

- (void)selectTabViewItem:(NSTabViewItem *)tabViewItem {
[transition captureViewForInitialView:self]; //切換え前の画像を開始画像として
[super selectTabViewItem:tabViewItem];  //切り替えて
[transition captureViewForFinalView:self]; //切換え後の画像を終了画像として

NSView *finalContentView = [tabViewItem view]; //終了Viewを
[finalContentView setHidden:YES]; //非表示
[transition start]; //アニメーション開始
[finalContentView setHidden:NO]; //表示
[self setNeedsDisplay:YES]; //ってこと.
}

@end

transitionが表すクラスについてはまた後日.

ちなみにこいつを呼び出すときはこうなる.

int pos = [transitionView indexOfTabViewItem:[transitionView selectedTabViewItem]];
pos = (pos==0)?1:0; //いま0なら1を,1なら0を呼ぶようにする.
[transitionView selectTabViewItemAtIndex:pos];

結局,"selectTabViewItemAtIndex"は"selectTabViewItem"を呼び出すので
上記TransitionViewのメソッドが呼ばれるわけです.

NSViewからNSVIewへのトランジションをCoreImageで/ 1

追記(2008/10/06): サンプルプロジェクトを作った.エントリーと異なる部分もあるが許してください.


とりあえず概略
1.[大方針]NSTabViewでViewを2つ用意して切り替える.(Tabは非表示にしきます)
2.NSTabViewの子要素を用意して切り替えメソッドにトランジションを割り込ませる
   参考:“Interface Builder (IB)上の要素の子要素(拡張:extends (java))を作る
      “NSViewからNSVIewへのトランジションをCoreImageで/ 2
3.切換え前のView(NSTabViewItem *)からCIImageを一枚
   参考:“Core ImageのCIImageをNSViewからサクッとつくる
      “NSViewからNSVIewへのトランジションをCoreImageで/ 3
4.切換え後のViewからCIImageを一枚
   参考:“Core ImageのCIImageをNSViewからサクッとつくる
      “NSViewからNSVIewへのトランジションをCoreImageで/ 3
5.こいつをCIFilterのトランジションを用いてつなぐ
   参考:“NSViewからNSVIewへのトランジションをCoreImageで/ 4
6.NSAnimationをつかって切換え時のアニメーション時間制御
   参考:“NSViewからNSVIewへのトランジションをCoreImageで/ 5
7.NSAnimationが"setCurrentProgress"を呼び出すタイミングでトランジション画像を描画
   参考:“NSViewからNSVIewへのトランジションをCoreImageで/ 5
8.このときNSAnimationが持っている0-1.0への時間をCIFilterに与えると中間画像が得られる.
   参考:“NSViewからNSVIewへのトランジションをCoreImageで/ 6
9.中間画像をdrawメソッドで描いて(正確にはdrawの中で8をします)実現.
   参考:“NSViewからNSVIewへのトランジションをCoreImageで/ 6

参考ソース:
Core Image NSView Transitions [fernLightning]
http://www.fernlightning.com/doku.php?id=randd:fancy:start
ありがとうございます.

Core ImageのCIImageをNSViewからサクッとつくる.

追記(2008/12/3): まるきり忘れていたのですが「どうやって記録すれば良いか悩む」は記録して解決している.



です.NSViewで描いているものからNSViewで描く物へのトランジションをしたいのが野望.
しらべてようやくできたんだけどどうやって記録すれば良いか悩む.

とりあえず参考ソース:
http://www.macs.hw.ac.uk/~rpointon/osx/coreimage.html
あとはいろいろ.

でもって言えていることはCIImageをNSViewから作るのは簡単になったということ.

- (CIImage *)createCoreImage:(NSView *)view {
NSBitmapImageRep *bitmap= [view bitmapImageRepForCachingDisplayInRect:[view bounds]];
[view cacheDisplayInRect:[view bounds] toBitmapImageRep:bitmap]; //important
CIImage *img= [[CIImage alloc] initWithBitmapImageRep:bitmap];
return img;
}

#cacheはないと動かない(なぜだか教えてエラい人).
"bitmapImageRepForCachingDisplayInRect"こいつが最近までなかったのか上記ソースも結構大変なことしている.

追記 2007/7/22
bitmapをretainシナイト消えるからかな.