久しぶりにやるとカラーマネジメントまわりのことをすっかり忘れている。

キャリブレーションしてもOSのUIの色はあわない

写真を表示させるとあっているように見えるのに、OS の UI (例えば Finder の背景の白) とかがディスプレイごとに全く違う色に見えたりする。

正確な情報が見つからなかったけど、OS の UI にはカラープロファイルがついてない?っぽい。スクリーンショットを撮った場合、撮影した画像にはモニタのプロファイルが埋め込まれる (ので、この画像を移動させると、そのモニタにおける見えかたが再現される、はず…)。

同じように、ウェブページの背景色など、CSS で指定されている色もカラーマネジメントの対象外なので、たとえディスプレイプロファイルを適切に設定していても、色は一致しない。実は color-profile というプロパティがCSSに用意されているが、どのブラウザにも実装されていない。(追記: Safari では sRGB として扱われるのでカラーマネジメントの中にいるみたい)

色域が異るディスプレイ間での色一致

片方が Adobe RGB 対応で、もう片方が sRGB だけの対応という場合

Adobe RGB の色域の画像を表示させる
  • Adobe RGB モニタでは正確に出せる
  • sRGB では色が圧縮される

sRGB の色域の画像を表示させる

  • Adobe RGB モニタでは正確に出せる (sRGB 領域を含んでいるから)
  • sRGB でも表示できる

カラーマネジメントが有効なケースまとめ

印刷まで行う場合

これが基本になる。ディスプレイのプロファイルと、プリンタ(用紙も含む)のプロファイルを作り、カラーマッチングする。

この出力の場合 Adobe RGB モニタで、画像データも Adobe RGB の範囲で作業するのが望ましい。

ウェブ向けの場合

基本的に、世の中のモニタはキャリブレーションされていないので、正確なカラーマッチは期待できない。とはいえ、中にはあわせている人もいるので、基本的に sRGB で統一して出すのが一番良い。

画像データの恒久性

あとは自分の写真が将来的に一貫して同じ色で表示されるようにデータをちゃんとしておくという用途。

ちゃんとキャリブレーションされていないモニタで作業した時点で、データは何がなんだかわからない色を基準にしていることになってしまう。将来的にモニタを替えたときに色が変わってしまう。

Lightroom でのカラーマネジメント覚書

http://helpx.adobe.com/jp/lightroom/help/color-management.html#about_color_management_in_lightroom

Lightroom は内部的には ProPhotoRGB というカラースペースを使っている。これは Adobe RGB よりももっと広い色域を持つカラースペースになっている。Adobe RGB ではカバーしきれない範囲の色をサポートするプリンタのためこうなっているっぽい。

つまり、Adobe RGB のモニタを使っていたとしても、見えない色を作っている場合がある。これは、ちょっと難しい問題だ。もしプリンタの色域を活かすならばディスプレイとのカラーマッチを捨てる必要がある。ディスプレイとのカラーマッチを優先するなら、ディスプレイの表示色域に出力色域が制限される。

実際のワークフローでは以下のような手順が必要

全体的な調整

ソフト校正を使用せずに大まかに好みの画質に調整する。とりあえず色域のことを考えず見えている画像を最適化する。

印刷する場合

現像モジュールでソフト校正をプリントのプロファイルにあわせる。校正刷りをつくる。

色域外警告をちゃんと見ながら作業する。モニター色域外警告色の部分は頭で補完するか、実際に印刷して検証するしかない。

校正の色域外警告はソフト校正で「色が変わっている部分」なので、注目してチェックを行う。

ウェブ用に出力する場合

印刷する場合と一緒だけど、現像モジュールでソフト校正を sRGB にあわせる。

sRGB はかなり色域が狭く感じることがあるので、校正刷りを作るなり、ウェブ主体なら sRGB の状態で校正かけるなりしたほうがよさそう。

色域

綺麗な青緑系の色は sRGB モニタでは殆ど表示できない。ので、意図的にホワイトバランスを崩したりしている場合かなり色が変わることがある。

  1. トップ
  2. tech
  3. ディスプレイキャリブレーションの覚書

WebP に変換するデモコマンドである cwebp はデフォルトでメタデータを全て削除する。ICC プロファイルすら消しさるのでかなりひどい。

  -metadata <string> ..... comma separated list of metadata to
                           copy from the input to the output if present.
                           Valid values: all, none (default), exif, icc, xmp

必要なメタデータ削っといて「ファイルサイズ減りました!!!」とか言わないように気をつけてください。

  1. トップ
  2. tech
  3. cwebp はメタデータを削除する

一定数以上のUSBデバイスを接続すると Mac が不安定になり、内蔵キーボード・トラックパッドなどが一切効かなくなる (USB バス全体が死ぬ感じ) という状況があり、よくわからないので、怪しいハブを止めたり、新しいハブを買ってみたりしていた。

そんななか、あるハブに替えたところバスが死ぬ前にエラーメッセージがでるパターンがようやく観測された。以下の通り (Console.app で USB を grep しながら見ていた)

the USB hardware ran out of device slots

このエラーメッセージで検索をかけたところ、まさにこの問題のことであろうFacebook のノートがひっかかった。

どうやら Haswell ではデフォルトだとたくさん繋ぐことができないらしい。このノートでもひとまずの解決方法が示されてはいるものの、USB 3.0 バスとの併用で疑問がある感じ。

リンクされているErgotron のドキュメントも読んだが、よくわからない。Haswell では25台以上はサポートしないと書いてあったり、もし30台以上のデバイスを繋ぐのであれば USB 3.0 デバイスは繋ぐなという感じのことが書いてある。

