うんこー
もっと精進します。
もっと精進します。
なんか synergy がやたらきれて調子が悪かったので再起動かけたら、ログイン画面がでる直前に青画面になってリブートがかかってしまうようになった。
いったんセーフモードで起動して再起動したら起動した。怖すぎる。
mayu かと思ったけど、インストールしてから数日たってて問題がなかったので、なんとなくだけどグラフィックカードのような気がする(解像度の変更に失敗している?)
やっぱ Perl むずい。ithread 周りをまたちょっと見てみたけど、罠が多くて覚えられない。
というのはどうでもいいけど、内部データ構造もよくわからない。utf8 まわりがぜんぜん……
haraitai
15日ぶり。久しぶりにトイレにこもったら足が痺れた。
学内の proxy よりも ssh でトンネリングした SOCKS 経由の接続の方がはやい。
献本欲しい!と書くともれなく gaba さんが献本して下さるかもしれません。という仕組みはまだありません?><
註記:このエントリは、なんらかのオープンなライセンスに基づいて、http://subtech.g.hatena.ne.jp/secondlife/20061204/1165212092 をコピペしたものです。
註記:このエントリは、なんらかのオープンなライセンスに基づいて、http://subtech.g.hatena.ne.jp/antipop/20061204/1165212198 をコピペしたものです。
やばい。素敵だ。なんでもっとはやく買わなかったんだろう。
このエントリは古いのでアテにしないでください。新しいスクリプトは userscripts.org で公開され、CodeRepos で保守されています。
mallowlabsの備忘録 - ポップアップ型英英辞書 見てて選択したらすぐ検索できるのっていいなぁと思ったので似たようなのを作ってみた。
相違点
結果のタイトル (赤い部分) をクリックするとその結果だけ消えます。ドキュメント内のどっかをクリックすると全部消えます。
ダブルクリックで単語を選択するのでどんどんひける。
画面イメージを取得して書き出してみる。
// 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 は遅い。
への布石
を組み合わせてスクリーンショットをとりまくって変換してみる。
#!/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
endzlib は使わない方がいい気がする。ハードディスクあいてないときは使わざるを得ないけど……
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.runext/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 で入れて云々がうまくいかない。深く追ってない。