ページ

2009年4月30日木曜日

WebKit検証(16) - Flash#6 Webサイトページの表示サイズ

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

WebViewで表示している Webサイトページの表示サイズはどこから取得できるだろうか?デバッグにサイズを表示して確認してみたところ、どうもメインフレーム配下の NSDocumentView から取得できるようだ。

 NSView* view = [[[_web_view mainFrame] frameView] documentView];
NSRect rect = [view bounds];
NSLog(@"%@", NSStringFromRect(rect));



実行して試してみると、このサイズでも


このサイズでも


サイズは変わらなかった。大きさもそれっぽい。
[Session started at 00:58:31 +0900.]
00:58:51.595 WebKitSample[923:10b] {{0, 0}, {984, 938}}
00:59:05.908 WebKitSample[923:10b] {{0, 0}, {984, 938}}



これを使わせてもらおう。

2009年4月29日水曜日

WebKit検証(15) - Flash#5 ウィンドウキャプチャ

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

先日の SnapWeb に刺激され(?)ウィンドウキャプチャ方式のアプローチを試してみる (*)。

(*) 実際に SnapWebがこの方法をとっているかは不明


サンプルに「Capture」ボタンをつけて、AppController#capture: へ接続する。実装はこんな感じ。

{
// (1) setup filename
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDesktopDirectory, NSUserDomainMask, YES);
NSString* path = [NSString stringWithFormat:@"%@/test.png",
[paths objectAtIndex:0], nil];


// (2) capture
CGWindowID *windowIDs = calloc(1, sizeof(CGWindowID));
windowIDs[0] = [_window windowNumber];
CFArrayRef windowIDsArray =
CFArrayCreate(kCFAllocatorDefault, (const void**)windowIDs, 1, NULL);
CGImageRef cgimage =
CGWindowListCreateImageFromArray(
CGRectNull, windowIDsArray, kCGWindowImageBoundsIgnoreFraming);

NSBitmapImageRep *bitmap_rep =
[[[NSBitmapImageRep alloc] initWithCGImage:cgimage] autorelease];

NSData* data = [bitmap_rep representationUsingType:NSPNGFileType
properties:[NSDictionary dictionary]];
[data writeToFile:path atomically:YES];

CGImageRelease(cgimage);
free(windowIDs);
CFRelease(windowIDsArray);

}


キャプチャの方法は昨年来紹介しているので必要なら過去のブログを参照してみて欲しい。私の場合、SimpleCapのコードからコピー&ペーストで5分ぐらいでできた(手抜き)。


さあ実行してみよう。Flashを含むページを開き「Capture」ボタンを押す。


出た。


ウィンドウを大きくすれば(当たり前だが)より大きな範囲をキャプチャできる。



理論上は、ウィンドウを Webサイトが表示できる十分な大きさまで広げてキャプチャすれば、Webサイト表示全体の画像が作れるわけだ。


サンプル:WebKitSample-2.zip



お膳立てはできた。
(続く)

2009年4月28日火曜日

本 - ObjC/iPhone関連2点

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

本屋へ行くとまたまたObjc/iPhone関連の新刊が出ていた。


木下さんによる Objective-C本。これはネットの連載に加筆して出版したもの。連載はたまに読んで参考にさせてもらっていた。



こちらは「Cocoaはやっぱり」で有名な鶴薗さんによる iPhone本。立ち読みした感じでは図が多く(おなじみの?シーケンス図も健在)わかりやすそうな印象を受けた。Amazonの評価も1件だけだが高い。

2009年4月27日月曜日

WebKit検証(14) - Flash#4

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

WebKit の Flashの問題で情報を探しているとこんなソフトを見つけた。

Brain Tickling Software - SnapWeb
"The internet snapshot and archiving utility"





試してみよう。

起動すると簡易ブラウザが立ち上がる。


Flashを含むページを表示する。


Saveボタンを押す。少し間がありファイルが作成された。色や内容がきちんと再現できている。


いろいろオプションもある。


- - - -
なんだかやりたいことがこのソフトで
すべて実現できているような。