台数の根拠がよくわからないので、自分のところで追試を行なったが、「the USB hardware ran out of device slots」になるのは32台を超えたとき(32台までなら大丈夫)という感じだった。

そんなにいっぱい繋がないやろwww とお思いだろうか?

接続中のUSBデバイスの数

接続中のUSBデバイスの数は以下で出した。

system_profiler SPUSBDataType | grep 'Location ID' | wc -l

USB の規格上のデバイス数上限は127(USB のアドレスが7bitで、0は予約されている)、このアドレスは Mac 上では「場所 ID」や「Location ID」と呼ばれている。デバイスの抜き差しが発生していなければ普通は連番の番号が振られている。

上記コマンドではアドレスが割り振られたデバイスがいくつあるか? を算出している。なので現実世界における見掛けのデバイス数とは異なる。

手元の MacBook Pro Retina Late 2013 では何も接続していなくても以下のデバイスが有効になっている。

  • メモリカードリーダー(内蔵)
  • キーボード・トラックパッド(内蔵)
  • Bluetooth ハブ(内蔵)
  • Bluetooth USB コントローラ(内蔵)

つまり、外部にはこれらを抜いた28デバイスが最大となる。

USB 3.0 7ポートハブの罠

USB 3.0 ハブは USB 2.0 のハブの機能も持っている。これは、実際に物理レイヤーとして USB 2.0 レイヤーも持っている (USB 2.0 と USB 3.0 は物理プロトコルが全然違うからかな)。そんな関係からか、OS から見ると 3.0 のハブと 2.0 のハブ2種類が別々に見える。

あるチップの仕様書を見たりするとなんとなくわかりやすい、
http://ww1.microchip.com/downloads/en/DeviceDoc/00001681B.pdf

そして、7ポートのハブというのは、内部的には4ポートのハブチップを2個使って2段接続されている。

つまり、7ポートUSB3.0ハブは、見掛けは1台だが、OSには4つのデバイスに見え、SuperSpeed と Hi-Speed それぞれにアドレスが振られる。

どうしてもたくさん繋ぎたい場合

Ergotron のドキュメントに示されているように、とりあえず USB 2.0 の機器をたくさん繋ぎたい場合、

nvram -p | grep usb-options で何も設定されていないことを確認して

sudo nvram usb-options="%01%00%00%00"

を実行して再起動すると認識するようになる。

元に戻すには

sudo nvram -d usb-options

この方法は確かにデバイスの上限を突破できるみたいだが、手元で試したところバスが不安定になり、内蔵キーボードなどを巻き込んでバスが死ぬことがあった。

Mac の場合、USB 3.0 Hi-Speed バス (2.0 互換レイヤー)、USB 3.0 SuperSpeed バス (3.0レイヤー) のみがデフォルトでアクティブなバスとなっているが、このコマンドによって USB Hi-Speed バス (2.0 ネイティブレイヤー) のバスが有効になるっぽい。

消費電力が増えるデメリットがあるみたいだけど、他のデメリットがよくわからない。3.0 との併用がうまくいかない?

いずれにせよ、自分の環境では不安定になるのは解決されなかったので深く追わなかった。

自分の環境

これからは USB 3.0 だ!! と意気込んでハブ類は USB 3.0 にできるだけ統一しようとしており 7 ポートの USB 3.0 ハブを2台をメインにデバイスを接続していた。また、ディスプレイに内蔵されている USB 3.0 ハブも、どうせだからと接続していた。上記の罠の関係もあって、デバイス上限に達しやすい環境だった。

ハブがいっぱいあっても意味がないので、USB 機器は計画性を持って管理したほうが良い。上限いかねーよwwとか舐めてると余裕でひっかかる。

バスが死ぬのは、デバイス上限を超えるというエッジケース(仕様上は127台を超えるまで発生しない)をしっかりテストしておらず対応できないデバイスがあって暴走(バスをロック?)しているような気がする。バスが死ぬとCPUは生きているのにハードリセットしか終了方法がなくなるので絶対に避けたい。

まとめ

USB 2.0 ですむ範囲のデバイスは USB 2.0 用のハブでまとめたほうが良い。今回のようなケースもそうだし、コスト的にもかなり安くすむ。USB 3.0 が必要なケースはそれほど多くない。カードリーダーや、HDD などぐらいだ。

また、DELL のディスプレイにはカジュアルに USB 3.0 ハブがついているが「せっかくだから…」と繋いでおいたりすると、上限を超えやすくなる。

というか根本的に127デバイスまでちゃんといけるようにしてほしい。

iBUFFALO USB2.0Hub バスパワー 4ポート ブラック 【PlayStation4,PS4,PS3 動作確認済】BSH4U06BK -

5.0 / 5.0

Anker USB 3.0 高速7ポートハブ (約1mのUSB 3.0ケーブル付き) -

5.0 / 5.0

  1. トップ
  2. tech
  3. Mac でいっぱいUSB機器を繋げない問題

たとえば視力2.0の人が300ppiのディスプレーで十分に綺麗に(隣り合うピクセルを区別できない)見れる距離で使っていたとしたら、同じ鑑賞距離の場合視力1.0の人は半分の150ppiでも十分ということになってしまう。

というわけで、デスクトップのディスプレイを想定して鑑賞距離を50cm固定としたとき、各視力でどれぐらいのppiがあれば十分かを出してみた。

0.3 52 ppi
0.5 87 ppi
0.7 122 ppi
1 175 ppi
1.5 262 ppi
2 349 ppi

2K 24インチモニタの場合 96ppi なので、50cm の鑑賞距離の場合、視力 0.5 の人は 4K になっても気付きにくいということになる。

  1. トップ
  2. tech
  3. 4Kと2Kが同じにみえる、という人もいるらしい。

