Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将图像插入RichTextBox?_C#_Vb.net_Image_Richtextbox_Rtf - Fatal编程技术网

C# 如何将图像插入RichTextBox?

C# 如何将图像插入RichTextBox?,c#,vb.net,image,richtextbox,rtf,C#,Vb.net,Image,Richtextbox,Rtf,我看到的大多数示例都说将其放在剪贴板上并使用粘贴,但这似乎不是很好,因为它会覆盖剪贴板 我确实看到了使用pinvoke手动将图像放入RTF,以将图像转换为wmf。这是最好的方式吗?还有更简单的方法吗?最简单的方法是修改RTF代码,自己插入图片 在RTF中,图片的定义如下: “{'\pict(brdr?&shading?&picttype&pictsize&metafileinfo?)数据”}” 问号表示控制字是可选的。 “数据”只是十六进制格式的文件内容。如果要使用二进制,请使用\bin控制字

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


我确实看到了使用pinvoke手动将图像放入RTF,以将图像转换为wmf。这是最好的方式吗?还有更简单的方法吗?

最简单的方法是修改RTF代码,自己插入图片

在RTF中,图片的定义如下:

“{'\pict(brdr?&shading?&picttype&pictsize&metafileinfo?)数据”}” 问号表示控制字是可选的。 “数据”只是十六进制格式的文件内容。如果要使用二进制,请使用\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=图片的所需宽度(以twips为单位)

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

接下来,从RichTextBox(rtbBox.RTF)获取RTF代码,将图片插入正确的位置,并设置rtbBox.RTF代码

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

我刚刚制作了一个小应用程序,它允许您在RTB中快速测试一些RTF代码,并查看它是如何处理的。你可以在这里下载: ().

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

当然,您可以随心所欲地编辑代码,这使得测试RichTextBox是否支持所需的命令或学习如何使用RTF控制字非常方便

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



注意,这只是我在5分钟内完成的一件小事,所以我没有实现文件打开或保存、拖放或其他文明的东西

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

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

有一些尝试和错误,但工作

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


这是一个不需要学习RTF语法的解决方案。

< P>如果你在C++中,那么方法就是通过OLE。更具体地说,如果你搜索谷歌为IVIDEATAObjt对象,它将显示C++代码如何将一个HbM映像插入RTF控件。其中一个环节是


现在,我不知道这是如何翻译成.Net代码的。我目前没有时间处理详细信息。

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

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);
            }
        }
    }
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分别是打开文件对话框、富文本框和按钮控件。

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


您可以生成您想要的任何类型的RTF文本,然后按照您的意愿使用它。这是一个结构非常好的示例,可以自动感知正在使用的图像类型(jpg/jpeg/png等),并且可以处理我一直在使用的图像文件。如果你在赶时间,那么这是一个伟大的RTF发生器

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

这是代码

 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();

            }
    }
}

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

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();
        }

    }
}

几个小时的冲浪解决方案,在不降低质量的情况下插入图像,并使用透明图像/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();
                }

我无法让RTB显示PNG,但至少它显示wmf.1“twip”=1/20点。1点~1.333像素(这取决于屏幕分辨率;目前大多数显示器的本机分辨率为每英寸96像素,因此保持不变),据我所知,RichTextBox(因此RTBTester)不接受\pngblip。它只接受\wmetafile[8]。有关更完整的解释,请参阅此参考:。我知道如果我从RichTextBox保存RTF,那么它可能会有\pngblip。但是,将{\pngblip….}构造复制到RTBTester不会显示图像。老实说,我对这个解决方案持怀疑态度。我的意思是,如果你已经在剪贴板上有了一个图像(在我的例子中),那么把它从剪贴板上拿下来,然后把它放回去应该不会有任何作用。但不知何故,这一招就像做梦一样奏效。非常感谢。如果Richtextbox只读属性设置为true,会发生什么情况?这个剪贴板方法将失败。@Jerry:你误解了。剪贴板开始处的数据不是将图像插入richtext过程的一部分。Bibek的回答功能是“把东西放回你发现它们的方式”逻辑。我认为将剪贴板数据设置回它以前的状态实际上不起作用。我从早上开始就在搜索“如何在Richtextbox中插入图像”,但一切都是虚幻的。在阅读了这个答案后,我在不到180秒内就完成了。