gpt4 book ai didi

c# - WPF RichTextBox 插入图片和撤消操作

转载 作者:太空宇宙 更新时间:2023-11-03 12:59:50 30 4
gpt4 key购买 nike

我有将图像从剪贴板导入 RichtTextBox 的代码。

Image i = new Image();
i.Source = Clipboard.GetImage();
paragraph.Inlines.Add(i);

当我尝试删除图像并按 Undo() 时出现异常。

No matching constructor found on type 'System.Windows.Interop.InteropBitmap'. You can use the Arguments or FactoryMethod directives to construct this type.' Line number '1' and line position '226'.

这是因为 RichTextBox 生成的 XAML 如下所示:

<Image.Source><swi:InteropBitmap /></Image.Source>

我尝试将 BitmapSource 的类型更改为 BitmapImage。但在这种情况下,我有 XAML:

<Image.Source><BitmapImage BaseUri="{x:Null}" /></Image.Source></Image>

删除后,撤消我有异常(exception):

Exception thrown: 'System.Windows.Markup.XamlParseException' in PresentationFramework.dll

Additional information: 'Initialization of 'System.Windows.Media.Imaging.BitmapImage' threw an exception.' Line number '1' and line position '243'.

我什至尝试使用 InlineImage 来自:http://wpftutorial.net/InlineImagesXaml.html

<InlineImage Width="100" Height="100" Stretch="Fill">
<![CDATA[iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAB3RJTUUH2AQP
SFlzAAALEgAACxIB0t1+/AAAAARnQU1BAACxjwv8YQUAAAnOSURBVHjaxVcLcBvVFT1vV
ki3Hju3GCQnGjkObONQkJkxCSIHQQGnIdEr5TFs+LaGl7RRCSUvDp8nglH4mDGQ6EwZIm=]]>
</InlineImage>

即使在这种情况下,我在撤消/重做操作中也有异常。有没有可能不编写自己的撤消/重做操作来处理这种情况。

最佳答案

我对编辑旧答案或添加新答案感到困惑。所以我要买一个新的。

使用下面的方法,我现在可以复制现有的图像文件并将其粘贴到 RTB 中,而且我现在还可以从 MSPaint、Photoshop 复制一些未保存的图像数据并粘贴。按保存按钮后,rtf 文件被保存并按预期在 MSWord 中打开。

Ctrl+Z 不起作用,因为图像数据在流中。我正在做。将图像复制为文件时,Ctrl+Z 不是问题。

如有任何疑问,欢迎提出。下面的代码是完整的,可以按原样使用。

ImageCode.cs 用于获取存储在剪贴板中的图像

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows;
using System.Runtime.InteropServices;

namespace WpfRichTextBox._32648134
{
public class ImageCode
{
public static ImageSource ImageFromClipboardDibAsSource()
{
MemoryStream ms = Clipboard.GetData("DeviceIndependentBitmap") as MemoryStream;
if (ms != null)
{
byte[] dibBuffer = new byte[ms.Length];
ms.Read(dibBuffer, 0, dibBuffer.Length);

BITMAPINFOHEADER infoHeader =
BinaryStructConverter.FromByteArray<BITMAPINFOHEADER>(dibBuffer);

int fileHeaderSize = Marshal.SizeOf(typeof(BITMAPFILEHEADER));
int infoHeaderSize = infoHeader.biSize;
int fileSize = fileHeaderSize + infoHeader.biSize + infoHeader.biSizeImage;

BITMAPFILEHEADER fileHeader = new BITMAPFILEHEADER();
fileHeader.bfType = BITMAPFILEHEADER.BM;
fileHeader.bfSize = fileSize;
fileHeader.bfReserved1 = 0;
fileHeader.bfReserved2 = 0;
fileHeader.bfOffBits = fileHeaderSize + infoHeaderSize + infoHeader.biClrUsed * 4;

byte[] fileHeaderBytes =
BinaryStructConverter.ToByteArray<BITMAPFILEHEADER>(fileHeader);

MemoryStream msBitmap = new MemoryStream();
msBitmap.Write(fileHeaderBytes, 0, fileHeaderSize);
msBitmap.Write(dibBuffer, 0, dibBuffer.Length);
msBitmap.Seek(0, SeekOrigin.Begin);

BitmapImage img = new BitmapImage();
img.BeginInit();
img.CacheOption = BitmapCacheOption.OnDemand;
img.CreateOptions = BitmapCreateOptions.DelayCreation;
img.StreamSource = msBitmap;
img.EndInit();

return img;
}
return null;
}

public static MemoryStream ImageFromClipboardDibAsStream()
{
MemoryStream ms = Clipboard.GetData("DeviceIndependentBitmap") as MemoryStream;
if (ms != null)
{
byte[] dibBuffer = new byte[ms.Length];
ms.Read(dibBuffer, 0, dibBuffer.Length);

BITMAPINFOHEADER infoHeader =
BinaryStructConverter.FromByteArray<BITMAPINFOHEADER>(dibBuffer);

int fileHeaderSize = Marshal.SizeOf(typeof(BITMAPFILEHEADER));
int infoHeaderSize = infoHeader.biSize;
int fileSize = fileHeaderSize + infoHeader.biSize + infoHeader.biSizeImage;

BITMAPFILEHEADER fileHeader = new BITMAPFILEHEADER();
fileHeader.bfType = BITMAPFILEHEADER.BM;
fileHeader.bfSize = fileSize;
fileHeader.bfReserved1 = 0;
fileHeader.bfReserved2 = 0;
fileHeader.bfOffBits = fileHeaderSize + infoHeaderSize + infoHeader.biClrUsed * 4;

byte[] fileHeaderBytes =
BinaryStructConverter.ToByteArray<BITMAPFILEHEADER>(fileHeader);

MemoryStream msBitmap = new MemoryStream();
msBitmap.Write(fileHeaderBytes, 0, fileHeaderSize);
msBitmap.Write(dibBuffer, 0, dibBuffer.Length);
msBitmap.Seek(0, SeekOrigin.Begin);

return msBitmap;
}
return null;
}
}

public static class BinaryStructConverter
{
public static T FromByteArray<T>(byte[] bytes) where T : struct
{
IntPtr ptr = IntPtr.Zero;
try
{
int size = Marshal.SizeOf(typeof(T));
ptr = Marshal.AllocHGlobal(size);
Marshal.Copy(bytes, 0, ptr, size);
object obj = Marshal.PtrToStructure(ptr, typeof(T));
return (T)obj;
}
finally
{
if (ptr != IntPtr.Zero)
Marshal.FreeHGlobal(ptr);
}
}

public static byte[] ToByteArray<T>(T obj) where T : struct
{
IntPtr ptr = IntPtr.Zero;
try
{
int size = Marshal.SizeOf(typeof(T));
ptr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(obj, ptr, true);
byte[] bytes = new byte[size];
Marshal.Copy(ptr, bytes, 0, size);
return bytes;
}
finally
{
if (ptr != IntPtr.Zero)
Marshal.FreeHGlobal(ptr);
}
}
}

[StructLayout(LayoutKind.Sequential, Pack = 2)]
struct BITMAPFILEHEADER
{
public static readonly short BM = 0x4d42; // BM

public short bfType;
public int bfSize;
public short bfReserved1;
public short bfReserved2;
public int bfOffBits;
}

[StructLayout(LayoutKind.Sequential)]
struct BITMAPINFOHEADER
{
public int biSize;
public int biWidth;
public int biHeight;
public short biPlanes;
public short biBitCount;
public int biCompression;
public int biSizeImage;
public int biXPelsPerMeter;
public int biYPelsPerMeter;
public int biClrUsed;
public int biClrImportant;
}

}