Picasa での色化け

先にまとめ

  • sRGB で出力すること
  • Google+ の「フォト」の設定で「自動補正」を「オフ」にすること

経緯

Picasa にアップロードすると、めちゃくちゃ色が変わるというのは認識していたが、面倒なので見ないふりをしていた。やる気を出してちゃんと調べた。

sRGB プロファイル強制適用

Picasa はアップロード時に問答無用で sRGB IEC61966-2.1 black scaled が適用される。マッチングされないで強制適用なようなので、AdobeRGB な画像をアップロードすると明かに彩度が落ちる。

sRGB でアップロードしても色が変わる

しかし、sRGB な画像をアップロードしても、色化けが起こる。OS に入っている sRGB と sRGB black scaled の違いかと思い (同じはずだけど)

http://www.color.org/srgbprofiles.xalter ここから .icc をダウンロードして

sudo cp ~/Downloads/sRGB_IEC61966-2-1_black_scaled.icc  /Library/ColorSync/Profiles/   
sudo chmod +r /Library/ColorSync/Profiles/sRGB_IEC61966-2-1_black_scaled.icc 

(なぜか read できない permission になってて混乱)

として、このプロファイルを使って書きだしてアップロードしてみたが、やはりダメ。Picasa にアップロードすると少し明くなってしまう。

いろいろ試行錯誤していたが、Google+ 側の「フォト」を開き、該当画像の「自動補正」を「オフ」にしたら色が正しくなった。Picasa 側ではこの設定が見えないので気付かなかった……

今後ハマらないように、Google+ 側の設定で自動補正をオフにした。念のため sRGB black scaled はそのまま適用するようにする。

  1. トップ
  2. tech
  3. Picasa にあげるときのカラープロファイル

いろいろ確認していたところ、Chrome で Preview.app と色が違うことに気付いた。sRGB モニタで見ていると同じように見えるが、AdobeRGB 色域のモニタにウィンドウを移動するとかなり彩度が上がる。謎……

Google Chrome は ICC v4 には対応してないが、sRGB_IEC61966-2-1_black_scaled.icc は v2 なので、それが原因ではない。

結局、結論は「Google Chrome はプライマリディスプレイのプロファイルしか認識しない」だった。

マルチモニタ環境で、モニタごと別々の Chrome のウィンドウを置いておくと、プライマリモニタ以外は全て色がずれるので気をつけましょうという感じだった。

なお Safari だけがマルチモニタでのプロファイル適用に対応しているみたいだった。

  1. トップ
  2. tech
  3. Google Chrome (Mac版) の色化け

USB 3.0 の伝送路における基本波が 2.5GHz なため、ISM バンドの 2.45GHz 帯 (2.4GHz〜2.5GHz)で電波障害が起きやすいという話。(波長の半分で1bit転送するのでデータレート的には5Gbps)

一応 USB 3.0 はEMI 対策として、スペクトラム拡散クロック (広い範囲にクロックを拡散することでピークを回避する) や、スプレッド処理 (信号経路には常にランダムのビットが流れるようにしてピークを防ぐ) をしているが、あまりに発生源とアンテナが近過ぎるとやはりダメらしい。

うちで使っているワイヤレスマウスも、USB 3.0 ハブに繋ぐとかなり挙動がおかしくてイライラする感じになる。

今後

USB 3.1 になると基本波が倍の 5GHz になるので、この問題は解決するかもしれない。(5.8GHz帯のISMバンドとはある程度離れてるし)

備考

USB 3.0 は 2.5GHz 基本波、5Gbps の物理ビットレートだが、8b/10b エンコードするので、実行ビットレートは 4Gbps 程度

USB 3.1 は 5GHz 基本波、10Gbps の物理ビットレート、128b132b エンコードなので、実行ビットレートは 9.7Gbps 程度

USB 3.0 では、USB 2.0 と違い、完全なスリープ状態でなければ常に信号が流れているらしい。


ref.

  1. トップ
  2. tech
  3. USB 3.0 の 2.4GHz 帯干渉 (無線マウスなどへの電波障害)

フルサイズ5060万画素

ところで以前レンズの理論上の解像度限界というのを求めたことがあった。これは、絞りを絞るほど回折によってボケてしまうという物理的な絶対的制約からくる解像度限界だった。

フルサイズセンサ (36x24mm) で 8688x5792pixel だとすると、画素サイズは 約 0.00414mm なので、F7 波長500nm でのレイリー限界 0.00427mm よりも細かくなる。

高画素数になるということは、より回折にシビアなセンサーになるということになる。ある程度よりも (この機種の場合 F7 程度) 絞ってしまえば、いくら高画素でも解像度はあがらないので意味がない。

実際のところでは、回折ボケよりも手ぶれのほうが厳しい場合が多いように思われるが、とにかく回折による解像度の限界を感じやすくなる。

ローパスレス

高画素化することによって空間的なサンプリング周波数があがり、ナイキスト周波数(=サンプリング周波数の半分)も上げることができる。十分に高いナイキスト周波数 (具体的にはレンズの性能よりもセンサーが勝る=レンズがローパスフィルタとして働く) の場合、センサー直前のローパスフィルタを省くことで画質の向上をはかることができる (ローパスフィルタでは、ナイキスト周波数ぴったりで遮断するということはできないので、いくらか解像度が犠牲になる)。

画素サイズを(アスペクト比間違いにより)間違えていたので、いろいろ修正しました。

  1. トップ
  2. tech
  3. EOS 5DS というフルサイズ5060万画素のカメラが発表された。

ちょいちょい「環境設定」→「セキュリティとプライバシー」→「アクセシビリティ」を開かせたいケースがあるが、openURL とかで Security.prefPane を開くだけだと「どこやねん」となりがちなので、アクセシビリティを設定するところまで一気に移動したくなる。

ScriptingBridge を使えばできるのだが、Objective-C でやる場合でもメソッド定義のヘッダファイルを生成して使うみたいな感じになっており、Swift からちょっと気軽に使おうと思うとダルくなってしまう。

フル機能を使うなら一度 Objective-C でラッパー書くのが正当だと思うが、一行も Objective-C を書きたくない気分のときは、プロトコルとエクステンションで必要なメソッドを強制的に定義してコンパイラを騙せば乘りきることができるようだ。

import Cocoa
import ScriptingBridge

// 元にないやつは optional にしないと extension でエラーになる
@objc protocol SBSystemPreferencesApplication {
    optional var panes: SBElementArray {get}
    func activate()
}


@objc protocol SBSystemPreferencesPane {
    optional var anchors: SBElementArray {get}
    optional var id: NSString {get}
    
}

@objc protocol SBSystemPreferencesAnchor {
    optional var name: NSString {get}
    optional func reveal() -> id_t
}

// protocol 定義を無理矢理使えるようにする
extension SBApplication : SBSystemPreferencesApplication {}
extension SBObject : SBSystemPreferencesPane, SBSystemPreferencesAnchor {}

struct Accessibility {
    static func checkAccessibilityEnabled(app: NSApplicationDelegate) {
        if AXIsProcessTrusted() != 1 {
            let alert = NSAlert()
            alert.messageText = "Require accessibility setting"
            alert.alertStyle = NSAlertStyle.CriticalAlertStyle
            alert.addButtonWithTitle("Open System Preference")
            alert.addButtonWithTitle("Quit")
            if alert.runModal() == 1000 {
                openSecurityPane()
                NSApplication.sharedApplication().terminate(app)
            } else {
                NSApplication.sharedApplication().terminate(app)
            }
        }
    }
    
    static func openSecurityPane() {
        // openURL 使うのが最も簡単だが、アクセシビリティの項目まで選択された状態で開くことができない
        // NSWorkspace.sharedWorkspace().openURL( NSURL.fileURLWithPath("/System/Library/PreferencePanes/Security.prefPane")! )
        
        // ScriptingBridge を使い、表示したいところまで自動で移動させる
        // open System Preference -> Security and Privacy -> Accessibility
        let prefs = SBApplication.applicationWithBundleIdentifier("com.apple.systempreferences")! as SBSystemPreferencesApplication
        prefs.activate()
        for pane_ in prefs.panes! {
            let pane = pane_ as SBSystemPreferencesPane
            if pane.id == "com.apple.preference.security" {
                for anchor_ in pane.anchors! {
                    let anchor = anchor_ as SBSystemPreferencesAnchor
                    if anchor.name == "Privacy_Accessibility" {
                        println(pane, anchor)
                        anchor.reveal!()
                        break
                    }
                }
                break
            }
        }
    }
}
  1. トップ
  2. tech
  3. Swift で Mac の ScriptingBridge を無理矢理つかう

自宅で使っているデスク

Garage CL-147H というやつ (約24kg)。fantoni GT-147H というやつ (約34kg) のほうがかっこいいけど、高い。

天板の色が濃くて、丈夫なやつが安くほしかった。これはかなり満足してる。ウォールナットタイプは幕板がないので左右に揺れやすいみたいだけど、普段使いでは全く気にしたことはない 。

天板自体に鉄パイプで補強がしてあり、60kg まで耐荷重がある。最近のモニタは軽いのでまずギリギリになることはなさそう。ゆすろうとすれば揺れるが、キーボード叩きまくる程度ではほとんど揺れることはない。キーボードを叩いてモニタが揺れたりすると、案外かなりイライラしてくるので、机はできるだけ丈夫で重いのを買うほうが良いと感じる。

デスクの配置

窓に背を向ける形、部屋の中のほうを向いて座っている。こうするとモニタを隔てて狭いスペースに身体が押しこめられるような形になって(狭くて雑然としているのが好きな自分には) 集中しやすい。

この配置だと家族と会話するとき後ろに振りかえる必要がない (ただしモニタで遮られているので相手か自分が少し動く必要がある) し、モニタで表示している内容をカジュアルに見られたりすることがないので、エロ画像を見ててもバレにくいというメリットがある (あんまり家で仕事しないけど、最悪自宅で仕事するときも都合が良い)。

チェア

ITOKI(イトーキ) PRAO(プラオチェア)248C ローバック(T型肘付 樹脂脚) ナイロンキャスター アップルグリーン ブラック KE-248GH-T1T1L6 -

5.0 / 5.0

中古 13000円ぐらいで買ったイトーキのプラオチェアというのを使ってる (前書いたエントリ)。現時点で全く問題に感じる点はない。新品でも5万円ぐらいで、アーロンチェアとかと比べたらかなり安いと思うけど必要十分な機能はあると思う。ただ、金が無限にあるならバロンチェアが欲しいです。

フロアシート 1800×910×1.5mm(1畳サイズ) クリア A712 -

3.0 / 5.0

賃貸なので床にシートをひいている。これは今のところ不満はあまりない (ちょっと見た目が悪いとか、床にくっつきすぎるとかが不満) けど、本質的な問題は次に引越すときに出てきそうなのでなんともいえない。

モニタ ディスプレイ

Dell ディスプレイ モニター P2415Q 23.8インチ/4K/IPS非光沢/6ms/HDMI,DPx2(MST)/sRGB99%/USBハブ/3年間保証 -

