[C#][WPF][WinForms]RichTextBoxで画像(JPEG)を挿入する。

WPF/WinFormsで提供されるRichTextBoxを簡単にWORDのような機能を提供してくれますが、画像挿入やテーブル追加の機能がありません。 

これらの機能を実現するには、RTFの仕様に従い文字列でデータを追加する必要があります。

コードは以下のようになります。

private const string RTF_HEADER = @"{\rtf1\ansi\ansicpg1252\deff0\deflang1033";
private const string RTF_DOCUMENT_POST = @"\cf0\fs17}";

public void InsertImage(RichTextBox rtfbox, Image _image) {
	StringBuilder _rtf = new StringBuilder();

	// Append the RTF header
	_rtf.Append(RTF_HEADER);

	// Create the Windows Metafile and append its bytes in HEX format
	_rtf.Append(InsertJpgImage(_image));

	//Close RTF header
	_rtf.Append(RTF_IMAGE_POST);

	rtfbox.SelectedRtf = _rtf.ToString();
}

private static string GetWidthAndHeight(Image image, float dpiX, float dpiY){
	float width = (float)image.Width / dpiX;
	float height = (float)image.Height / dpiY;

	int picw = (int)(width * 2540);
	int pich = (int)(height * 2540);

	int picwgoal = (int)(width * 1440);
	int pichgoal = (int)(height * 1440);

	return "\\picw" + picw + "\\pich" + pich + "\\picwgoal" + picwgoal + "\\pichgoal" + pichgoal;
}

public static string InsertJpgImage(Image image){
	byte[] buffer;

	using (var stream = new MemoryStream())
	{
		image.Save(stream, ImageFormat.Jpeg);
		buffer = stream.ToArray();
	}

	string hex = BitConverter.ToString(buffer, 0).Replace("-", string.Empty);

	string widthAndHeight = GetWidthAndHeight(image, image.HorizontalResolution, image.VerticalResolution);

	return "{\\pict\\jpegblip" + widthAndHeight + " " + hex + "}";
}

また、RTFの仕様では、画像は以下の書式となっています。


RTFファイルには、他のアプリケーションで作成された画像を含めることができます。 これらの画像は、16進数(デフォルト)またはバイナリ形式にすることができます。 写真は目的地であり、\ pictコントロールワードで始まります。 次の例で説明するように、\ pictキーワードの前に\ * \ shppict宛先制御キーワードがあります。 画像の宛先の構文は次のとおりです。

タグ 内容
<pict> '{' \pict (<brdr>? & <shading>? & <picttype> & <pictsize> & <metafileinfo>?) <data> '}'
<picttype> | \emfblip | \pngblip | \jpegblip | \macpict | \pmmetafile | \wmetafile | \dibitmap <bitmapinfo> | \wbitmap <bitmapinfo>
<bitmapinfo> \wbmbitspixel & \wbmplanes & \wbmwidthbytes
<pictsize> (\picw & \pich) \picwgoal? & \pichgoal? \picscalex? & \picscaley? & \picscaled? & \piccropt? & \piccropb? & \piccropr? & \piccropl?
<metafileinfo> \picbmp & \picbpp
<data> (\bin #BDATA) | #SDATA

これらの制御ワードについて、次の表で説明します。 この表の一部の測定値はtwip単位です。 twipはポイントの20分の1です。

タグ 内容
\emfblip 画像のソースはEMF(拡張メタファイル)です。
\pngblip
画像のソースはPNGです。
\jpegblip
画像のソースはJPEGです。
\shppict
Word97-2000の画像を指定します。 これは宛先制御ワードです。
\nonshppict
Word97-2000が入力時に読み取らない{\ pict宛先を書き込んだことを指定します。 このキーワードは、他のリーダーとの互換性のためです。
\macpict
画像のソースはQuickDrawです。
\pmmetafileN
画像のソースはOS / 2メタファイルです。 N引数は、メタファイルの種類を識別します。 N値は、以下の\ pmmetafileテーブルで説明されています。
\wmetafileN
画像のソースはWindowsメタファイルです。 N引数は、メタファイルタイプを識別します(デフォルトは1です)。
\dibitmapN
画像のソースは、Windowsデバイスに依存しないビットマップです。 N引数は、ビットマップタイプを識別します(0に等しい必要があります)。

Windowsデバイスに依存しないビットマップからRTFに含まれる情報は、BITMAPINFO構造体とそれに続く実際のピクセルデータの連結です。
\wbitmapN
画像のソースは、Windowsデバイスに依存するビットマップです。 N引数は、ビットマップタイプを識別します(0に等しい必要があります)。

Windowsデバイス依存ビットマップからRTFに含まれる情報は、GetBitmapBits関数の結果です。
 
 画像サイズ、スケーリング、トリミング
タグ 内容
\picwN 画像がWindowsメタファイルの場合はxExtフィールド。 画像がビットマップの場合、またはQuickDrawからの画像の幅(ピクセル単位)。 N引数は長整数です。
\pichN 画像がWindowsメタファイルの場合はyExtフィールド。 画像がビットマップの場合、またはQuickDrawからの画像の高さ(ピクセル単位)。 N引数は長整数です。
\picwgoalN 画像の希望の幅(twip単位)。 N引数は長整数です。
\pichgoalN 画像の希望の高さ(twip単位)。 N引数は長整数です。
\picscalexN 水平スケーリング値。 N引数は、パーセンテージを表す値です(デフォルトは100です)。
\picscaleyN 垂直スケーリング値。 N引数は、パーセンテージを表す値です(デフォルトは100です)。
\picscaled 指定されたフレーム内に収まるように画像を拡大縮小します。 \ macpict画像でのみ使用されます。
\picprop 形状プロパティがインライン画像に適用されることを示します。 これは宛先制御ワードです。
\defshp インライン画像がワードアート形状であることを示します。
\piccroptN twipsでの最高のトリミング値。 正の値は画像の中央に向かってトリミングされます。 負の値は中央から離れてトリミングされ、画像の周囲にスペースの境界線が追加されます(デフォルトは0です)。
\piccropbN twipsでの下部のトリミング値。 正の値は画像の中央に向かってトリミングされます。 負の値は中央から離れてトリミングされ、画像の周囲にスペースの境界線が追加されます(デフォルトは0です)。
\piccroplN 左のトリミング値をtwipで表示します。 正の値は画像の中央に向かってトリミングされます。 負の値は中央から離れてトリミングされ、画像の周囲にスペースの境界線が追加されます(デフォルトは0です)。
\piccroprN ツイップでの正しいトリミング値。 正の値は画像の中央に向かってトリミングされます。 負の値は中央から離れてトリミングされ、画像の周囲にスペースの境界線が追加されます(デフォルトは0です)。

0 件のコメント :

コメントを投稿