Illustratorの代わりにAffinity Designerを使う

affinity design 2019 06 14 00 10 59

Adobe IllustratorをCS4から10年以上使っているんですが、そろそろAdobeにも飽きてきたので他の選択肢を探してみようと思い色々休日に調べていました。 探してみると選択肢は非常に少なく、フリーのInkscapeか有償のAffinity Designerのどちらかを選ぶという状況です。 Affinity Designerも有償と言えど6,000円程なので、たったのCC1ヶ月分です。

https://affinity.serif.com/ja-jp/designer/

Affinityという名前は初めて聞いたのですが、多くのIllustratorの機能をサポートしている上に、公式サイト・ヘルプが日本語に翻訳されており敷居も低いです。製品ラインは3つ用意されており、

  • Affinity Photo: Adobe Photoshopの代替え
  • Affinity Designer: Adobe Illustratorの代替え
  • Affinity Publisher: Adobe Indesignの代替え

といった様子です。 今回はAffinity Designerの無料試用版を使用して、使い勝手を確認します。

こちらが全体の画面です。 遊んでいる鉄道ゲームの路線図を作ってみました。

affinity design 2019 06 14 00 12 46

結論

  • Affinity Designerのメリット

    • 全体的に動作が非常に軽快
    • ドロー・ペイントがシームレスに統合されている
    • 写真・図に対してトーンカーブ・輝度調整等の補正が使用可能
    • スナップが高機能
    • 星型などのシェイプが使いやすい
    • シンボルへの反映がリアルタイムで反映して、使用感が非常に良い
    • 複製機能が凄すぎる
    • 6,000円と安価
  • Affinity Designerのデメリット

    • 印刷会社が公式にサポートしていないので、入稿に不安
    • 3Dグリッド等の、最近のイラレで利用可能な特殊な機能は無い
    • パターン作成機能に乏しい

機能レベルでの良い所

ペルソナ

ペルソナ切り替え機能で、ベクトル・ピクセル描写のモードを一瞬で切り替えることが出来ます。 ペルソナは3つ用意されています。

  • 描画ペルソナ

    • ドロー系
    • ペンツール・長方形楕円などのシェイプツール
  • ピクセルペルソナ

    • ラスタ形式のピクセルを操作するモード
    • Photoshopのような機能
    • ブラシ・覆い焼き・ぼかしブラシ・
  • エクスポートペルソナ

    • ドキュメントの書き出し方法を定義する
    • スライスツール

簡単な写真レタッチ・イラストへの書き込みを行い、制作物のデザインを行うなど、Adobeでは複数製品を利用する必要がある操作が、単一のソフトで行なえます。

ペルソナを切り替えると、利用可能なツールも切り替わります。

スナップが高機能

全体的にスナップ機能が高機能に感じますが、1つだけ例を紹介します。 文字オブジェクトのスナップに対して、上下左右中央のスナップが効きます。 Illustratorでは確か無い機能なので非常に嬉しいですね。

affinity design 2019 06 13 23 39 17

アートボードでのトリム

\ キー一発でアートボードでトリムできるので、全体を見渡す時に非常に便利です。 あと、製作時の画面・書き出し後の画像の差異がIllustratorに比べると少ないように感じます。

シンボル

シンボルへの変更がリアルタイムで反映されていくのが衝撃的でした。 レスポンシブなシンボルを定義する機能も有りますので、かなり高機能に感じます。

色調調整

トーンカーブ・輝度調整・ポスタライゼーション等の補正がそのまま使用可能です。 ペンツールで描写した図形・配置した写真両方への編集が可能です。 全体的に少し明るくしたい等の事もPhotoshopに頼る必要がないです。

シェイプ・カーブ

描写可能な図形の種類がかなり多いです。すごい。

affinity design 2019 06 13 23 54 17

そして、シェイプ(四角・円・星等)とカーブ(ペンで描く曲線)が明確に分かれており、後から形状の変更が可能です。 動的に様子を見ながら調整できて良いですね。

イラレも最近ライブシェイプとしてCCでサポートしましたが、まだ熟れていないように感じます。

コーナーツール

角を丸くする度合いを後から自由に変更できます。 イラレも最近ライブコーナーウィジェットとしてCCでサポートしました。

まとめ

最高だからIllustratorを卒業してaffinity designer使おうかなと思う…

  • Q. PDF入稿で良いのでは?

    • .ai .eps 入稿が必須になるグッズ等の発注でなければ大丈夫だと思う
    • テンプレート等の .ai ファイルも開けるが、PDF互換モードでしか使えない
  • Q. お金払えるならイラレで良くない?

    • DTPやってる人はイラレ手放せないと思う
    • 趣味でWebデザインとかペライチのチラシ作るならこっちのほうが楽な場合も多い
    • ライブペイント等のイラレにしかない機能も有るので、どちらが合うかはその人次第
続きを読む

Go言語で実装するプラグイン機構

ソフトウェアに拡張性を持たせる時にプラグイン機構を持たせる事は一般的ですが、それを実現する方法は結構バラバラなのかなと思います。例えば、

  1. C言語等の.so/.dllを読み込む方法
  2. Nodejsのような言語での単なるimport
  3. TCPやUnixソケットを利用してRPC通信を行う方法

などが有るのかなと思います。1番目・2番目は、関数の呼び出し速度等のオーバーヘッドが少なく高速ですが、言語等の制約が大きくなる・メモリを共有することによるセキュリティリスクが発生します。そこで、提供するインターフェースを制約出来る場合は、3番目の手法が多く使われるようです。