4.0 / 5.0

Dell ディスプレイ モニター U2713H 27インチ/WQHD/IPS非光沢/6ms/DVI(DL),HDMI.DPx2(MST)/AdobeRGB 99%/USBハブ/3年間保証 -

5.0 / 5.0

  • P2415Q (23.8インチ 4Kディスプレイ)
  • U2713H (27インチ AdobeRGB 色域ディスプレイ)

をディスプレイアームで固定している。電子工作する関係でとにかくデスクの空いているスペースを広くとりたいので、モニタの本体はデスクの端よりも外に出るように設置している。

エルゴトロン LX Desk Mount LCD Arm 45-241-026 -

5.0 / 5.0

マウス・マウスパッド・キーボード

Logicool ロジクール ワイヤレスマウス M310t シルバー -

5.0 / 5.0


SteelSeries QcK マウスパッド 63004 -

5.0 / 5.0

マウスはロジクールの M310 という無線マウス。手にあうマウスって案外すくないけど、これは使いやすい。

マウスパッドは Steel Series QCK。会社もこれ。ずっとこれ。最高。いちばん売れてるサイズよりもワンサイズ上かな? 小さくてもいい気はしてます。

PFU Happy Hacking Keyboard Professional2 墨 英語配列 静電容量無接点 USBキーボード Nキーロールオーバー UNIX配列 WINDOWS/MAC両対応 ブラック PD-KB400B -

5.0 / 5.0

今使っているキーボードは先日 @naoya_ito さんから頂いた HHKB Pro2 墨で、会社もこれを使ってる (少し前までは自宅では MacBook のキーボードを直接叩いてた) 後ろに「ナオヤモデル」って今度サインしようと思います。最近会うことがないので、自分で…

最近のコード整理事情

ソースコードではなく物理的なコード

デスクの裏に100均のワイヤーラティス(網)をつけているというのは前に書いたが、最近はこれまた100均で2個100円で売られているC型クランプを4つ使い固定するようにした。前まで両面テープで固定していたが、どうしても時間が経過すると落ちてきてしまっていた。クランプを使うことにより完全に落ちなくなったのである程度重さがあるACアダプタとかもデスク裏に置いておけるようになった。ref. [tech] 100均グッズを使ってデスクの天板裏でケーブルの整理 | Sat, Mar 2. 2013 - 氾濫原

配線ボックスに入れるよりは放熱性があるかなという感じ。机の裏のはじっこのほうは案外デッドスペースなので活用できると嬉しい。

C型クランプはこういう感じのやつ (100均のなので、これよりもっと安いけど)

アルミ C型クランプ 50mm -

3.0 / 5.0

周辺機器

スタンダード FT-450DM HF/50MHzトランシーバー 50Wタイプ -

5.0 / 5.0

アマチュア無線関係の機器と電子工作用の機器が端っこに置いてある。前までデスクの上で置いていたけど、作業スペースを増やしたいので、別の棚の上に置く形にしている。

その他

子どものときから、雑然としていて機械いっぱいに囲まれているデスクに憧れがある。昨今の風潮としてはモノは少ないほど良いというのがあって、まぁそれはそうだろうと思うし、なんか賢そうで良いと思うんだけど、それには逆行する形でいろいろ導入している。

測定器は憧れの最たるところで、とにかくかっこいいし夢が広がる。とはいえ現状では「必要に応じて」という原則をどうしても持っているので、自分のスキルレベルが上がらなければ新しい測定器の必要性が出てこない。

ものが増えると(特に家が狭い場合)保有コストというのがバカにならないので、あらゆるモノの導入には抵抗があるが、なんとかしてゴチャゴチャいろいろ置きたい。

  1. トップ
  2. tech
  3. 自宅をかっこいい作業環境にしたい

Xcode のメニューから C ファイルをヘッダファイル込みで作ろうとすると Bridging Header を作るか? と聞かれるので、作るを選ぶと、*-Bridging-Header.h という Obj-C の(?)ヘッダファイルができ、作った C ファイルのヘッダファイルが #import されている。

あとはできた C ファイルに適当に書いて C ファイルのヘッダに適当に関数シグネチャを書けば、Swift 側ではプロジェクト内のグローバル関数として使えるようになっている。全部 Unmanaged だけど調べればほぼその通りうごいてくれる。

ただし一部の複雑な struct を書くと Swift のコンパイルで刺さることがある。自分は kinfo_proc を使いたかったんだけど、まんまとこの罠でハマって2時間ぐらい悩んだ。

  1. トップ
  2. tech
  3. Swift から C で書いた関数を呼びたいとき

takeRetainedValue()
→ 呼び出した関数内で値が retain されている場合こちらを使う。Swift 側でアンラップする際には retain しないでメモリマネジメントに加える。

takeUnretainedValue()
→ 呼びだした関数内で値が retain されていない場合こちらを使う。Swift 側でアンラップする際 retain を行いメモリマネジメントに加える。

どっち使えばいいんだよ

とりあえず takeRetainedValue() を使い、問題が起こらないならそれでよい? もしヌルポが起これば takeUnretainedValue() に変えてみるとか?

Swift の参照カウンタのチェックポイントは関数脱出時のようなので、関数内で完結する分には常に takeRetainedValue() で取り出しても問題がおきない (勝手に解放されない) と思うが、よくわからない。

  1. トップ
  2. tech
  3. Swift takeRetainedValue() or takeUnretainedValue

UIElementInspector は Apple が提供している開発ツールで、マウスカーソル直下にあるアクセシビリティオブジェクトについて、どんな属性と値があるかを表示してくれる。便利

