2011年7月31日日曜日

Quartz Composer / WebViewの画像を取得するパッチ 修正版

前提
前の版

問題や課題(?)
問題
  • 色が合わない(赤と青が入れ替わっている RGBA(BitmapImageRep)→BGRA(OutputImageProvider))
  • 大きい画像から小さい画像に切り替えた際に以前の画像サイズのままになることがある
    課題
  • Download終了時の画像のみでアニメーションしない
    ということで修正してみた.


  • やってみた
    WebViewPlugIn.h

    #import <Quartz/Quartz.h>
    #import <Webkit/WebKit.h>

    @interface WebViewPlugIn : QCPlugIn {
    @private
    WebView *aWebView;
    WebFrameView *aWebFrameView;
    NSString *oldURL;
    NSBitmapImageRep *aBitmapImageRep;
    }

    @property(assign) NSString *inputURL;
    @property(assign) id<QCPlugInOutputImageProvider> outputImage;
    @end


    WebViewPlugIn.m

    #import <OpenGL/CGLMacro.h>
    #import "WebViewPlugIn.h"

    #define kQCPlugIn_Name @"WebView"
    #define kQCPlugIn_Description @"WebView description"

    @implementation WebViewPlugIn
    @dynamic inputURL;
    @dynamic outputImage;
    + (NSDictionary *)attributes
    {
    return [NSDictionary dictionaryWithObjectsAndKeys:
    kQCPlugIn_Name, QCPlugInAttributeNameKey,
    kQCPlugIn_Description, QCPlugInAttributeDescriptionKey,
    nil];
    }

    + (NSDictionary *)attributesForPropertyPortWithKey:(NSString *)key
    {
    return nil;
    }

    + (QCPlugInExecutionMode)executionMode
    {
    return kQCPlugInExecutionModeProvider;
    }

    + (QCPlugInTimeMode)timeMode
    {
    return kQCPlugInTimeModeIdle;
    }

    - (id)init
    {
    self = [super init];
    if (self) {
    NSRect r= NSMakeRect(0,0, 16, 16);
    aWebView= [[WebView alloc] initWithFrame:r
    frameName:nil
    groupName:nil];
    NSWindow *w= [[NSWindow alloc] init];
    [w setContentView:aWebView];
    [w setFrame:r display:YES];
    [aWebView setFrameLoadDelegate:self];
    aWebFrameView= [[aWebView mainFrame] frameView];
    }
    return self;
    }
    - (void)finalize
    {
    [super finalize];
    }
    - (void)dealloc
    {
    [aWebView release];
    [oldURL release];
    [super dealloc];
    }
    @end
    @implementation WebViewPlugIn (Execution)
    - (BOOL)startExecution:(id <QCPlugInContext>)context
    {
    return YES;
    }
    - (void)enableExecution:(id <QCPlugInContext>)context
    {
    }
    static void _BufferReleaseCallback(const void* address, void* info)
    {
    CGContextRelease(info);
    }
    - (BOOL)execute:(id <QCPlugInContext>)context atTime:(NSTimeInterval)time withArguments:(NSDictionary *)arguments
    {
    if (![oldURL isEqualToString:self.inputURL]) {
    [[aWebView window] setContentSize:NSMakeSize(16,16)];
    [aWebView setMainFrameURL:self.inputURL];

    [oldURL release];
    oldURL= [self.inputURL retain];
    [aBitmapImageRep release];
    aBitmapImageRep= nil;
    }

    if (aBitmapImageRep!=nil) {
    [aWebFrameView lockFocus];
    [aWebFrameView cacheDisplayInRect:[aWebFrameView bounds] toBitmapImageRep:aBitmapImageRep];
    [aWebFrameView unlockFocus];

    NSSize aSize= [aBitmapImageRep size];

    NSUInteger i;
    char *p= (char *)[aBitmapImageRep bitmapData];
    for(i= 0; i<[aBitmapImageRep bytesPerRow]*aSize.height;i+=4){
    char cr= p[i];
    char cb= p[i+2];
    p[i]= cb;
    p[i+2]= cr;
    }


    id provider= [[context outputImageProviderFromBufferWithPixelFormat:QCPlugInPixelFormatBGRA8
    pixelsWide:aSize.width
    pixelsHigh:aSize.height
    baseAddress:[aBitmapImageRep bitmapData]
    bytesPerRow:[aBitmapImageRep bytesPerRow]
    releaseCallback:_BufferReleaseCallback
    releaseContext:NULL
    colorSpace:[[aBitmapImageRep colorSpace] CGColorSpace]
    shouldColorMatch:YES]
    retain];
    if(provider == nil)
    return NO;
    self.outputImage = provider;
    }
    else {
    self.outputImage= nil;
    }
    return YES;
    }
    - (void)disableExecution:(id <QCPlugInContext>)context
    {
    }
    - (void)stopExecution:(id <QCPlugInContext>)context
    {
    }
    @end
    @implementation WebViewPlugIn (WebView)
    - (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
    {
    NSSize size= [[aWebFrameView documentView] bounds].size;
    NSUInteger i= ((NSUInteger)size.width)%4;
    if (i!=0) {
    size.width+= 4-i;
    }
    [[aWebView window] setContentSize:size];

    [aBitmapImageRep release];
    [aWebFrameView lockFocus];
    aBitmapImageRep= [[aWebFrameView bitmapImageRepForCachingDisplayInRect:[aWebFrameView bounds]] retain];
    [aWebFrameView unlockFocus];

    }
    @end



    結果
    こちらを表示.

    動画のページで横スクロールバーがでてる…documentViewのサイズもだめなのかなぁ…。

    0 件のコメント: