29

我看到的大多数示例都说将其放在剪贴板上并使用粘贴,但这似乎不是很好,因为它会覆盖剪贴板。

我确实看到了一种使用 pinvoke 手动将图像放入 RTF 以将图像转换为 wmf 的方法。这是最好的方法吗?我还能做更直接的事情吗?

4

10 回答 10

57

最直接的方法是修改 RTF 代码以自己插入图片。

在 RTF 中,图片是这样定义的:

'{' \pict (brdr?& shading?& picttype & pictsize & metafileinfo?) data '}' 问号表示控制字是可选的。“数据”只是十六进制格式的文件内容。如果要使用二进制,请使用 \bin 控制字。

例如:

{\pict\pngblip\picw10449\pich3280\picwgoal5924\pichgoal1860 hex data}
{\pict\pngblip\picw10449\pich3280\picwgoal5924\pichgoal1860\bin binary data}

\pict = 开始一个图片组,\pngblip = png 图片 \picwX = 图片宽度(X 为像素值) \pichX = 图片高度 \picwgoalX = 图片所需宽度,单位为缇

因此,要插入图片,您只需打开图片,将数据转换为十六进制,将这些数据加载到字符串中并在其周围添加 RTF 代码即可定义 RTF 图片。现在,您有一个包含图片数据的自包含字符串,您可以将其插入到文档的 RTF 代码中。不要忘记结束的“}”

接下来,您从 RichTextBox (rtbBox.Rtf) 中获取 RTF 代码,将图片插入到适当的位置,并设置 rtbBox.Rtf 的代码

您可能遇到的一个问题是 .NET RTB 对 RTF 标准没有很好的支持。

我刚刚制作了一个小应用程序*,它允许您快速测试 RTB 中的一些 RTF 代码并查看它如何处理它。您可以在此处下载: RTB 测试器( http://your-translations.com/toys )。

您可以将一些 RTF 内容(例如来自 Word)粘贴到左侧 RTF 框中,然后单击“显示 RTF 代码”以在右侧 RTF 框中显示 RTF 代码,或者您可以将 RTF 代码粘贴到右侧 RTB 中并单击在“应用 RTF 代码”上查看左侧的结果。

当然你也可以随意编辑代码,方便测试RichTextBox是否支持你需要的命令,或者学习如何使用RTF控制字。

您可以在线下载 RTF 的完整规范。


NB这只是我在5分钟内拍打的小东西,所以我没有实现文件打开或保存,拖放或其他文明的东西。

于 2009-02-20T05:16:16.690 回答
13

我使用以下代码首先从剪贴板获取数据,将其保存在内存中,将图像设置在剪贴板中,将其粘贴到富文本框中,最后恢复剪贴板中的数据。

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    OpenFileDialog1.Filter = "All files |*.*"
    OpenFileDialog1.Multiselect = True
    Dim orgdata = Clipboard.GetDataObject

    If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
        For Each fname As String In OpenFileDialog1.FileNames
            Dim img As Image = Image.FromFile(fname)
            Clipboard.SetImage(img)
            RichTextBox1.Paste()

        Next
    End If
    Clipboard.SetDataObject(orgdata)
End Sub

OpenFileDailog1、RichTextBox1 和 Button1 分别是打开文件对话框、富文本框和按钮控件。

于 2009-12-26T15:05:14.593 回答
6
private void toolStripButton1_Click(object sender, EventArgs e)
    {
        FileDialog fDialog = new OpenFileDialog();
        fDialog.CheckFileExists = true;
        fDialog.CheckPathExists = true;
        fDialog.RestoreDirectory = true;
        fDialog.Title = "Choose file to import";
        if (fDialog.ShowDialog() == DialogResult.OK)
        {
            string lstrFile = fDialog.FileName;
            Bitmap myBitmap = new Bitmap(lstrFile);
            // Copy the bitmap to the clipboard.
            Clipboard.SetDataObject(myBitmap);
            DataFormats.Format format = DataFormats.GetFormat(DataFormats.Bitmap);
            // After verifying that the data can be pasted, paste
            if(top==true && this.rtTop.CanPaste(format))
            {
                rtTop.Paste(format);
            }
            if (btmLeft == true && this.rtBottomLeft.CanPaste(format))
            {
                rtBottomLeft.Paste(format);
            }
            if (btmCenter == true && this.rtBottomCenter.CanPaste(format))
            {
                rtBottomCenter.Paste(format);
            }
            if (btmRight == true && this.rtBottomRight.CanPaste(format))
            {
                rtBottomRight.Paste(format);
            }
        }
    }
于 2009-04-21T09:19:09.960 回答
5

这是我破解富文本控件的方法:

在写字板或 MS-WORD 中插入所需的图像。将文件另存为“rtf”。在记事本中打开 rtf 文件以查看原始 rtf 代码。将所需的标签和内容复制到富文本框的“rtf”属性(附加到现有文本)。

涉及一些试验和错误,但有效。

在 C# 中,我使用带有必要 rtf 代码的占位符 StringBuilder 对象。然后我只是附加图像路径。

这是一种无需学习 RTF 语法的解决方法。

于 2009-02-20T05:28:52.073 回答
1

我在新线程中发布的我自己的版本,显然我应该在这里搜索并发布它。无论如何,再次使用剪贴板,非常容易。

private void button1_Click(object sender, EventArgs e)
    {
        openFileDialog1.Filter = "Images |*.bmp;*.jpg;*.png;*.gif;*.ico";
        openFileDialog1.Multiselect = false;
        openFileDialog1.FileName = "";
        DialogResult result = openFileDialog1.ShowDialog();
        if (result == DialogResult.OK)
        {
            Image img = Image.FromFile(openFileDialog1.FileName);
            Clipboard.SetImage(img);
            richTextBox1.Paste();
            richTextBox1.Focus();
        }
        else
        {
            richTextBox1.Focus();
        }

    }
}
于 2017-08-24T21:04:39.613 回答
0