https://developer.apple.com/library/mac/samplecode/UIElementInspector/Introduction/Intro.html

  1. トップ
  2. tech
  3. Mac のアクセシビリティAPIで何が取得できるか簡単に調べられる UIElementInspector

自分のアプリケーション (AXApplication ) の AXEnhancedUserInterface (bool) を調べて、1 が入っていたら VoiceOver が起動している。

Google Chrome を強制的にアクセシビリティ有効にする方法

Google Chrome はこの値を見てアクセシビリティオブジェクトを作るかどうかを決めているようで (パフォーマンスのため?)、デフォルトではアクセシビリティオブジェクトが生成されない。

自分で作ったアプリケーションでアクセシビリティを使いたい場合、これは不便な仕様である。必要に応じて

  • 全アプリケーションに AXEnhancedUserInterface をセット
  • アプリケーションが起動するたびに AXEnhancedUserInterface をセット
  • アプリケーション終了時に AXEnhancedUserInterface をリセット (ただし VoiceOver が起動しているようなら何もしない)

みたいなことが必要になる。

なお Google Chrome でアクセシビリティが有効化されているかどうかは chrome://accessibility を見ればわかる。また、上記 AXEnhancedUserInterface を設定しなくても、一時的でいいのならこのページでアクセシビリティを有効にできる。

有効にしたあとはページのリロードが必要、と思ったけど必要ないっぽい…

  1. トップ
  2. tech
  3. Mac で VoiceOver が起動しているかどうかを判定する方法 / または Google Chrome を強制的にアクセシビリティ有効にする方法

前にMacRuby でスクリーンキャスト用のキーストローク表示スクリプトを書いたんですが、それを Swift で書きなおして機能を追加したりしてアプリにしました。

追加の機能:パスワードフィールドで自動非表示

基本的に AXSecureTextField への入力って、そもそもアクセシビリティのコールバックにこない?っぽいのですが、一部のアプリでは飛んできてしまったり、よくわからない挙動をします。

なので、こちらのツール側で、パスワードフィールドかどうかを判定して非表示に切り替えています。

と書くと簡単なんですが、実際一番やりたい Google Chrome ではデフォルトではアクセシビリティオブジェクトが生成されないみたいな罠があったり (VoiceOver が有効でなければアクセシビリティオブジェクトを作らない)、やっかいです。

あとよくやるパスワード入力といえば sudo ですが、ローカルについては sudo のプロセスが生きている限り自動的に非表示にするようにできるのですが、リモートではうまくできる方法が思いついていません (Terminal.app の画面内容をちゃんととれればヒューリスティックに判定できそうなんですが、screen 内だとそもそもとれないので諦めた)

Mac App Store

github で公開しつつ Mac AppStore に試しに出してみたいなと思っていたんですが、そもそもアクセシビリティAPIで他のアプリにちょっかいを出すアプリは、Mac AppStore で要求される App Sandbox 内では正常に動作しないみたいなので諦めました。

つまりアクセシビリティ機能を向上するためのアプリ (Assistive app) というのは Mac AppStore では出せないってことっぽいですね。純正の VoiceOver でも使ってろってことなんでしょうかね。

  1. トップ
  2. tech
  3. スクリーンキャスト用のキーストローク表示アプリ

Xcode 6.1.1 で Shortcut Recorder の 440a3d18e688142cd00fc88e4dc36ff355448fa6 を使ってみたらうまくいかなかった。

Xcode 上の Interface Builder で Custom View を追加し、Class を SRRecorderControl にすると、ビューがロードされてちゃんと表示される、という状態までは簡単にいけた。

しかし起動させてみるとグレーアウトされた状態になってしまった。これは enabled になっていないようなので、awakeFromNib で sr.enabled = true を付け加えた。これで起動させると、ひとまず動き、キー入力を受け付ける状態までは進むようになった。

しかし、キーを実際に入力しようとすると一切入力できず、無反応だった。これはどうやたら修飾キーまわりの設定が全くされていないとこのような挙動になるようだ。

結局 Shortcut Recorder のソースコードに println() を仕込みながら調べるハメになったが、デフォルトで設定されるはずのプロパティが一切設定されていないということがわかった。なので結局のところ自力で以下のようなコードを追加した。

inputHotkey.delegate = self
inputHotkey.allowsEscapeToCancelRecording = true
inputHotkey.setAllowedModifierFlags((NSEventModifierFlags.ShiftKeyMask | NSEventModifierFlags.CommandKeyMask | NSEventModifierFlags.ControlKeyMask | NSEventModifierFlags.AlternateKeyMask).rawValue, requiredModifierFlags: 0, allowsEmptyModifierFlags: false)
inputHotkey.enabled = true

該当コントロールのデフォルト値は initWithFrame: で行われているが、Interface Builder で配置したコントローラは initWithCoder: で初期化されるようなので、この処理が走らない。

Interface Builder 経由で置くことが想定されていないのだろうか。とはいえ README では IB で置けとも書いてあるし、よくわからない。

  1. トップ
  2. tech
  3. Shortcut Recorder がうまく動かなかった
  1. トップ
  2. swift
  3. Shortcut Recorder がうまく動かなかった
  1. トップ
  2. cocoa
  3. Shortcut Recorder がうまく動かなかった

水曜日に体調不良で会社を休んだ。といっても自分は頭痛と身体がだるいというだけで熱はなく、妻が高熱を出したために主に子供の面倒を見る必要があった。

子供の熱からの両親ダウンというパターンだった。これ思いのほか厳しい。子供が元気になってから親が体調不良になると、子供はとにかく元気良く、相手をするのが辛い。

