it-roy-ru.com

Как я могу вставить изображение в RichTextBox?

Большинство примеров, которые я вижу, говорят о том, чтобы поместить их в буфер обмена и использовать вставку, но это не очень хорошо, потому что перезаписывает буфер обмена.

Я видел один метод который вручную помещал изображение в RTF, используя pinvoke для преобразования изображения в wmf. Это лучший способ? Есть ли что-нибудь более простое, что я могу сделать?

25
Daniel LeCheminant

Самый простой способ - изменить код RTF, чтобы вставить картинку самостоятельно. 

В RTF картинка определяется следующим образом:

'{'\pict (brdr? & shading? & picttype & pictsize & metafileinfo?) data '}' Знак вопроса означает, что управляющее слово необязательно. ". data" - это просто содержимое файла в шестнадцатеричный формат. Если вы хотите использовать двоичный файл, используйте слово\bin control Word. 

Например:

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

\ pict = запускает группу изображений, \pngblip = png picture \picwX = ширина изображения (X - значение пикселя) \pichX = высота изображения \picwgoalX = требуемый ширина картинки в твипах

Итак, чтобы вставить изображение, вам просто нужно открыть его, преобразовать данные в шестнадцатеричное, загрузить эти данные в строку и добавить вокруг него коды RTF, чтобы определить изображение RTF. Теперь у вас есть отдельная строка с данными изображения, которую вы можете вставить в код RTF документа. Не забывайте закрывать "}"

Затем вы получаете код RTF из RichTextBox (rtbBox.Rtf), вставляете картинку в нужное место и устанавливаете код rtbBox.Rtf

Одна из проблем, с которой вы можете столкнуться, заключается в том, что .NET RTB не очень хорошо поддерживает стандарт RTF. 

Я только что создал небольшое приложение *, которое позволяет вам быстро протестировать некоторый код RTF внутри RTB и посмотреть, как он обрабатывает его. Вы можете скачать его здесь: RTB tester ( http://your-translations.com/toys ). 

Вы можете вставить некоторое содержимое RTF (например, из Word) в левое поле RTF и нажать «Показать коды RTF», чтобы отобразить коды RTF в справа RTF, или вы можете вставить RTF код в правый RTB и нажать «Применить RTF коды», чтобы увидеть результаты с левой стороны. 

Конечно, вы можете редактировать коды по своему усмотрению, что делает его очень удобным для проверки того, поддерживает ли RichTextBox нужные вам команды или узнать, как использовать управляющие слова RTF. 

Вы можете скачать полную спецификацию для RTF онлайн.


NB Это всего лишь маленькая вещь, которую я собрал за 5 минут, поэтому я не реализовал открытие или сохранение файлов, перетаскивание и другие цивилизованные вещи. 

50
Sylverdrag

Я использую следующий код, чтобы сначала получить данные из буфера обмена, сохранить их в памяти, установить изображение в буфер обмена, вставить его в поле Rich Text Box и, наконец, восстановить данные в буфере обмена.

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 - это диалоговое окно «Открыть файл», «Rich Text Box» и кнопки управления соответственно.

11
Bibek Dahal
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);
            }
        }
    }
6
ashwin

Вот что я делаю, чтобы взломать элемент управления rich text:

Вставьте нужное изображение в WordPad или MS-Word. Сохраните файл как «rtf». Откройте файл RTF в блокноте, чтобы увидеть необработанный код RTF. Скопируйте необходимые теги и прочее в свойство 'rtf' вашего Rich Text Box (добавьте к существующему тексту). 

Есть проб и ошибок, но работает.

В C # я использую объекты-заполнители StringBuilder с необходимым кодом RTF. Затем я просто добавляю путь к изображению.

Это обходной путь для того, чтобы не изучать синтаксис RTF.

4
Sesh

Моя собственная версия, которую я разместил в новой ветке, по-видимому, я должен был найти и опубликовать ее здесь. В любом случае, снова использовать буфер обмена, очень просто.

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

    }
}
1
SandraTinch

Все, что я сделал, это сделал небольшой элемент управления pictureBox в c # и убедился, что он спрятан за другим объектом, достаточно большим, чтобы скрыть его. Затем я сделал кнопку для вставки изображения, и он загрузил 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();

            }
    }
}
0
Larryrl

Если вы были в C++, способ сделать это через OLE. Более конкретно, если вы будете искать в Google объект ImageDataObject, он покажет код на C++, как вставить HBITMAP в элемент управления RTF. Одна ссылка здесь .

Теперь, как это переводится в код .Net, я не знаю. У меня сейчас нет времени прорабатывать детали.

0
Joel Lucsy

Несколько часов поиска решения для вставки изображения без потери качества и исправления серого фона с прозрачным изображением/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();
                }
0
Sourcephy

Я также искал что-то для этой же задачи и нашел это ->

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

Вы можете генерировать любой тип текста RTF, а затем использовать его по своему усмотрению. Очень хорошо структурированный пример, который автоматически определяет используемый тип изображения (jpg/jpeg/png и т.д.) И работает с файлами изображений, которые я использовал. Если вы спешите, то это отличный генератор RTF!

0
jackocurly0074