主窗口.xaml

<Window x:Class="WpfRichTextBox._32648134.Win32648134"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Win32648134" Height="600" Width="700">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="41*"/>
<RowDefinition Height="5*"/>
<RowDefinition Height="21*"/>
</Grid.RowDefinitions>
<RichTextBox x:Name="RtbCompose" Width="500" Height="300" ScrollViewer.VerticalScrollBarVisibility="Visible">
<FlowDocument x:Name="FdDocument">
<Paragraph x:Name="Para1"></Paragraph>
</FlowDocument>
</RichTextBox>
<Button x:Name="BtnCopyImgFile" Content="Paste image" HorizontalAlignment="Left" Margin="96,10,0,0" Grid.Row="1" VerticalAlignment="Top" Width="75" Click="BtnCopyImgFile_Click"/>
<Button x:Name="BtnSave" Content="Save" HorizontalAlignment="Left" Grid.Row="1" VerticalAlignment="Top" Width="75" Margin="521,10,0,0" Click="BtnSave_Click"/>
<Button x:Name="BtnCopyImgData" Content="Paste image data" HorizontalAlignment="Left" Margin="190,11,0,0" Grid.Row="1" VerticalAlignment="Top" Click="BtnCopyImgData_Click"/>
</Grid>
</Window>

主窗口.xaml.cs

using System;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Diagnostics;
using System.IO;

namespace WpfRichTextBox._32648134
{
/// <summary>
/// Interaction logic for Win32648134.xaml
/// </summary>
public partial class Win32648134 : Window
{
public Win32648134()
{
InitializeComponent();
}

private void BtnCopyImgFile_Click(object sender, RoutedEventArgs e)
{
Image i = new Image();

if (Clipboard.ContainsFileDropList())
{
StringCollection fileNames = Clipboard.GetFileDropList();
BitmapImage img = new BitmapImage(new Uri(fileNames[0], UriKind.Absolute));
i.Source = img;
Para1.Inlines.Add(i);
}

Para1.Inlines.Add(new Run("first rtb app"));
}

private void BtnSave_Click(object sender, RoutedEventArgs e)
{
TextRange allText = new TextRange(RtbCompose.Document.ContentStart, RtbCompose.Document.ContentEnd);

FileStream stream = new FileStream(@"I:\RTB.rtf", FileMode.Create);

allText.Save(stream, DataFormats.Rtf);

if (stream != null)
stream.Close();
}

private void BtnCopyImgData_Click(object sender, RoutedEventArgs e)
{
bool hasImgData = Clipboard.ContainsImage();
Image i = new Image();
if (hasImgData)
{
BitmapSource imgData = (BitmapSource)ImageCode.ImageFromClipboardDibAsSource();
i.Source = imgData;

Para1.Inlines.Add(i);
}

Para1.Inlines.Add(new Run("rtb app, image comes from image data instead of file"));
}
}
}

关于c# - WPF RichTextBox 插入图片和撤消操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32648134/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com