あと自分は普段離乳食を作っておらず任せっぱなしだったので勝手がわからず苦労した。レトルトもあったので使ったらよかったが、頭が働いておらず効率的な方法を描けなかった。普段からの訓練が必要とは思っていながらも、やってもらってると甘えてしまう。

書いてなかったけど保育園は第一希望で内定しました。既に入園検診済み。

園長面談(平日だけど両親参加必須)というのがどういうものなのか心配……

保育園入園時に必要なものに、サイズ指定のグッズいろいろがあり、調達に悩んだ結果自作した話。

入園グッズの工面方法

  • 手芸店に外注 (布団カバー1つで工賃だけで4000円ぐらい)
  • 自分で作る
  • なんとかして既製品を探す

といった方法がある

外注しなかった理由

習得も含めた時間などのコストと得られるメリットとのトレードオフになる。外注できるならしてもいいが

  • 必要なものの工賃だけでミシン買えるぐらいする(人件費考えれば妥当な値段だけど)
  • ミシンも自由にあつかえないとか技術力低いのでは?
  • 子供が学校でミシンやるとき教えられるぐらいのスキルは欲しい
  • 今後もたびたび作ることになりそう

といった点を鑑みてミシンを買った。これ

トーヨー 電動ミシン レッド JY-1R -

5.0 / 5.0