如果您使用 C++,则可以通过 OLE 来实现。更具体地说,如果您在 Google 上搜索 ImageDataObject,它将显示 C++ 代码如何将 HBITMAP 插入 RTF 控件。一个链接在这里

现在,我不知道这如何转化为 .Net 代码。我目前没有时间仔细研究细节。

于 2009-02-25T19:09:40.690 回答
0

我也在为同样的任务寻找一些东西并找到了这个->

http://sourceforge.net/projects/netrtfwriter/

您可以生成所需的任何类型的 RTF 文本,然后根据需要使用它。结构很好的示例,它将自动感知正在使用的图像类型(jpg/jpeg/png 等)并适用于我一直在使用的图像文件。如果您赶时间,那么这是一个很棒的 RTF 生成器!

于 2012-09-13T15:43:04.037 回答
0

我所做的只是在 c# 中制作了一个小的图片框控件,并确保它隐藏在另一个足够大的对象后面以隐藏它。然后我做了一个按钮来插入图片,它用图片加载了图片框,然后把它放在了richTextBox中,然后它清除了图片框控件。

这是代码。

 private void InsertPicture_Click(object sender, EventArgs e)
    {

                    {
            if (openFileDialog4.ShowDialog() == DialogResult.OK)
            {
                // Show the Open File dialog. If the user clicks OK, load the 
                // picture that the user chose.   
                pictureBox2.Load(openFileDialog4.FileName);
                Clipboard.SetImage(pictureBox2.Image);
                pictureBox2.Image = null;
                this.richTextBox1.Paste();

            }
    }
}
于 2016-07-10T23:49:07.430 回答
0

插入代码以使用剪贴板执行此操作后,输入Clipboard.Clear();. 它运作良好,它不会清除所有内容,仅清除最后添加到剪贴板的项目。

完整代码:

private void addPictureToRTB()
{
    using (OpenFileDialog ofd = new OpenFileDialog() { Filter = "Pictures|*.png" })
    {
         if (ofd.ShowDialog() == DialogResult.OK)
         {
               ClipBoard.SetImage(Image.FromFile(ofd.FileName));
               richTextBox.Paste();
               Clipboard.Clear();
         }
    }
}

然后在需要的地方引用这个函数。

于 2021-12-20T01:03:02.247 回答
-1

几个小时寻找解决方案以在不损失质量的情况下插入图像并用透明图像/ png 修复灰色背景

                // assuming the image is in your Resources
                var img = Resources.ImageWithTransparentBckgrnd;
                var g = Graphics.FromImage(img);
                using (var ms = new MemoryStream())
                {
                    img.Save(ms, ImageFormat.Png);
                    IntPtr ipHdc = g.GetHdc();
                    Metafile mf = new Metafile(ms, ipHdc);
                    g = Graphics.FromImage(mf);
                    g.FillEllipse(Brushes.White, 0, 0, 16, 16); // size you want to fill in
                    g.Dispose();
                    mf.Save(ms, ImageFormat.Png);
                    IDataObject dataObject = new DataObject();
                    dataObject.SetData("PNG", false, ms);
                    Clipboard.SetDataObject(dataObject, false);
                    richTextBox1.Paste();
                    SendKeys.Send("{RIGHT}");
                    richTextBox1.Focus();
                }
于 2018-10-08T13:55:28.427 回答