jsonからGPUImageFilterを生成する

#はじめに
GPUImageFilterをビルドせずに書き換えたい！
申請せずにサーバーからフィルタを更新したい！
よし！jsonファイルから色んなGPUImageFilterを生成しよう！

#参考
[[Objective-C] 文字列からインスタンスの生成とメソッド呼び出し（プロパティの設定）をやってみる]
(http://qiita.com/edo_m18/items/4613acf85816b979f193#comment-0e7704770e1fdb722926)

#GPUImageFilterDictionary

メインのメソッドです。
こいつににjsonファイルを渡すと指定されたフィルタが生成されます。

##ヘッダ部と実装部

```objc:GPUImageFilterDictionary.h
#import <GPUImage/GPUImage.h>

@interface GPUImageFilterDictionary : NSObject
@property(nonatomic, strong)NSString *version;
@property(nonatomic, strong)NSString *key; 
@property(nonatomic, strong)NSString *type;
@property(nonatomic, strong)GPUImageOutput *gpuImage; /*キモになるプロパティ*/
-(instancetype)initWithJsonFilePath:(NSString*)jsonFilePath;/
@end
```

```objc:GPUImageFilterDictionary.m
長いから省略 githubを見てください
```
[GPUImageJson(Github)](https://github.com/sakiyamaK/GPUImageJson/blob/master/GPUImageJson/GPUImageFilterDictionary.m)にあげています。
jsonからObjCを制御するキモになってるカテゴリは[ここ](https://github.com/sakiyamaK/GPUImageJson/blob/master/GPUImageJson/NSObject%2BinstanceFromDictionary.m)

##使い方

```objc
@interface ViewController ()
@property (nonatomic, strong) GPUImageVideoCamera *videoCamera;
@property (nonatomic, strong) GPUImageView *previewView;
@property (nonatomic, strong) GPUImageFilterDictionary *filterDic;
@end

@implementation ViewController
/*
GPUImageVideoCameraのスタートや
GPUImageViewの配置は省略
*/

//フィルタの生成と連結
-(void)setupFilter{
  //sample_filter.jsonから指定のGPUImageFilterをもったGPUImageFilterDictionaryのインスタンスをを生成
  GPUImageFilterDictionary *filterDic = [[GPUImageFilterDictionary alloc] initWithJsonFilePath:@"sample_filter"];
  _filterDic = filterDic;
  
  //連結するフィルタの取得
  GPUImageFilter *createFilter = (GPUImageFilter *)filterDic.gpuImage;
  
  //連結
  [_videoCamera addTarget:createFilter];
  [createFilter addTarget:_previewView];
}
@end 
```

#仕様
今のところ生成できるのは
・ <b>GPUImageFilter</b>
・ <b>GPUImageImagePicture</b>
・ <b>GPUImageImageFilterGroup</b>
の３つとそのサブクラスです

プロパティやメソッドの引数で対応している型は
・ <b>bool, char int, short, long, long long, float, double, NSInteger,</b> あとそれぞれの<b>unsigned</b>
・ <b>CGPoint, CGRect, CGVector, CGSize, CGAffineTransform, UIEdgeInsets, UIEdgeInsets</b>
・ <b>Objective-Cのクラス</b>
です
その他の型を引数にとるメソッドは使えませんが、今のところ困ってないです。

#jsonファイル

##GPUImageFilterとGPUImagePictureの書き方
```json:説明
{
  "ver": /*jsonのバージョン番号 任意の数*/,
  "key": /*ソース内でフィルタを分類するkey 任意の一意な文字列*/,
  "type": /*呼び出すクラス*/,
  "property_list":/*呼び出すプロパティの配列*/
  [
    {"property": /*プロパティ名*/,
     "type":/*代入する値の型 unsigned longなどのスペースがある場合はunsigned_longとする */,
     "value":/*プロパティに代入する値*/
    }
  ],
   "method_list":/*呼び出すメソッドの配列 さらに別クラスのメソッドを入れ子で実行できる*/
  [
    {
      "method_name":/*メソッド名*/,
      "method_type_list":/*メソッドの種類を指定する配列 イニシャライザを意味する「init」かクラスメソッドを意味する「class」を指定する　どちらでもないなら記載しなくてよい*/,
      "param_list":/*メソッドに代入するパラメータの配列*/
      [
        {"type":/*パラメータの型*/,
         "value":/*パラメータの値*/
        }
      ]
    }
```

##例

例として<b>GPUImageBrightnessFilter</b>を生成するjsonファイル
brightnessプロパティの値を0.5にしたインスタンスを生成します。

###json

```json:gpuimagefilter.json
{
  "ver": 1,
  "key": "g1",
  "type":"GPUImageBrightnessFilter",
  "property_list":[{"property":"brightness", "type":"float", "value":0.5}],
}
```
###出力

これで生成されるGPUImageFilterを通すとこんな感じの画像が出力されます。

<img width="320" alt="IMG_5553.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/105057/578b3a7f-fe07-35e8-74f2-8580b2a7ed7c.png">

##GPUImageFilterGroupの書き方
```json:説明
{
  "ver": /*jsonのバージョン番号 任意の数*/,
  "key": /*ソース内でフィルタを分類するkey 任意の一意な文字列*/,
  "type": GPUImageFilterGroup,
  "create":[/*GPUImageFilterGroupで連結するフィルタの配列(中身はGPUImageFilterをつくるjsonと同じ)*/],
  "add_targets":[/*add_targetでの連結を指定する配列 fromからtoへ連結する locationでtextureLocationを指定する*/
                 {"from":, /*createで生成したフィルタのkey*/
                  "to":,/*createで生成したフィルタのkey*/ 
                  "location":/*textureLocationの数値*/
                 },
                 ],
  /*GPUImageFilterGroupのinitialFiltersの配列 createで生成したフィルタのkey */
  "initialFilters":[],
  /*GPUImageFilterGroupのterminalFilter createで生成したフィルタのkey */
  "terminalFilter":,
}

```

## 例

・<b>GPUImageBrightnessFilter</b>を通して
・test.pngを<b>GPUImagePicture</b>で読み込んで
・<b>GPUImageAlphaBlendFilter</b>で混ぜる
というfiltergroupを作ります

### json

<b>GPUImagePicture</b>は<b>initWithImage:(UIImage*)</b>メソッドで生成します
この引数の<b>UIImage</b>も<b>imageNamed:</b>メソッドをjsonで入れ子で指定して生成します

```json:gpuimagefiltergroup
{
  "ver": 1,
  "key": "g1",
  "type":"GPUImageFilterGroup",
  "create":[
            {
            "key":"f1",
            "type":"GPUImageBrightnessFilter",
            "property_list":[{"property":"brightness", "type":"float", "value":0.5}],
            },
            {
            "key":"f2",
            "type":"GPUImageAlphaBlendFilter",
            "property_list":[{"property":"mix", "type":"float", "value":0.5}],
            },
            {
            "key":"p1",
            "type":"GPUImagePicture",
            "method_list":[
                           {
                           "method_name":"initWithImage:",
                           "method_type_list":["init"],
                           "param_list":[
                                         {"type":"UIImage",
                                         "method_list":[{
                                                        "method_name":"imageNamed:",
                                                        "method_type_list":["init","class"],
                                                        "param_list":[{"type":"NSString",
                                                                      "value":"test.png"}],
                                                        }],
                                         },
                                         ]
                           }
                           ],
            },
            ],
  "add_targets":[
                 {"from":"f1", "to":"f2", "location":0},
                 {"from":"p1", "to":"f2", "location":1},
                 ],
  "initialFilters":["f1"],
  "terminalFilter":"f2",
}
```

###test.png
こんな画像を画面いっぱいにブレンドします
![test.png](https://qiita-image-store.s3.amazonaws.com/0/105057/b6c740ca-6953-478f-54e6-8b7703f27dd4.png)



###出力
<img width="320" alt="IMG_5552.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/105057/21979c83-6853-79eb-318f-3af4baa53424.png">


#サンプルソース
[GPUImageJson(Github)](https://github.com/sakiyamaK/GPUImageJson)


#まとめ
これでサーバーからjsonを指定して自由にGPUImgageのフィルタが更新できる！
それにしても相変わらず俺得なことしかまとめてないな