Releases: routersys/YMM4-ShapePaste
v1.0.0
v1.0.0 - 図形の貼り付け for YMM4 初回リリース
YukkuriMovieMaker4 向けの映像エフェクトプラグイン 図形の貼り付け の初回リリースです。
任意の図形を指定した位置・サイズ・回転・不透明度で描画し、
Direct2D の ColorMatrix・AffineTransform2D・Composite エフェクトチェーンで
変形・不透明度制御・合成を行う映像エフェクトプラグインです。
新機能
1. エフェクトの登録
ShapePasteEffect は VideoEffectBase を継承します。
[VideoEffect]属性によりカテゴリVideoEffectCategories.Decorationに登録されます。- 検索タグとして
"Shape Paste"・"図形貼り付け"の 2 つが登録されます。 IsAviUtlSupported = falseにより AviUtl フィルタ形式(.exo出力)は非対応です。CreateExoVideoFiltersは空のシーケンスを返却します。LabelはTexts.ShapePasteEffectDefaultNameを返却します。GetAnimatables()はX・Y・Z・Opacity・Zoom・Rotation・Left・Right・
Top・Bottom・ShapeParameterの 11 個のIAnimatableインスタンスを返却します。
すべてのアニメーションパラメータでキーフレームアニメーションに対応しています。
2. パラメータ
X・Y・Z(描画位置座標)
[AnimationSlider] 属性を持つ Animation プロパティです。
[DrawPositionVisible] 属性により IsFullyPinned が true の場合は非表示になります。
- X・Y: 初期値
0、範囲 ±VeryLargeValue、単位px。描画位置の平行移動に使用します。
サイズ追従が有効な場合は固定端の位置から自動計算したオフセットが使用されます。 - Z: 初期値
0、範囲 ±VeryLargeValue、単位px。視点距離1000を基準とした
透視投影スケールの算出に使用します。Zが視点距離(1000)に近づくと分母がゼロに
近づくため、最小スケール1e-5でクランプして映像の消失を防ぎます。
Opacity(不透明度)
[AnimationSlider] 属性を持つ Animation プロパティです。初期値 100.0、範囲 0〜100、単位 %。
ColorMatrix エフェクトのアルファ成分(M44)に opacity / 100.0 を設定することで
不透明度を制御します。RGB 成分(M11・M22・M33)は 1f で固定されます。
Zoom(拡大率)
[AnimationSlider] 属性を持つ Animation プロパティです。初期値 100.0、範囲 0〜VeryLargeValue、単位 %。
[DrawPositionVisible] 属性により IsFullyPinned が true の場合は非表示になります。
Z 座標から算出した透視投影スケール(PerspectiveDistance / (PerspectiveDistance - Z))と
乗算した値を finalScale として AffineTransform2D のスケール変換に適用します。
finalScale は最小スケール 1e-5 でクランプされます。
サイズ追従が有効かつ IResizableShapeParameter に対応した図形の場合、スケールは 1f 固定となり
IResizableShapeParameter.Resize による直接リサイズが行われます。
Rotation(回転)
[AnimationSlider] 属性を持つ Animation プロパティです。初期値 0、範囲 ±VeryLargeValue、単位 °。
度数法の値を value * Math.PI / 180.0 でラジアンに変換し、AffineTransform2D の
回転変換に適用します。
InvertX・InvertY(左右反転・上下反転)
[ToggleSlider] 属性を持つ bool プロパティです。既定値は false。
スケール行列の符号を反転(finalScaleX *= -1f / finalScaleY *= -1f)することで実現します。
DisplayMode(表示方法)
[EnumComboBox] 属性を持つ ShapeDisplayMode 列挙型プロパティです。
既定値は ShapeDisplayMode.Overlay(そのまま重ねて表示)です。
プロパティの変更は Set(ref field, value) により VideoEffectBase の変更通知機構を通じて
プロセッサへ伝播します。詳細は「3. 表示方法と合成モード」を参照してください。
IsBack(背面に描画)
[ToggleSlider] 属性を持つ bool プロパティです。既定値は false。
[IsBackVisible] 属性により DisplayMode が ShapeDisplayMode.Overlay の場合のみ表示されます。
Overlay モード時に Composite の入力順を反転させることで、図形を元アイテムの
背面に配置します。
PinLeft・PinRight・PinTop・PinBottom(端の固定)
[ToggleSlider] 属性を持つ bool プロパティです。既定値はすべて false。
各プロパティの変更通知は nameof(IsSizeTrackingEnabled) および nameof(IsFullyPinned) を
追加で発行し、依存プロパティの表示状態を連動して更新します。
IsSizeTrackingEnabled:PinLeft || PinRight || PinTop || PinBottom。いずれか 1 つ以上が
有効な場合にサイズ追従処理が起動します。IsFullyPinned:PinLeft && PinRight && PinTop && PinBottom。4 辺すべて固定時に
X・Y・Z・Zoom パラメータを非表示にします。
Left・Right・Top・Bottom(余白)
[AnimationSlider] 属性を持つ Animation プロパティです。初期値 0、範囲 ±VeryLargeValue、単位 px。
各プロパティは対応する Pin が有効な場合のみ [LeftMarginVisible]・[RightMarginVisible]・
[TopMarginVisible]・[BottomMarginVisible] 属性によって表示されます。
固定した端からのオフセット量を指定します。正の値で外側方向、負の値で内側方向に余白を設けます。
固定していない端については X・Y・Zoom で指定した位置・サイズが基準として使用されます。
ShapeType(種類)
[ShapeTypeComboBox] 属性を持つ Type プロパティです。
既定値は PluginLoader.GetPrimaryPluginType<IShapePlugin>() が返す型です。
BeginEdit で oldShapeType に現在値を保持し、EndEditAsync のタイミングで
ShapeType が変更されていた場合または ShapeParameter が null の場合に
ShapeFactory.GetPlugin(ShapeType).CreateShapeParameter(ShapeParameter?.GetSharedData()) で
図形パラメータを再生成します。前の ShapeParameter の GetSharedData() を引き継ぐため、
対応する共有項目は可能な範囲で維持されます。
ShapeParameter(図形パラメータ)
[Display(AutoGenerateField = true)] 属性を持つ IShapeParameter プロパティです。
既定値は new RectangleShapeParameter(null) です。
選択した図形プラグインに応じたパラメータが YMM4 の UI により自動生成されます。
GetAnimatables() の返却リストに含まれるため、図形パラメータ内のアニメーション値も
キーフレームアニメーションの対象となります。
3. 表示方法と合成モード
ShapeDisplayMode 列挙型の各値と Composite エフェクトへの設定対応は以下のとおりです。
| 値 | CompositeMode |
入力 0(背景) | 入力 1(前景) |
|---|---|---|---|
Replace(完全置換) |
SourceOver |
emptyImage(完全透明) |
図形変換後出力 |
InsideArea(領域内に表示) |
SourceIn |
元アイテム入力 | 図形変換後出力 |
AboveArea(領域上に重ねて表示) |
SourceAtop |
元アイテム入力 | 図形変換後出力 |
Overlay(そのまま重ねて表示)IsBack = false |
SourceOver |
元アイテム入力 | 図形変換後出力 |
Overlay(そのまま重ねて表示)IsBack = true |
SourceOver |
図形変換後出力 | 元アイテム入力 |
input(元アイテム)が null の場合は emptyImage を代替として使用します。
shapeSource が未構築の場合も同様に emptyImage を代替として使用します。
emptyImage は Flood(色 (0, 0, 0, 0))を Crop(矩形 (0, 0, 1, 1))で
切り抜いた完全透明の 1×1 画像として構築されます。
4. エフェクトチェーンの構築
ShapePasteEffectProcessor は IVideoEffectProcessor を実装します。
コンストラクタでは以下のエフェクトを生成し、すべて disposer に登録します。
new ColorMatrix(devices.DeviceContext)でColorMatrixエフェクト(shapeOpacity)を生成します。new AffineTransform2D(devices.DeviceContext)でAffineTransform2Dエフェクト(shapeTransform)を生成します。
補間モードはAffineTransform2DInterpolationMode.Linearに設定されます。shapeTransform.Outputを取得してshapeTransformOutputとして保持します。new Composite(devices.DeviceContext)でCompositeエフェクトを生成します。composite.Outputを取得してOutputプロパティとして公開します。emptyImage(Flood→Cropの透明 1×1 画像)を構築します。
エフェクトチェーンの接続はUpdateShapeSourceおよびConfigureComposite内で
フレームごとに動的に設定されます。
5. 図形ソースの更新とサイズ追従処理
UpdateShapeSource の処理フローは以下のとおりです。
item.ShapeParameterがnullの場合は処理をスキップします。DisposeShapeSourceで既存のshapeSourceを破棄します。ShapeParameter.GetSharedData()→ShapeFactory.GetPlugin(ShapeType).CreateShapeParameter(sharedData)
でliveParamを生成し、liveParam.CreateShapeSource(devices)でshapeSourceを構築します。shapeSource.Update(effectDescription)で初回更新を行います。IsSizeTrackingEnabledがtrueかつliveParamがIResizableShapeParameterを実装し
かつinputが非nullの場合、以下のサイズ追従処理を行います。GetImageLocalBoundsで図形および元アイテムの境界矩形を取得します。- 固定していない端は X・Y・Zoom・Z の値から算出した基準位置を使用します。
- 固定している端は
±inputSize / 2.0 ± marginで目標位置を算出します。 IResizableShapeParameter.Resize(scaleX, scaleY)で図形を直接リサイズしたのち
shapeSource.Update(effectDescription)で再更新します。offsetX/offsetYには固定端から算出した中心座標を設定します。finalScaleX/finalScaleYは1f固定となります。- 元アイテムの境界幅・高さが有限値でない場合はスケール計算にフォールバックします。
InvertXがtrueの場合finalScaleX *= -1f、InvertYがtrueの場合finalScaleY *= -1fを適用します。UpdateShapeTransformを呼び出して変換を確定します。shapeOpacity.SetInput(0, shapeSource.Output, true)で図形出力をColorMatrixへ接続し、
shapeTransform.SetInput(0, shapeOpacity.Output, true)でAffineTransform2Dへ接続します。
6. 変形の適用
UpdateShapeTransform の処理フローは以下のとおりです。
shapeSourceがnullの場合は処理をスキップします。Opacityの値からColorMatrixのM44(アルファ成分)を設定します。
他の対角成分(M11・M22・M33)は1f固定、その他の成分は0f固定です。Rotationの現在値をvalue * Math.PI / 180.0でラジアンに変換します。- 以下の順で変換行列を合成して
shapeTransform.TransformMatrixに設定します。Matrix3x2.CreateScale(scaleX, scaleY)Matrix3x2.CreateRotation(rotationRad)Matrix3x2.CreateTranslation(offsetX, offsetY)
7. 入力管理とリソース解放
SetInput は input フィールドを更新します。
ClearInput は input を null にリセットしたのち DisposeShapeSource を呼び出します。
DisposeShapeSource では以下の順で図形ソースを解放します。
-
shapeSourceがnullの場合は処理をスキップします。 -
shapeOpacity.SetInput(0, null, true)でColorMatrixの入力参照を解除します。 -
shapeTransform.SetInput(0, null, true)でAffineTransform2Dの入力参照を解除します。 -
shapeSource.Dispose()で図形ソースを解放し、shapeSourceをnullにします。
Disposeでは以下の順でリソースを解放します。 -
composite.SetInput(0, null, true)およびcomposite.SetInput(1, null, true)で
Compositeの入力参照を解除します。 -
DisposeShapeSource()で図形ソースを解放します。 -
disposer.Dispose()で登録済みのすべてのリソースを一括解放します。
8. プロパティ可視性制御
各プロパティの表示・非表示は ICustomVisibilityAttribute2 を実装したカスタム属性で制御されます。
すべての属性は PropertyVisibilityAttributeBase を基底クラスとして持ちます。
GetBinding は SourcePropertyName を Path とする OneWay バインディングを返し、
VisibilityConverter(predicate を IsVisible に委譲)で Visibility 値に変換します。
| 属性 | 監視プロパティ | 表示条件 |
|---|---|---|
DrawPositionVisibleAttribute |
IsFullyPinned |
false のとき表示 |
IsBackVisibleAttribute |
DisplayMode |
ShapeDisplayMode.Overlay のとき表示 |
LeftMarginVisibleAttribute |
PinLeft |
true のとき表示 |
RightMarginVisibleAttribute |
PinRight |
true のとき表示 |
TopMarginVisibleAttribute |
PinTop |
true のとき表示 |
BottomMarginVisibleAttribute |
PinBottom |
true のとき表示 |
9. 多言語対応
Texts.csv(8 言語 × 56 キー)を YukkuriMovieMaker.Generator の [AutoGenLocalizer] 属性が
処理し、各ロケールのリソースを自動生成します。対応言語は
日本語 / 英語 / 中国語簡体字 / 中国語繁体字 / 韓国語 / スペイン語 / アラビア語 / インドネシア語です。
| キーグループ | 用途 |
|---|---|
ShapePasteEffectDefaultName |
エフェクト名・Label プロパティ・[VideoEffect] 属性の表示名 |
ShapePasteEffectGroupName_* |
パラメータのグループ名(Draw・Display・SizeTracking・Margin・Shape) |
ShapePasteEffectDisplayName_* |
各パラメータの表示名(19 項目) |
ShapePasteEffectDiscription_* |
各パラメータの説明文(19 項目) |
ShapePasteEffectUnit_* |
アニメーションスライダーの単位(Pixels・Percent・Degrees) |
ShapePasteEffectEnum_DisplayMode_* |
ShapeDisplayMode 列挙値の表示名・説明文(4 値 × 2) |