実際に作る場合、ほかにもいろいろ必要なものがある。

  • 裁ち鋏
  • 糸切り鋏
  • 定規 (メジャーとかでもなんとかなるけど、チャコペンで線をひきにくい)
  • チャコ
  • ミシン糸 (#30〜#60ぐらい?)
  • ミシン針 (ミシンにも付属してるが太さがよくわからない。12 14 16 号あたりが必要?)
  • ボビン (ミシンに付属してる)
  • マチ針
  • ハリ山
  • 布 (案外高い)

ずっと裁縫道具は保存していたのでだいたいはなんとかなった。

大抵100円均一でも売ってるのでとりあえずはなんとかなりそう。ただ刃物系、糸切りハサミと断ちバサミはちゃんとしたのを買ったほうがストレスが少ないと思われる。

レオニス カラーミシン針セット(9号×2本/11号×4本/14号×2本/16号×2本) -

3.0 / 5.0

SEWING 洋裁・手芸鋏 キャップ付 20.5cm ソフトリング -

3.0 / 5.0

Clover 糸切はさみ[ブラック]黒刃(10.5cm) -

3.0 / 5.0

布団カバー

まず作ったのが布団カバー。1つあたり布が260cmぐらい必要なので、布代だけで 2000 円はかかる (800円/m だとして)

比較的簡単だと思うが、縫う距離が長いので時間がかかる。裁断からやってできあがりまで、1枚あたり2時間〜3時間ぐらいかかった。

つまり時給1500円でも人件費だけで3000円〜4500円かかることになり、オーダーメイドの工賃は十分妥当な金額とわかる。

なので、その金額を外に出すか、自分でその分の仕事をするかの選択になる。(前述の通り内製で処理することにした。気楽に自力でそれだけ稼げる仕事なんてなかなかないわけだし)

品質はともかく作ることはできた。自分の子供が使うのだから過剰に品質にこだわることもないだろう。

のこり

まだまだ作るのがある。たぶんコツを捕めば楽しい気がするのでがんばる。

外注の考えかた

自分でやるのとコストがあまり変わらない場合 (スケールメリットがないとか) で自分でなんとかできそうなことなら、自分でやるほうを優先したい。外注してもスキルは得られず金が減るが、自作すればスキルも得られて金が出ていなかない。なにより技術力はずっと残って財産になる。

  1. トップ
  2. tech
  3. 保育園の入園グッズをつくるためにミシンを買った

アイロンで写せる型紙を購入したのだけれど、見ての通り色の濃い生地を買ってしまったので全く写らず (写ってるけど見えない)、チャコペーパーをひいてがんばって写した…… というか厚紙に型紙起こしなおしたほうがいいかもしれない。むずかしい。

キルティング地なのですこし不安だったけど、とくに問題もなく製作できた。

紐の通し口の処理が勉強になった。

布端のかがりを細かいジグザグではじめてしまったのでだいぶ時間がかかってしまった。とはいえ全体の作業時間は型紙写すのに試行錯誤した時間を含め2時間弱ぐらい。

備考

これも保育園グッズの一つなのだが、保育園からの要求仕様には「コップ入れ」とか書かれておらず、どのぐらいのサイズが必要なのか、全くわからない。中に入れるコップのサイズが分からないのに、コップ入れを用意しろといわれる。世の中は厳しい。

  1. トップ
  2. tech
  3. 今日のミシン: コップ入れ

出社した直後ぐらいからだるくなり、12時ごろに「もうこれはだめだな」と思い早退。

帰宅時点では37°ぐらいの微熱。悪寒がするので熱めの風呂に入ってからすぐ寝て、15時ぐらいに37.8°ぐらい。生卵をTKGとして摂取してひたすら寝つ続け、20時ぐらいに37.3°ぐらいまで下がる。それからまたひたすら寝て朝がたに36.5°ぐらいの平熱になった。

型紙付属のレシピから変えてマジックテープ式にしようとしたら (保育園の要求仕様を満たすため)、いろいろ失敗してしまった。マジックテープがどうも固く、ジグザグ縫いで目が飛びまくりどうしようもなく、しかたなく直線に変えたり、マチをつけて固定するところで手縫いする必要があるのだが、玉止めがうまくいかず……

とはいえ一応実用上は問題ない形に仕上げた…… 精進が必要。

OLFA セーフティロータリカッター L型 156B -

5.0 / 5.0

OLFA 円形刃45mm替刃 RB45-1 -

5.0 / 5.0

OLFA カッターマットA2 159B -

5.0 / 5.0

布を切るといえば裁ち鋏でしょ??と思って思考停止していたけど、ローリングカッターを使ったほうが圧倒的に楽チンだった。

  1. 布を浮かす必要がない
    • 裁断精度があがる
  2. 1つの動作で完結できる
    • 裁ち鋏だと「ハサミを開く」「線にあわせる」「ハサミを線にあわせて閉じる」「途中で開いなおしてすすめる」を繰替えす
    • ローリングカッターはまっすぐ押すだけ。良く切れるのでほぼパツイチ

ただし欠点があって、一度に切れる長さはカッターマットの大きさに制限される。

裁断が結構気が重い作業だけど気が楽になるし、時短できるしチートアイテムっぽい。

#!/usr/bin/xcrun swift
import Cocoa
struct ProgramOption {
var list : Bool = false
var set : String? = nil
var help : Bool = false
}
func getInstalledBrowsers () -> [ NSBundle ] {
var browsers = [ NSBundle ]()
let array = LSCopyAllHandlersForURLScheme("http").takeRetainedValue()
for var i = 0, len = CFArrayGetCount(array); i < len; i++ {
let bundleId = unsafeBitCast(CFArrayGetValueAtIndex(array, i), CFString.self) as String
if let path = NSWorkspace.sharedWorkspace().absolutePathForAppBundleWithIdentifier(bundleId) {
if let bundle = NSBundle(path: path) {
// let name: String = bundle.infoDictionary!["CFBundleName"] as String
browsers.append(bundle)
}
}
}
return browsers
}
func setDefaultBrowser (bundleId : String) -> Bool {
let httpResult = LSSetDefaultHandlerForURLScheme("http", bundleId)
let httpsResult = LSSetDefaultHandlerForURLScheme("https", bundleId)
if httpResult == noErr && httpsResult == noErr {
return true
} else {
return false
}
}
var option = ProgramOption()
for var i = 0, len = Process.arguments.count; i < len; i++ {
let arg = Process.arguments[i]
switch arg {
case "-h", "--help":
option.help = true
case "-l", "--list":
option.list = true
case "-s", "--set":
option.set = Process.arguments[++i]
default:
break
}
}
if option.help {
println("-h, --help: Show help (this)")
println("-l, --list: Show installed browser list")
println("-s [bundleId], --set [bundleId]: Set default browser to specified browser")
exit(0)
}
if option.list {
let browsers = getInstalledBrowsers()
for browser in browsers {
let bundleId = browser.bundleIdentifier!
let path = browser.bundlePath
println("\(bundleId)")
println("\t\(path)")
}
}
if let bundleId = option.set {
if setDefaultBrowser(bundleId) {
exit(0)
} else {
exit(1)
}
}
exit(0)

peco る

set_default_browser.swift --set $( set_default_browser.swift -l | grep -v "\t" | peco )

雑にpecoれる

経緯

むかしむかしに Obj-C で書いたことがあってな

  1. トップ
  2. tech
  3. デフォルトブラウザを5秒に1回変える人に便利な Swift スクリプト書いた (Mac)

全体的にむずかしくないはずなのに、取っ手をつける位置を間違えて一旦リッパーで完全にとってやりなおすという無駄な作業が発生した。つらかった。

これで要求されていた保育園グッズは終わり。

柄違いのも作っていた。コップ入れは大変簡単で、裁断がおわれば30分ぐらいで作れた(これは朝出社前に縫った)

花粉症の季節なのでポケットティッシュを割と持ち歩いているのだけれど、雑にカバンの中に放りこんでおくとぐちゃぐちゃになってダメになってしまうことが多々あってつらかった。

ということで作った。

最初、ある本に書いてある通りにつくったらサイズがあわず、結局自分で計って作りなおした。ポケットティッシュは 8cm x 11cm x 0.5cm ぐらいの大きさなので、これを収めるには 9cm x 12cm ぐらいの広さが必要だった。

工程自体は難しくないけど、正確に布を切ることが神経をつかうし、とにかく難しい。

哺乳瓶入れが1つしかなくもう1つ欲しいという要望をうけて作った。

別の作例を参考にサイズを変えて作ったのだけど、計算を間違えたのか、つまむと2cmぐらい余分がでるぐらいの大きさになってしまった。

下を「わ」にして「折りマチ」をつけたタイプで、キルティングの1枚の布からできている。

筒状のものは一定のサイズ以下になるとミシンの腕に入らなくなって縫えなくなるということがわかった。紐片方出しの場合どうしても筒状にしてから縫う必要がある(と思う)ので、一定サイズ以下の場合両出しで締める構造にしなければならない気がする。

前述の通り何かを間違えてちょっと大きめにできてしまったが、おかげて筒状にしてもぎりぎり縫えるサイズにおさまった。実用上困るほどの大きさの違いではないので「失敗」の知見をためつつ実用上は「成功」ということにしておく。

ミシンに少し慣れてきたので、今まで「自分で作る」ことを考えたこともなかったことについて、改めて「自分で作れるならどんなものを作るか?」と考えている。

たとえば普段使いのカバンのアイデア

  • 箱のティッシュを組込めること
  • ゴミ箱ポケットをつけること
  • 13インチ MacBook がそのまま放りこめること

これらを満たすもの、特に最初の2つを満たすカバンというのは見たことがないので、技術力があれば作りたいなという気持ちがある。

かなり重いものを入れがちなカバンを自分で作るのは不安が多いが、そうでないなら自分で作っても面白そう。