なおソフトの動きで気になることが2点あった。
一つは、ブラウザ部分と、その枠の部分が別のウィンドウになっていたこと。
もう一つは、Save時にどうも screencaptureコマンドが動作していること。

この2つから類推するに、もしかしてブラウザ部分のウィンドウをサイトの表示ができる最大サイズまで拡大し、それを screencaptureコマンドで撮影しているのでは?だとしたらかなりユニーク、というか荒技だ。でも再現性という意味では確実かもしれない。ちょっと試してみたいな。

2009年4月26日日曜日

SimpleCap調整(範囲選択サイズ指定のコンテキストメニュー移動)#2

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

さて用意したメニューのプレースホルダーにプリセットされた範囲選択サイズを設定する。

QuickConfigのメニューは、範囲選択処理を司る SelectionHandler がボタンが押されたら反応し、上位のCaptureController に開いてもらっている。これは Nib内のインスタンスを上位のコントローラで保持しているため。そんなこともあるので(少しややこしいが)CaptureControllerから再び SelectionHandlerをコールバックし、ここでプレースホルダーへプリセットサイズを設定することにする。

QuickConfigボタン押下
 ↓
SelectionHandler
 ↓
CaptureContorller#openSelectionConfigMenuWithView:event:
 ↓
SelectionHandler#setupQuickConfigMenu:(NSMenu*)menu


SelectionHandler#setupQuickConfigMenu: で InterfaceBuilderで用意しておいたメニューが渡されるので、この中からプレースホルダー用の NSMenuItemを見つけて置き換えれば良い。NSMenuItemを特定するには Tag か Titleで判断する。今回はあらかじめ InterfaceBuilderで Tagを1〜5(他は0)に設定しておいたのでこれでプレースホルダーのNSMenuItemを判定する。コードはこんな感じ。

