Как я могу вставить изображение в RichTextBox? - PullRequest
25 голосов
/ 12 февраля 2009

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

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

Ответы [ 9 ]

52 голосов
/ 20 февраля 2009

Самый простой способ - изменить код 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 picture \ picwX = ширина изображения (X - значение в пикселях) \ pichX = высота картинки \ picwgoalX = требуемая ширина изображения в твипах

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

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

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

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

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

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

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


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

11 голосов
/ 26 декабря 2009

Я использую следующий код, чтобы сначала получить данные из буфера обмена, сохранить их в памяти, установить изображение в буфер обмена, вставить его в 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» и кнопки управления соответственно.

6 голосов
/ 21 апреля 2009
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);
            }
        }
    }
4 голосов
/ 20 февраля 2009

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

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

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

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

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

1 голос
/ 25 августа 2017

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

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

    }
}
0 голосов
/ 08 октября 2018

Несколько часов поиска решения для вставки изображения без потери качества и исправления серого фона с прозрачным изображением / 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 голосов
/ 11 июля 2016

Все, что я сделал, это сделал небольшой элемент управления 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 голосов
/ 13 сентября 2012

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

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

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

0 голосов
/ 25 февраля 2009

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

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

...