🙆
Windows限定でSVGファイルを画像化する
SVGファイルを画像化したい場合、SharpVectorsなどのライブラリーがありますが、Windowsプラットフォーム限定であればライブラリー無しで一応は実現できます。
SVGのレンダリング
古き良き(?)WbBrowserコントロールを使います。
最新の規格に追随することは望めませんが、基本的なレンダリングできると思われます。
WindowsでSVGを表示するアプリケーションの先行事例(ブラウザー系を除く)としてはmicrosoft/PowerToysがあります。
SvgThumbnailProvider.cs
を参考にすれば大体実装できます。
大まかな方式
-
WebBrowserSiteBase
を継承したクラスで制限をかける。 -
WebBrowser
コントロールを(フォームに追加せずに)作成する。 -
WebBrowser.DocumentText
でSVGファイルを読み込ませる。 - ロードが終わるまで
Application.DoEvents();
する。(力業!) -
WebBrowser.DrawToBitmap()
でビットマップに描画する。
WebBrowserのセキュリティ
SVGファイルにスクリプトを書けますし、外部リソースへのリンクも出来ます。
インプロセスのWebBrowserコントロールでそれが出来ては困りますが、
WebBrowserSiteBase
を継承したクラスで制限をかけているようです。
/// <summary>
/// Extend the WebBrowserSite with IDispatch implementation to handle the DISPID_AMBIENT_DLCONTROL.
/// More details: https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa770041(v=vs.85)?redirectedfrom=MSDN#controlling-download-and-execution.
/// </summary>
protected class WebBrowserSiteExt : WebBrowserSite, IReflect
{
// Dispid of DISPID_AMBIENT_DLCONTROL is defined in MsHtmdid.h header file in distributed Windows Sdk component.
private const string DISPIDAMBIENTDLCONTROL = "[DISPID=-5512]";
...
public object? InvokeMember(string name, BindingFlags invokeAttr, Binder? binder, object? target, object?[]? args, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParameters)
{
if (name?.Equals(DISPIDAMBIENTDLCONTROL, StringComparison.CurrentCulture) == true)
{
// Using InvariantCulture since this is used for web browser configurations
return Convert.ToInt32(
WebBrowserDownloadControlFlags.DLIMAGES |
WebBrowserDownloadControlFlags.PRAGMA_NO_CACHE |
WebBrowserDownloadControlFlags.FORCEOFFLINE |
WebBrowserDownloadControlFlags.NO_CLIENTPULL |
WebBrowserDownloadControlFlags.NO_SCRIPTS |
WebBrowserDownloadControlFlags.NO_JAVA |
WebBrowserDownloadControlFlags.NO_FRAMEDOWNLOAD |
WebBrowserDownloadControlFlags.NOFRAMES |
WebBrowserDownloadControlFlags.NO_DLACTIVEXCTLS |
WebBrowserDownloadControlFlags.NO_RUNACTIVEXCTLS |
WebBrowserDownloadControlFlags.NO_BEHAVIORS |
WebBrowserDownloadControlFlags.SILENT, CultureInfo.InvariantCulture);
}
この他にも、スレッド/プロセス単位で制限をかけることが出来ます。
Introduction to Feature Controls (Windows) | Microsoft Docs
手元のWindows 10 21H1では、下記の様な設定になっておりほぼ問題が無い状態でしたが、使用するユーザーの設定により緩められている可能性があるので、念のためアプリケーション側で上書きしておくで、安心することが出来ます。
CoInternetIsFeatureEnabled で取得した結果
FEATURE_OBJECT_CACHING = 0
FEATURE_ZONE_ELEVATION = 1
FEATURE_MIME_HANDLING = 1
FEATURE_MIME_SNIFFING = 1
FEATURE_WINDOW_RESTRICTIONS = 1
FEATURE_WEBOC_POPUPMANAGEMENT = 1
FEATURE_BEHAVIORS = 0
FEATURE_DISABLE_MK_PROTOCOL = 0
FEATURE_LOCALMACHINE_LOCKDOWN = 1
FEATURE_SECURITYBAND = 1
FEATURE_RESTRICT_ACTIVEXINSTALL = 1
FEATURE_VALIDATE_NAVIGATE_URL = 1
FEATURE_RESTRICT_FILEDOWNLOAD = 1
FEATURE_ADDON_MANAGEMENT = 1
FEATURE_PROTOCOL_LOCKDOWN = 1
FEATURE_HTTP_USERNAME_PASSWORD_DISABLE = 1
FEATURE_SAFE_BINDTOOBJECT = 1
FEATURE_UNC_SAVEDFILECHECK = 1
FEATURE_GET_URL_DOM_FILEPATH_UNENCODED = 0
FEATURE_TABBED_BROWSING = 1
FEATURE_SSLUX = 1
FEATURE_DISABLE_NAVIGATION_SOUNDS = 1
FEATURE_DISABLE_LEGACY_COMPRESSION = 0
FEATURE_FORCE_ADDR_AND_STATUS = 1
FEATURE_XMLHTTP = 0
FEATURE_DISABLE_TELNET_PROTOCOL = 1
FEATURE_FEEDS = 1
FEATURE_BLOCK_INPUT_PROMPTS = 1
制限をかける場合は、P/InvokeでCoInternetSetFeatureEnabled
関数を呼び出します。
サンプルアプリケーション
必要な処理をまとめたサンプルを下記に置いておきました。
Discussion
貴重な情報ありがとうございます。
背景が透過するようなSVGの場合、PNGに透過情報を引き継ぐような対応は難しいですか?