- (void)setupQuickConfigMenu:(NSMenu*)menu
{
// [super setupQuickConfigMenu:menu];
NSMenuItem* item;
NSString* title;

item = [menu itemWithTag:1];
title = [self sizeTitleWithNameKey:UDKEY_SELECTION_NAME1
widthKey:UDKEY_SELECTION_WIDTH1
heightKey:UDKEY_SELECTION_HEIGHT1];
[item setTitle:title];
[item setAction:@selector(selectSize:)];
[item setTarget:self];


可変の仕組みではないのでベタな作りだが。。ここは元々コンテキストメニューで使っていたコードをコピーしただけ。


さて動かしてみよう。


出た。

2009年4月25日土曜日

SimpleCap調整(範囲選択サイズ指定のコンテキストメニュー移動)

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

久々に SimpleCap の調整。

範囲選択で右クリックするとコンテキストメニューが開きプリセットされたサイズを選択できる。



右クリックはわかりづらい上、その後 QuickConfigが用意されたのでそこへ移すことにする。

まずは InterfaceBuilderでメニューに5つ分のメニューアイテムを追加する。SimpleCapではプリセットは5個固定なので安易だが固定枠をあらかじめ用意しておき、これをプレースホルダーとして実行時に内容を置き換えることにする。




置き換えはまた明日。

2009年4月24日金曜日

WebKit検証(13) - Flash#3

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

Flashが正しくキャプチャできない件についてネットで調べてみたところ何人か困っている人がいた。

Apple Mailing Lists - Capturing offscreen webview containing flash

NSBitmapImageRep#initWithFocusedViewRect: を使うことが示唆されている。


cocoa-dev - Capture youtube image in webview

本ブログ同様に NSView#cacheDisplayInRect:toBitmapImageRep:
でうまくいかない件が取り上げられている。

今日は調査だけでおしまい。

2009年4月23日木曜日

WebKit検証(12) - Flash#2

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

NSView を画像に保存する方法がもう一つあったのを思い出した。こちらを使って Flashページのキャプチャをやってみよう。

現在は NSView#cacheDisplayInrect:toBitmapImageRep: を使っている。

 NSBitmapImageRep* bitmap =
[view bitmapImageRepForCachingDisplayInRect:rect];
[view cacheDisplayInRect:[view bounds]
toBitmapImageRep:bitmap];



これをやめて NSView#dataWithPDFInsideRect: に切り替える。
 NSData* data = [view dataWithPDFInsideRect:rect];
NSImage* img = [[[NSImage alloc] initWithData:data] autorelease];
data = [img TIFFRepresentation];
NSBitmapImageRep* bitmap = [NSBitmapImageRep imageRepWithData:data];



実行してキャプチャしてみよう。

出た。



ただ画面上部に出るはずの赤いメニューが抜けている。このあたりは前回の PDFと同じ。

2009年4月22日水曜日

WebKit検証(11) - Flash

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

Flashを含むページを保存するとどうなるのだろうか。やってみよう。

まずFlashがあるページをサンプルプログラムで開き画像を保存する。


色がおかしい。


次にPDFで保存してみる。色はいいが、上の赤いメニューが消えている。


試しに Safariで印刷プレビューを見てみる。こちらは見たままが再現できているようだ。


しまいにはクラッシュしてしまった。。。

[Session started at 2009-04-22 17:07:57 +0900.]
プログラムをデバッガに読み込み中...
GNU gdb 6.3.50-20050815 (Apple version gdb-962) (Sat Jul 26 08:17:57 UTC 2008)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "powerpc-apple-darwin".プログラムは読み込まれました。
sharedlibrary apply-load-rules all
Attaching to program: `/Users/hashi/Documents/Private/study/WebKitSample/build/Debug/WebKitSample.app/Contents/MacOS/WebKitSample', process 14036.


うーむ。Flash向けに何か対応が必要なのか?

2009年4月21日火曜日

WebKit検証(10) - CSSのmedia変更

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

これまでに WebViewを使って画像やPDFを作成してきたが、どれも一部のフレームしか表示されなかった。そういうものなのかと思っていたところ、先日 odnazさんから印刷用CSS が適用されたのではないかとの指摘を受けた。なるほど。確かにそんな感じがする。

動作確認に利用していたページ(ADCのリファレンス)を Safariで開き、印刷プレビューを見ると確かに右側のフレームだけの表示になっている。


印刷用プレビュー



スタイルシートにはメディアタイプと呼ばれる出力媒体を設定することができる。一般的に使われる画面(screen)、印刷(print) の他に、携帯デバイス(handheld)や点字向け(braille, embosseed)、さらには音声(speech)などを指定することができる。この設定を受け取ったブラウザはそれらに適合したデバイス(例えば音声合成ソフトとスピーカー)が利用可能であれば、その出力媒体をターゲットにした表現を行う(例えば、ページを読み上げる)。

参考:正しい知識を得たい人の為のCSS2リファレンス - メディアタイプ


よく使われるのは screen(画面)と print(印刷)で、通常ブラウザで使っている場合には screen向けに定義されたスタイルシートを使い画面表示を行う。一方 印刷(もしくはプレビュー)する場合には print向けに定義されたスタイルシートを使う。今回 ADCのリファレンスページではCSS内に printが設定されていたので、Safari(もしくは WebView)がそのスタイルシート設定を使い、一部のフレームだけを表示していた。


ということは WebView が使うメディアタイプを制御できれば、画像生成時(もしくはPDF生成時)の表現を変えられるのでは?

そこでリファレンスを眺めているとメディアタイプを指定するメソッドが見つかった。
WebView#setMediaStyle:

ここへ "screen" を渡してみたらどうなるのか?やってみよう。

コードへ下記を1行追加する。

[_web_view setMediaStyle:@"screen"];



実行して PDFを保存してみる。左のフレームが出た。


意図通りに動いてくれたようだ。ただ左のフレームは画面で見た通り(スクロールバー付き)が再現されている。メディアタイプが screen(画面)なのでこれは仕方ないか。右側のフレームはページ分割されてちゃんと下まで出ているようだ。


次に画像。


こちらも左フレームが表示されて見たままが画像として作成された。


- - - -
Thanks! > odnazさん

2009年4月20日月曜日

WebKit検証(9) - PDF形式で保存(その2)

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

前回の PDF生成の方法は簡易ではあったものの、ページ制御ができなかった(大きなサイズも1ページの PDF書類になっていた)。

そこで WebKitと少し離れるが、PDF形式をページ付きで保存できないかどうか、もう少し調べてみた。

(1時間程度)いろいろ調べた結果、とりあえず2つの方法があることが分かった。
一つはカスタムビューを作り NSView#knowsPageRange:NSView#rectForPage: をオーバーライドした上で、前回の NSView#dataWithPDFInsideRect: と組み合わせてページ制御する方法。

これは今回の様に他から与えられた NSView を扱う場合、少々面倒(カスタムビューを用意した上で、そちらへ描画内容をコピーしなければならない)。


もう一つは NSPrintOperation を使い印刷の仕組みを借りる方法。

通常印刷する時に印刷ダイアログを開き PDF保存することができるが、それと同じ仕組み(多分)。


今回はこの方法を試してみた。

参考にしたページ:
Printing Dicrectly To PDF Without Dialog

コードはこんな感じ。

- (IBAction)savePDF:(id)sender
{
// (1) setup filename
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDesktopDirectory, NSUserDomainMask, YES);
NSString* path = [NSString stringWithFormat:@"%@/test.pdf",
[paths objectAtIndex:0], nil];

// (2) setup WebView
NSView* view = [[[_web_view mainFrame] frameView] documentView];

// (3) setup NSDictionary for NSPrintInfo
NSMutableDictionary* p_dict = [NSMutableDictionary
dictionaryWithDictionary:[[NSPrintInfo sharedPrintInfo] dictionary]];
[p_dict setObject:NSPrintSaveJob forKey:NSPrintJobDisposition];
[p_dict setObject:path forKey:NSPrintSavePath];

// (4) setup NSPrintInfo
NSPrintInfo* p_info = [[NSPrintInfo alloc] initWithDictionary:p_dict];
[p_info setHorizontalPagination:NSAutoPagination];
[p_info setVerticalPagination:NSAutoPagination];
[p_info setVerticallyCentered:NO];

// (5) setup NSPrintOperation
NSPrintOperation* p_ope =
[NSPrintOperation printOperationWithView:view
printInfo:p_info];
[p_ope setShowPanels:NO];

// (6) print it
[p_ope runOperation];
}


NSPrintOperation が印刷(今回はPDF保存)のジョブを制御しており、NSPrintInfoが用紙やページなどの情報を管理している。これらを用意するだけで簡単に印刷が行える。

さて実行してみよう。

まずページを表示し PDFボタンを押す。



それっぽい(?)ファイルが出来た。



開いてみるとちゃんとページに分割されている。


- - - -
たったこれだけのコーディングで PDFファイルが作れるなんて cocoaは良くできてる。毎度感心する。

2009年4月19日日曜日

WebKit検証(8) - PDF形式で保存

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

次は PDF形式で保存してみる。

NSViewには #dataWithPDFInsideRect なんてそのものずばりのメソッドが用意されているのでこれを使ってみよう。以前の画像を保存するコードを流用してちょっぴり書き換えるだけ。

- (IBAction)savePDF:(id)sender
{
NSView* view = [[[_web_view mainFrame] frameView] documentView];
NSRect rect = [view bounds];
NSData* outdata = [view dataWithPDFInsideRect:rect];

NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDesktopDirectory, NSUserDomainMask, YES);
NSString* path = [NSString stringWithFormat:@"%@/test.pdf",
[paths objectAtIndex:0], nil];

[outdata writeToFile:path atomically:YES];
}


InterfaceBuilderでPDFボタンを追加し上記メソッドを呼び出すようにする。


実行してみよう。PDFボタンを押すと PDFファイルが生成された。


PDFファイルだ。


文字の情報もちゃんと持っていてマウスで範囲選択できる。


リンクも有効だ。



縦に長いページを PDFへ落とすと、1ページの PDFになる。
これを保存すると:



こうなる。


左フレームはどこかへ(?)行ってしまった。

2009年4月18日土曜日

WebKit検証(7) - WebArchive形式で保存

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

WebKitを使って Webアーカイブ形式の保存を試してみよう。

Webアーカイブ形式とは、Webページをファイルに保存する時に使われている形式の一種で、Safariからだと メニューから「別名で保存...」で保存できる。


保存したファイルは Safariで読み込み表示させることができる。



まずWebアーカイブ形式で保存するためのボタンを追加する。


ボタンが押されたら次の処理を実行する。

- (IBAction)saveWebArchive:(id)sender
{
WebDataSource* dataSource = [[_web_view mainFrame] dataSource];
WebArchive* webArchive = [dataSource webArchive];
NSData* data = [webArchive data];

NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDesktopDirectory, NSUserDomainMask, YES);
NSString* path = [NSString stringWithFormat:@"%@/test.webarchive",
[paths objectAtIndex:0], nil];

[data writeToFile:path atomically:YES];
}


WebKitには Webアーカイブを扱うクラス WebArchive が用意されている、ここから#dataで NSDataをとりだし保存すればできあがり。


実行してみよう。ページを表示させボタンを押すとファイルが作成された。


これを Safariへドラッグ&ドロップしてみる。出た。



なお保存ファイルの拡張子を間違えると Webアーカイブ形式と認識されない。最初は間違えて .archive としたところ、アイコンは白紙で Safriへ渡しても表示することができなかった。

2009年4月17日金曜日

SimpleCap微調整(吹き出しバグ修正)

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

ステータスバー上のアイコンが減った場合に吹き出しが古い位置に表示される現象が以前報告された。


遅くなったが対応した。

2009年4月16日木曜日

SimpleCap微調整

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

範囲選択で矢印キーを押すとラバーバンドが10ピクセル移動するようになっている。これを1ピクセルへ変更した。
10ピクセル単位で移動したい場合は Optionキーを押しながら矢印キーを押す。

矢印を使うケースは微調整を行いたい時が多いので通常1ピクセル移動の方が使い勝手が良い。

2009年4月15日水曜日

WebKit検証(6) - クリップ

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

生成画像の横幅を固定にする為、はみ出た部分はカットしてしまおう。これは簡単にできて NSView#bitmapImageRepForCachingDisplayInRect: へ渡す NSRectで調整(クリップ)できる。

 NSView* view = [[[_web_view mainFrame] frameView] documentView];
NSRect rect = [view bounds];
rect.size.width = 600;

NSBitmapImageRep* bitmap =
[view bitmapImageRepForCachingDisplayInRect:rect];



こんな感じ。

2009年4月14日火曜日

WebKit検証(6) - スクロール禁止

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

昨日の続き。
WebFrameView#setAllowsScrolling: を呼び出してスクロールを禁止してみよう。

- (void)awakeFromNib
{
:
[[[_web_view mainFrame] frameView] setAllowsScrolling:NO];
}


実行してみる。スクロールバーは消えたが。。


保存画像は変わらず。


駄目か。
余分な分は自分で切り取るしかないのかもしれない。

2009年4月13日月曜日

WebKit検証(5) - キャプチャサイズ

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

キャプチャ画像のサイズはどうやって決まるのだろうか。調べてみる。

まず表示ビューの大きさに影響を受けているかどうかを確認しよう。InterfaceBuilderで、ウィンドウサイズによってWebViewが伸縮するように設定する。


ウィンドウを小さくした時と大きくした時とで生成画像に差が出るかどうか見てみる。

まず小さくした場合。


生成画像は大体見えているものと同じだ。幅があるのは、スクロールで隠れていた部分がある為。



次に大きくした場合。


こちらも基本的に見えている大きさで画像が生成されている。



では、もっと極端に幅を狭くしてみよう。


やはり生成画像も細長くなる。


全体はこんな感じ。


- - - -
ビューから直接画像へ落としているので、見えるものがそのまま画像として生成されるという当たり前といえば当たり前の結果となった。ただし、ビューはスクロールを許しているので、生成画像の幅をビューの大きさで制御することはできない。であればスクロールを禁止すれば良い??