zoukankan      html  css  js  c++  java
  • WPF杂难解 RichTextBox粘贴图片地址处理,并保存的问题

    引:

    这个系列将会记录工作中遇到的一些疑难问题,并贴出自己的解决方案。因为本人水平仍在入门级别徘徊,如有更好方案,望高手指点。

    问题来源:

    公司在做的项目中,需要用到文本编辑器,实现粘贴文本、图片等功能,类似网页中的FCKEditor。处理图片时,我们需要缩略显示图片,并把图片发送到服务器。

    问题在这里,我们以xaml读取RichTextBox的内容时,发现其图片标签的地址极其怪异,如下:

    <FlowDocument PagePadding="5,0,5,0" AllowDrop="True" NumberSubstitution.CultureSource="User" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
        <BlockUIContainer TextAlignment="Justify">
            <Image Width="553" Height="415">
                <Image.Source>
                    <BitmapImage BaseUri="pack://payload:,,wpf1,/Xaml/Document.xaml" UriSource="./Image1.bmp" CacheOption="OnLoad" />
                </Image.Source>
            </Image>
        </BlockUIContainer>

    </FlowDocument> 

     其中有BaseUri="pack://payload:,,wpf1,/Xaml/Document.xaml" UriSource="./Image1.bmp"猜测图片是被保存在某个临时文件夹中 ,但是无法定位。

    解决思路一:

     既然图片是粘贴进来的,我们应该能在RichTextBox的粘贴命令时即对图片进行处理。于是使用了WPF的ClipBoard,把图片保存到本地后,再插入RichTextBox中。大致代码如下:

    private void PaseHandlers(object sender, ExecutedRoutedEventArgs args) 

    {
        if (Clipboard.ContainsData(DataFormats.Bitmap))
        {
            BitmapSource bitmap = Clipboard.GetImage();
            System.Drawing.Bitmap b = BitmapToBitmap(bitmap, ".bmp");
            string path = Constants.SYSTEM.TEMP_DATA_PATH + Guid.NewGuid().ToString() + ".bmp";
            b.Save(path, System.Drawing.Imaging.ImageFormat.Jpeg);
            b.Dispose();
            //添加到控件中
            InsertImage(path, path, this.Document);
            args.Handled = true;
            return;
        }
    }

     但这个方案的问题在于,如果我以图文混排方式粘贴的话,文本就会丢失。

    有人会说,那你用Clipboard.GetText(); 拿文本嘛。我当然试了,但是这样会把图片和文本分开,即图片和文字的位置关系没办法处理。

    解决思路二:

    刚刚开始考虑这个问题时想到过RTF,又惮于RTF格式的复杂。 

     但是RTF给RichTextBox赋值显示又是好的,所以想到一个取巧的办法,先在内存中实例化一个RichTextBox,将ClipBord内的RTF格式数据赋给它,再对它的Document进行解析。

     //取出剪切板内数据 

    IDataObject iData = Clipboard.GetDataObject();

    //内存内实例化一个RichTextBox
    System.Windows.Controls.RichTextBox rtb = new System.Windows.Controls.RichTextBox();
    //rtf格式
    if (iData.GetDataPresent(DataFormats.Rtf))
    {
        var rtf = iData.GetData(DataFormats.Rtf);
        //将rtf载入内存内的RichTextBox
        TextRange textRange = new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd);
        using (MemoryStream rtfMemoryStream = new MemoryStream())
        {
            using (StreamWriter rtfStreamWriter = new StreamWriter(rtfMemoryStream))
            {
                rtfStreamWriter.Write(rtf);
                rtfStreamWriter.Flush();
                rtfMemoryStream.Seek(0, SeekOrigin.Begin);
                //Load the MemoryStream into TextRange ranging from start to end of RichTextBox.
                textRange.Load(rtfMemoryStream, DataFormats.Rtf);
            }
        }
    }

    这样就又可以利用 System.Windows.Markup.XamlWriter.Save();将其保存为xaml处理。起码可以分析它的节点了。

     这里我们又回到了问题来源时列出的文件格式,在对图片处理时用到了一个转换:

    BitmapImage bitmap = new BitmapImage();
    bitmap.BeginInit();
    bitmap.BaseUri = new Uri(bmpNode.Attributes["BaseUri"].Value);
    bitmap.UriSource = new Uri(bmpNode.Attributes["UriSource"].Value, UriKind.Relative);
    bitmap.EndInit();
    BitmapSource bsrc = (BitmapSource)bitmap;
    PngBitmapEncoder png = new PngBitmapEncoder();
    png.Frames.Add(BitmapFrame.Create(bsrc));
    imgName = Constants.SYSTEM.TEMP_DATA_PATH + "\\" + bmpNode.Attributes["UriSource"].Value.Replace("./""");
    if (File.Exists(imgName))
    {
        File.Delete(imgName);
    }
    using (Stream stream = File.Create(imgName))
    {
        png.Save(stream);
    }

    这样图片即是可控的,很方便地对它进行处理。

    但是这个方法处理来,性能损耗很大,希望高手能给出更好的解决方案。 

  • 相关阅读:
    Allegro PCB Design GXL (legacy) 使用slide无法将走线推挤到焊盘的原因
    OrCAD Capture CIS 16.6 导出BOM
    Altium Designer (17.0) 打印输出指定的层
    Allegro PCB Design GXL (legacy) 将指定的层导出为DXF
    Allegro PCB Design GXL (legacy) 设置十字大光标
    Allegro PCB Design GXL (legacy) 手动更改元器件引脚的网络
    magento产品导入时需要注意的事项
    magento url rewrite
    验证台湾同胞身份证信息
    IE8对css文件的限制
  • 原文地址:https://www.cnblogs.com/shen6041/p/2385888.html
Copyright © 2011-2022 走看看