Resolved Insert Image Into RichtextBox

aaaron

Well-known member
Joined
Jan 23, 2011
Messages
216
Programming Experience
10+
A long time ago I wrote code to insert an image into a RichTextBox.

Haven't used it for years until I tried recently and got an error mesage.

Downloaded new and simpler code to do it. And got the same error as my code.

Looks like the RichTextBox has changed.

Here is one code I used:

VB.NET:
Dim q As Drawing.Image = GetImageResource(resourceName)
Dim bmp As New Bitmap(q)
Dim ms As New MemoryStream()
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp)
Dim bmpBytes As Byte() = ms.GetBuffer()
Dim str As String = Encoding.ASCII.GetString(bmpBytes)
RichTextBox1.SelectedRtf = "{\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fnil\fcharset0 Microsoft Sans Serif;}}\viewkind4\uc1\pard\f0\fs20 " & str & "\par}"

Here is the error message:

Untitled.png
 
Last edited by a moderator:
Solution
Testing things out and looking at the generated rtf is good advice, also research the RTF specification.
Here's some more help with a short sample code:
VB.NET:
Dim twipsPerPixel = 1440 \ DeviceDpi
Dim imgfile = "sample.png"
Dim bytes = File.ReadAllBytes(imgfile)
Using mem = New MemoryStream(bytes), img = Image.FromStream(mem)
    Dim hex = BitConverter.ToString(bytes).Replace("-", "")
    Dim w = img.Width * twipsPerPixel
    Dim h = img.Height * twipsPerPixel
    Dim rtf = $"{{\rtf1 {{\pict\pngblip\picw{w}\pich{h} {hex}}}}}"
    'sample rtf string: {\rtf1 {\pict\pngblip\picw1500\pich1500 0123456789ABCDEF}}
    SampleRichTextBox.SelectedRtf = rtf
End Using
Key elements is that measurements is mostly in twips, image data is hex (default)...
Let's start with the issues with your post.
  • Please post in the most specific forum you can for the topic of the thread. Your issue is with a Windows Forms control so, clearly, the Windows Forms forum is a more appropriate place for this thread than the VB.NET General forum. I have moved the thread.
  • You messed up the formatting of your code. We all make mistakes but, once you submitted your post, you could see that it wasn't formatted properly but you didn't fix it. I have fixed it for you. Please ensure that all code snippets are formatted appropriate for readability. There is a Preview button above your post. You should use it to ensure that everything looks correct before submitting.
  • Never post just a screenshot of text. Error messages are text and should be posted as text, formatted appropriately. If a screenshot can add value then you can provide one as well as the text but that should never be the only version of that text. We can't copy text from a picture. In this case, there's no value added anyway because you can highlight one or more lines in your code if you format it properly.
 
As for the problem, here's how I would test it. Create the simplest image you can, e.g. 1x1 black pixel. Create a RixhTextBox with very simple text and copy the RTF. Paste your image into it using the keyboard, then copy the RTF again and compare the two. Do this again with a few more simple images. You should now be able to see what RTF gets inserted and what part corresponds specifically to the image. You can then determine how to create that part of the text specifically from your Image object. I doubt that it's actually straight ASCII text, but I haven't actually tested for myself.
 
I just tested with an empty RichTextBox and, as I suspected, you are actually trying to insert an entire RTF document, rather than just the RTF snippet for an image. The Rtf property of an empty control looks like this:
"{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang2057{\fonttbl{\f0\fnil\fcharset0 Microsoft Sans Serif;}}" & vbCrLf & "{\*\generator Riched20 10.0.22621}\viewkind4\uc1 " & vbCrLf & "\pard\f0\fs17\par" & vbCrLf & "}" & vbCrLf
It may well be that if you were to set the Rtf property, rather than the SelectedRtf property, then your code would work. You should read the relevant documentation to learn the difference between those two properties. It's not hard to see though, given that it's basically the same as the difference between the Text and SelectedText properties of a TextBox. One is the entire content and the other is just the part that is selected in the UI.
 
Try this. Add a TextBox and a Button to a form and add this code:
VB.NET:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    TextBox1.SelectedText = " New Text "
End Sub
Now enter some text in the TextBox, place the caret somewhere and click the Button. You'll see that specified text gets inserted into the existing text at the location of the caret. If you actually select some text and click the Button, the selected text will be replaced. That's basically what you need to do with the SelectedRtf of your RichTextBox. You don't want an entire RTF document. You want to specify just the RTF markup required for the image so it can be inserted into what's already there.
 
Testing things out and looking at the generated rtf is good advice, also research the RTF specification.
Here's some more help with a short sample code:
VB.NET:
Dim twipsPerPixel = 1440 \ DeviceDpi
Dim imgfile = "sample.png"
Dim bytes = File.ReadAllBytes(imgfile)
Using mem = New MemoryStream(bytes), img = Image.FromStream(mem)
    Dim hex = BitConverter.ToString(bytes).Replace("-", "")
    Dim w = img.Width * twipsPerPixel
    Dim h = img.Height * twipsPerPixel
    Dim rtf = $"{{\rtf1 {{\pict\pngblip\picw{w}\pich{h} {hex}}}}}"
    'sample rtf string: {\rtf1 {\pict\pngblip\picw1500\pich1500 0123456789ABCDEF}}
    SampleRichTextBox.SelectedRtf = rtf
End Using
Key elements is that measurements is mostly in twips, image data is hex (default) or binary (which can't be set through the Rtf/SelectedRtf string properties), and you do need the {\rtf1 } document wrapper when setting SelectedRtf.

Should mention it is also possible to put an image in clipboard and use the Paste method to insert it.
 
Solution
JohnH,


Thanks. By copying codes from a working RTF file wth an image I included much that was unnecessary.

I should have checked more!

I know you know but if someone else is reading this, JohnH's code works if you change SelectedRtf to Rtf.

That is, to insert at the selection requires that the text be formated as if it was an entire document. (rtf1 is the header of an RTF file).
 
The sample code setting .SelectedRtf works fine for me. Without {\rtf1 } wrapper I get "File format is not valid".

It would also work for setting .Rtf since the string is itself a minimal rtf document.
 
Back
Top