2006年 12月 06日

うんこー

もっと精進します。

Windows 機が起動しなくなった

なんか synergy がやたらきれて調子が悪かったので再起動かけたら、ログイン画面がでる直前に青画面になってリブートがかかってしまうようになった。
いったんセーフモードで起動して再起動したら起動した。怖すぎる。
mayu かと思ったけど、インストールしてから数日たってて問題がなかったので、なんとなくだけどグラフィックカードのような気がする(解像度の変更に失敗している?)

perl

やっぱ Perl むずい。ithread 周りをまたちょっと見てみたけど、罠が多くて覚えられない。
というのはどうでもいいけど、内部データ構造もよくわからない。utf8 まわりがぜんぜん……

2006年 12月 05日

gerry++

haraitai
15日ぶり。久しぶりにトイレにこもったら足が痺れた。

proxy

学内の proxy よりも ssh でトンネリングした SOCKS 経由の接続の方がはやい。

2006年 12月 04日

<a href="http://espion.just-size.jp/archives/06/338142930.html">「Greasemonkeyスクリプティング TIPS&SAMPLES」と言う本を書きました</a>

献本欲しい!と書くともれなく gaba さんが献本して下さるかもしれません。という仕組みはまだありません?><

註記:このエントリは、なんらかのオープンなライセンスに基づいて、http://subtech.g.hatena.ne.jp/secondlife/20061204/1165212092 をコピペしたものです。

註記:このエントリは、なんらかのオープンなライセンスに基づいて、http://subtech.g.hatena.ne.jp/antipop/20061204/1165212198 をコピペしたものです。

HHKB

やばい。素敵だ。なんでもっとはやく買わなかったんだろう。

2006年 12月 03日

英和辞書ひきまくる Greasemonkey スクリプト

このエントリは古いのでアテにしないでください。新しいスクリプトは userscripts.org で公開され、CodeRepos で保守されています。

mallowlabsの備忘録 - ポップアップ型英英辞書 見てて選択したらすぐ検索できるのっていいなぁと思ったので似たようなのを作ってみた。

fastlookupalc.user.js

相違点

  • 英和 (alc)
  • 一個ひいた後に、さらにひける。(こういう機能は英英のほうが便利だけど)

結果のタイトル (赤い部分) をクリックするとその結果だけ消えます。ドキュメント内のどっかをクリックすると全部消えます。

ダブルクリックで単語を選択するのでどんどんひける。

2006年 12月 02日

OSX スクリーンショット

画面イメージを取得して書き出してみる。

// gcc -framework Cocoa
// depth 32bit, intel little endian
#import <Cocoa/Cocoa.h>

int main() {
	int w = CGDisplayPixelsWide(kCGDirectMainDisplay);
	int h = CGDisplayPixelsHigh(kCGDirectMainDisplay);
	NSLog(@"%d, %d", w, h);

	unsigned char* _screenBytesActual = (unsigned char*)CGDisplayBaseAddress(kCGDirectMainDisplay);
	NSLog(@"Address: %08x", _screenBytesActual);

	int bitPerPixel    = CGDisplayBitsPerPixel(kCGDirectMainDisplay);
	int bitPerSample   = CGDisplayBitsPerSample(kCGDirectMainDisplay);
	int samplePerPixel = CGDisplaySamplesPerPixel(kCGDirectMainDisplay);
	int bytePerRow     = CGDisplayBytesPerRow(kCGDirectMainDisplay);
	int bytePerPixel   = bitPerPixel / 8;
	NSLog(@"%d %d %d %d %d", bitPerPixel, bitPerSample, samplePerPixel, bytePerRow, bytePerPixel);

	FILE* fp;
	if ((fp = fopen("test.bin", "w")) == NULL) {
		NSLog(@"fopen failed");
		exit(1);
	}

	int x, y;
	for (y = 0; y < h; y ++) {
		fwrite(_screenBytesActual + y * bytePerRow, w * bytePerPixel, 1, fp);
	}
	fclose(fp);

	return 0;
}

書き出されたファイルは BGRA がディスプレイの左上から並んでる (intel)。
1ピクセルあたり 4 bytes なので、全体では 1280*800*4 = 4096000 = 4000KB

でできた test.bin を png なりに変換してみる。ここでは rmagick

require 'rubygems'
require 'RMagick'
require 'ostruct'
require 'profiler'

frame = OpenStruct.new
frame.width = 1280
frame.height = 800

Profiler__.start_profile
img = Magick::Image.new(frame.width, frame.height)
img.import_pixels(0, 0, frame.width, frame.height, "BGRA", File.read("test.bin"), Magick::CharPixel)

img.write("test.png")

Profiler__.print_profile(STDOUT)

img.write は遅い。

OSX スクリーンキャストツール

への布石

を組み合わせてスクリーンショットをとりまくって変換してみる。

#!/usr/bin/ruby

require 'rubygems'
require 'RMagick'
require 'ostruct'
require 'pathname'
require 'osx/cocoa'
require 'ext/osxscreen'
require 'zlib'
require 'progressbar'

include OSX

system('rm test/*')

size = eval( `./fullscreen.rb` )
p size

fps = 12 # frames per second

interval = 1.0 / fps

time = Time.now + 3

nextrun = 0
loop do
	true while Time.now.to_f < nextrun
	nextrun = Time.now.to_f + interval
	filename = "test/temp-#{Time.now.to_i}.#{Time.now.usec}.bin"

	File.open(filename, 'wb') do |f|
		f.write OSX::ScreenData.data
	end
	