Go言語で開発されている、hashicorp/terraform cloudfoundry/cli は共に3番目のRPC通信でプラグイン機構を実装しています。その中でもterraformで使用されているプラグイン機構は、言語への依存が低いという特徴があり、興味深いので調べてみました。

hashicorp/go-pluginを試す

https://github.com/hashicorp/go-plugin

HashiCorpが開発しているライブラリで、Packer, Terraform, Nomad, Vault等の内部で利用されています。RPCにgRPCを使用していて、ホスト側のライブラリはGo言語ですが、クライアント(プラグイン側)の言語依存がほぼ無いのが特徴です。Go+Go/Go+Nodejs/Go+Python等の構成が非常に簡単に実現できます。また、実装も非常に軽いです。

試しにGoのホストと、Scalaのプラグインという構成で雑に試してみました。

サンプルリポジトリ: https://github.com/kamijin-fanta/go-plugin-example

このような簡単なサービスを実装してみました。サービスの定義・実装は素のgRPCとして実装するので、言語に合ったツールを使用します。Scalaでのサーバ実装には、protocの代わりに ScalaPB のコード生成を使用しました。traitが自動的に生成されるので、それぞれのメソッド(ここではSayHello)を実装するだけです。

// サービス定義
syntax = "proto3";
package com.example.protos;

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}
// サーバ実装
class GreeterImpl extends GreeterGrpc.Greeter {
  override def sayHello(req: HelloRequest) = {
    val reply = HelloReply(message = "Hello " + req.name)
    Future.successful(reply)
  }
}
var Handshake = plugin.HandshakeConfig{
  ProtocolVersion:  1,
}
var PluginMap = map[string]plugin.Plugin{
  "greeter": &GreeterGRPCPlugin{},
}
client := plugin.NewClient(&plugin.ClientConfig{
  HandshakeConfig:  Handshake,
  Plugins:          PluginMap,
  Cmd:              exec.Command(os.Getenv("PLUGIN")),
  AllowedProtocols: []plugin.Protocol{plugin.ProtocolGRPC},
})

rpcClient, _ := client.Client()
raw, _ := rpcClient.Dispense("greeter")
service := raw.(Greeter)
result, _ := service.Hello("fukuyama") // Hello fukuyama

多くのコードを省略しているので、詳細はリポジトリよりコードを探してください。

通信フロー

hashicorp/go-pluginでは、TCPのgRPCを用いて通信を行いますが、ホストはポート番号等をどうやって知っているのでしょうか?簡単に図にしてみました。

  1. ホスト側はプラグインをForkExecする
  2. プラグインはネゴシエーションのための文字列を標準出力でホストに伝える (APIバージョン/接続プロトコル/Listenアドレスが含まれる)
  3. ホスト側のAPIバージョンと一致していれば、指定されたアドレスへgRPC接続を行う
  4. サービスのヘルスチェックを行う
  5. プラグインの通信を行う
  6. 通信が終了する際にホストはプラグインのプロセスを終了する

Negotiation

ネゴシエーションの為にプラグインからホストに送られる文字列は、1|1|tcp|127.0.0.1:1234|grpcの様な形式です。

CORE-PROTOCOL-VERSION | APP-PROTOCOL-VERSION | NETWORK-TYPE | NETWORK-ADDR | PROTOCOL
  • CORE-PROTOCOL-VERSION go-plugin自体のAPIバージョンで、現在は1
  • APP-PROTOCOL-VERSION ユーザが用意するAPIのバージョン
  • NETWORK-TYPE unixかtcpが指定可能
  • NETWORK-ADDR 接続先のアドレス
  • PROTOCOL grpcかnetrpcが指定可能

Health Check

ヘルスチェックは、gRPCを通じて行われます。プラグイン側はHealthサービスを実装している必要があります。とりあえず面倒なら常に status: ServingStatus.SERVING を返しておけば良いです。

message HealthCheckRequest {
  string service = 1;
}

message HealthCheckResponse {
  enum ServingStatus {
    UNKNOWN = 0;
    SERVING = 1;
    NOT_SERVING = 2;
  }
  ServingStatus status = 1;
}

service Health {
  rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
}

health.proto: https://github.com/grpc/grpc/blob/master/src/proto/grpc/health/v1/health.proto

雑記

これを調べるきっかけは、Grafanaを調べている時に見つけたBackendPluginsでした。Grafanaのプラグインの種類は他に、Palnel Plugin, Datasource Pluginの2種類有るのですが、いずれもJSで記述するフロントエンドのプラグインです。認証等のコードを差し込めるように用意されたのがBackend Pluginsです。

Developing Backend Plugins: https://grafana.com/docs/plugins/developing/backend-plugins-guide/

このプラグインに採用されている仕組みが hashicorp/go-plugin でした。現在はDataSourceとRendererの2つのAPIしか用意されていないようですが、今後増えてくると拡張性が非常に増すのではないかと思います。

公式が用意している grafana/grafana-image-renderer プラグインは、TypeScriptで全て書かれています。言語に依存されない利点を活用しています。Nodejs上でgRPCサーバを用意し、今回のガイドと同じ様な実装を行ってサービスをプラグインとして提供しています。まだサードパーティのプラグインを受け入れるという感じでは無いのが悲しいですが、時間の問題だと思います。

go plugin 2019 05 17 17 50 29

↑水と油のリポジトリ

参考

続きを読む