gpt4 book ai didi

c# - 在富文本框中的光标位置插入图像

转载 作者:太空狗 更新时间:2023-10-29 21:17:55 25 4
gpt4 key购买 nike

我知道有很多这样的问题,但我问是因为我无法理解给出的所有答案。我有 RichTextBox,我希望用户能够在当前光标位置插入图像。

我试过使用Clipboard 设置图像,然后将其粘贴到富文本框中。这行得通,但有人告诉我这是不好的做法,因为它会在不通知用户的情况下更改剪贴板中的数据。

这是我试过的

    private bool CheckIfImage(string filename)
{
if (filename.EndsWith(".jpeg")) { return true; }
else if (filename.EndsWith(".jpg")) { return true; }
else if (filename.EndsWith(".png")) { return true; }
else if (filename.EndsWith(".ico")) { return true; }
else if (filename.EndsWith(".gif")) { return true; }
else if (filename.EndsWith(".bmp")) { return true; }
else if (filename.EndsWith(".emp")) { return true; }
else if (filename.EndsWith(".wmf")) { return true; }
else if (filename.EndsWith(".tiff")) { return true; }
else { return false; }
}

private void openFileDialog2_FileOk(object sender, CancelEventArgs e)
{
if (CheckIfImage(openFileDialog2.FileName.ToLower()) == true)
{
Image img = Image.FromFile(openFileDialog2.FileName);
string setData = (String)Clipboard.GetData(DataFormats.Rtf);

Clipboard.SetImage(img);
rtbType.Paste();

Clipboard.SetData(DataFormats.Rtf, setData);
}
else
{
MessageBox.Show("Invalid Image File Selected");
}
}

请问有什么更好的方法吗?

最佳答案

我已经使用发布的解决方案为您准备了一个功能齐全的示例 here利用 RTF 的力量。

正如 Hans Passant 所写:解决方案非常棘手,并且有一些有效的替代方案可以实现。

顺便说一句,这是你的代码(重写):

private bool CheckIfImage(string filename)
{
var valids = new[] {".jpeg", ".jpg", ".png", ".ico", ".gif", ".bmp", ".emp", ".wmf", ".tiff"};
return valids.Contains(System.IO.Path.GetExtension(filename));
}

private void openFileDialog2_FileOk(object sender, CancelEventArgs e)
{
if (CheckIfImage(openFileDialog2.FileName.ToLower()) == true)
embedImage(Image.FromFile(openFileDialog2.FileName));
else
MessageBox.Show("Invalid Image File Selected");
}

这是embedImage方法:

    private void embedImage(Image img)
{
var rtf = new StringBuilder();

// Append the RTF header
rtf.Append(@"{\rtf1\ansi\ansicpg1252\deff0\deflang1033");
// Create the font table using the RichTextBox's current font and append
// it to the RTF string
rtf.Append(GetFontTable(this.Font));
// Create the image control string and append it to the RTF string
rtf.Append(GetImagePrefix(img));
// Create the Windows Metafile and append its bytes in HEX format
rtf.Append(getRtfImage(img));
// Close the RTF image control string
rtf.Append(@"}");
richTextBox1.SelectedRtf = rtf.ToString();
}

这里有所有必要的方法:

    private enum EmfToWmfBitsFlags
{
EmfToWmfBitsFlagsDefault = 0x00000000,
EmfToWmfBitsFlagsEmbedEmf = 0x00000001,
EmfToWmfBitsFlagsIncludePlaceable = 0x00000002,
EmfToWmfBitsFlagsNoXORClip = 0x00000004
};

private struct RtfFontFamilyDef
{
public const string Unknown = @"\fnil";
public const string Roman = @"\froman";
public const string Swiss = @"\fswiss";
public const string Modern = @"\fmodern";
public const string Script = @"\fscript";
public const string Decor = @"\fdecor";
public const string Technical = @"\ftech";
public const string BiDirect = @"\fbidi";
}

[DllImport("gdiplus.dll")]
private static extern uint GdipEmfToWmfBits(IntPtr _hEmf,
uint _bufferSize, byte[] _buffer,
int _mappingMode, EmfToWmfBitsFlags _flags);


private string GetFontTable(Font font)
{
var fontTable = new StringBuilder();
// Append table control string
fontTable.Append(@"{\fonttbl{\f0");
fontTable.Append(@"\");
var rtfFontFamily = new HybridDictionary();
rtfFontFamily.Add(FontFamily.GenericMonospace.Name, RtfFontFamilyDef.Modern);
rtfFontFamily.Add(FontFamily.GenericSansSerif, RtfFontFamilyDef.Swiss);
rtfFontFamily.Add(FontFamily.GenericSerif, RtfFontFamilyDef.Roman);
rtfFontFamily.Add("UNKNOWN", RtfFontFamilyDef.Unknown);

// If the font's family corresponds to an RTF family, append the
// RTF family name, else, append the RTF for unknown font family.
fontTable.Append(rtfFontFamily.Contains(font.FontFamily.Name) ? rtfFontFamily[font.FontFamily.Name] : rtfFontFamily["UNKNOWN"]);
// \fcharset specifies the character set of a font in the font table.
// 0 is for ANSI.
fontTable.Append(@"\fcharset0 ");
// Append the name of the font
fontTable.Append(font.Name);
// Close control string
fontTable.Append(@";}}");
return fontTable.ToString();
}

private string GetImagePrefix(Image _image)
{
float xDpi, yDpi;
var rtf = new StringBuilder();
using (Graphics graphics = CreateGraphics())
{
xDpi = graphics.DpiX;
yDpi = graphics.DpiY;
}
// Calculate the current width of the image in (0.01)mm
var picw = (int)Math.Round((_image.Width / xDpi) * 2540);
// Calculate the current height of the image in (0.01)mm
var pich = (int)Math.Round((_image.Height / yDpi) * 2540);
// Calculate the target width of the image in twips
var picwgoal = (int)Math.Round((_image.Width / xDpi) * 1440);
// Calculate the target height of the image in twips
var pichgoal = (int)Math.Round((_image.Height / yDpi) * 1440);
// Append values to RTF string
rtf.Append(@"{\pict\wmetafile8");
rtf.Append(@"\picw");
rtf.Append(picw);
rtf.Append(@"\pich");
rtf.Append(pich);
rtf.Append(@"\picwgoal");
rtf.Append(picwgoal);
rtf.Append(@"\pichgoal");
rtf.Append(pichgoal);
rtf.Append(" ");

return rtf.ToString();
}

private string getRtfImage(Image image)
{
// Used to store the enhanced metafile
MemoryStream stream = null;
// Used to create the metafile and draw the image
Graphics graphics = null;
// The enhanced metafile
Metafile metaFile = null;
try
{
var rtf = new StringBuilder();
stream = new MemoryStream();
// Get a graphics context from the RichTextBox
using (graphics = CreateGraphics())
{
// Get the device context from the graphics context
IntPtr hdc = graphics.GetHdc();
// Create a new Enhanced Metafile from the device context
metaFile = new Metafile(stream, hdc);
// Release the device context
graphics.ReleaseHdc(hdc);
}

// Get a graphics context from the Enhanced Metafile
using (graphics = Graphics.FromImage(metaFile))
{
// Draw the image on the Enhanced Metafile
graphics.DrawImage(image, new Rectangle(0, 0, image.Width, image.Height));
}

// Get the handle of the Enhanced Metafile
IntPtr hEmf = metaFile.GetHenhmetafile();
// A call to EmfToWmfBits with a null buffer return the size of the
// buffer need to store the WMF bits. Use this to get the buffer
// size.
uint bufferSize = GdipEmfToWmfBits(hEmf, 0, null, 8, EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault);
// Create an array to hold the bits
var buffer = new byte[bufferSize];
// A call to EmfToWmfBits with a valid buffer copies the bits into the
// buffer an returns the number of bits in the WMF.
uint _convertedSize = GdipEmfToWmfBits(hEmf, bufferSize, buffer, 8, EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault);
// Append the bits to the RTF string
foreach (byte t in buffer)
{
rtf.Append(String.Format("{0:X2}", t));
}
return rtf.ToString();
}
finally
{
if (graphics != null)
graphics.Dispose();
if (metaFile != null)
metaFile.Dispose();
if (stream != null)
stream.Close();
}
}

我建议您将其包装到您自己的 UserControl 中。

关于c# - 在富文本框中的光标位置插入图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18017044/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com