#	Zlib::GzipWriter.open(filename + '.gz', Zlib::BEST_SPEED) do |f|
#		f.write OSX::ScreenData.data
#	end

	puts filename
	break if Time.now > time
end

frame = NSScreen.mainScreen.frame.size

files = Pathname.glob('test/*')
bar = ProgressBar.new('Convert', files.size)
files.each do |f|
	img = Magick::Image.new(frame.width, frame.height)
	img.import_pixels(0, 0, frame.width, frame.height, "BGRA", f.read, Magick::CharPixel)
	img.crop!(*size)

	img.write(f.to_s + '.png')
	f.unlink
	bar.inc
end

zlib は使わない方がいい気がする。ハードディスクあいてないときは使わざるを得ないけど……
fullscreen.rb (名前わるすぎ)

#!/usr/bin/ruby

require 'osx/cocoa'
include OSX

class SelectionView < NSView
	attr_accessor :delegate

	def drawRect(rect)
		NSColor.colorWithCalibratedRed(0, :green, 0, :blue, 0, :alpha, 0.1).set
		NSRectFill(bounds)

		if @start && @end
			NSColor.colorWithCalibratedRed(0.5, :green, 0.5, :blue, 0.5, :alpha, 0.5).set
			NSRectFill(calc_rect)
		end
	end

	def mouseDown(event)
		@start = NSEvent.mouseLocation
	end

	def mouseDragged(event)
		@end = NSEvent.mouseLocation
		setNeedsDisplay(true)
	end

	def mouseUp(event)
		@end = NSEvent.mouseLocation
		delegate.windowShouldClose(nil)
		window.close
	end

	def calc_rect
		x = [@start.x , @end.x].min
		y = [@start.y , @end.y].min
		w = (@start.x - @end.x).abs
		h = (@start.y - @end.y).abs
		[x, y, w, h]
	end
end

class TEST < NSObject
	def applicationDidFinishLaunching(aNotification)
		size = NSScreen.mainScreen.frame.size
		rect = [0, 0, size.width, size.height]
		@window = NSWindow.alloc.initWithContentRect(rect,
		                                  :styleMask, NSBorderlessWindowMask,
		                                    :backing, NSBackingStoreBuffered,
		                                      :defer, 0)
		@window.setDelegate(self)
		@window.setOpaque(0)
		@window.setHasShadow(0)
		@window.setLevel(1000) # NSScreenSaverWindowLevel

		@view = SelectionView.alloc.initWithFrame(rect)
		@view.delegate = self
		@window.setContentView(@view)

		@window.makeKeyAndOrderFront(nil)
		@window.orderFrontRegardless
	end

	def windowShouldClose(sender)
		size = NSScreen.mainScreen.frame.size
		rect =  @view.calc_rect
		rect[1] = size.height - rect[1] - rect[3]
		p rect
		exit
		true
	end
end

$App = NSApplication.sharedApplication
$App.setDelegate(TEST.alloc.init)
$App.run

ext/screendata は C

#include <Carbon/Carbon.h>
#include <ruby.h>

VALUE
screendata_data () {
	VALUE ret;
	int w = CGDisplayPixelsWide(kCGDirectMainDisplay);
	int h = CGDisplayPixelsHigh(kCGDirectMainDisplay);

	unsigned char* _screenBytesActual = (unsigned char*)CGDisplayBaseAddress(kCGDirectMainDisplay);
	unsigned char* _screenBytes       = (unsigned char*)malloc(w * h * 4);
	//NSAssert(_screenBytes != 0, "fail malloc");

	int bitPerPixel    = CGDisplayBitsPerPixel(kCGDirectMainDisplay);
	int bitPerSample   = CGDisplayBitsPerSample(kCGDirectMainDisplay);
	int samplePerPixel = CGDisplaySamplesPerPixel(kCGDirectMainDisplay);
	int bytePerRow     = CGDisplayBytesPerRow(kCGDirectMainDisplay);
	int bytePerPixel   = bitPerPixel / 8;

	int x, y;
//	for (y = 0; y < h; y++) {
//		unsigned long step = y * bytePerRow;
//		for (x = 0; x < w; x++) {
//			unsigned long pixel;
//			pixel =  *((unsigned long*)(_screenBytesActual + (x * bytePerPixel) + step));
//			// pixel on Intel => AABBGGRR
//			// bitmap data planes => AARRGGBB
//			pixel = ((pixel & 0x00ff0000) >> 16) | ((pixel & 0x000000ff) << 16) | (pixel & 0xff00ff00);
//			*((unsigned long*)(_screenBytes + x * 4 + y * w * 4)) = pixel;
//		}
//	}
	for (y = 0; y < h; y ++) {
		memcpy(_screenBytes + y * w * 4, _screenBytesActual + y * bytePerRow, w * bytePerPixel);
	}

	ret = rb_str_new((const char*)_screenBytes, w * h * 4);
	free(_screenBytes);
	return ret;
}

void
Init_osxscreen () {
	VALUE ScreenData;
	VALUE module;

	rb_eval_string("require 'osx/cocoa'");
	module = rb_eval_string("OSX");

	ScreenData = rb_define_module_under(module, "ScreenData");
	rb_define_module_function(ScreenData, "data", screendata_data, 0);
}

memcpy の引数を逆にしてひどいことになった。すぐなおるからいいけど(CGDisplayBaseAddress の先には直接書き込める。すなわち直接描画できる。)
ここから flv に変換したい。
rmovie という gem があるんだけど、コンパイルできない。ffmpeg を port で入れて云々がうまくいかない。深く追ってない。