简体   繁体   English

无法从剪贴板检索图像

[英]Can't retrieve image from clipboard

I try to save range of cells from excel file to a picture. 我尝试将单元格范围从excel文件保存到图片。 I used the CopyPicture method from the interop.excel api so the picture sould be on clipboard. 我使用了来自interop.excel api的CopyPicture方法,因此图片位于剪贴板上。 When i press ctrl+v on a word document for example, i get the picture but i can't success to get it with code. 例如,当我在Word文档上按ctrl + v时,我得到了图片,但是我无法成功通过代码获得它。 The returned data from the GetImageFromClipBoard method is null. 从GetImageFromClipBoard方法返回的数据为null。

    public void SaveAsImage()
    {
        var usedRange = ws.UsedRange;
        int startRow = usedRange.Row;
        int endRow = startRow + usedRange.Rows.Count - 1;
        int startColumn = usedRange.Column;
        int endColumn = startColumn + usedRange.Columns.Count - 1; 
        Xl.Range rng = wb.ActiveSheet.Range[ws.Cells[1, 1], 
        ws.Cells[endRow, endColumn]];
        rng.CopyPicture(Xl.XlPictureAppearance.xlScreen, 
        Xl.XlCopyPictureFormat.xlBitmap);

        Image image = GetImageFromClipBoard();
        image.Save("image.bmp", System.Drawing.Imaging.ImageFormat.Bmp);
    }

    [STAThread]
    private Image GetImageFromClipBoard()
    {
        IDataObject clipboardData = Clipboard.GetDataObject();
        Exception threadEx = null;
        Thread staThread = new Thread(
            delegate ()
            {
                try
                {
                    clipboardData = Clipboard.GetDataObject();
                }

                catch (Exception ex)
                {
                    threadEx = ex;
                }
            });
        staThread.SetApartmentState(ApartmentState.STA);
        staThread.Start();
        staThread.Join();
        return (Bitmap)clipboardData.GetData(DataFormats.Bitmap);
    }

What you are trying to do is retrieving a bitmap from the clipboard, as type "Bitmap". 您要执行的操作是从剪贴板中检索位图,类型为“位图”。 I'm not sure Office uses that type at all, though. 不过,我不确定Office是否使用该类型。

Note that the DataFormats are not an enum; 注意, DataFormats不是枚举。 they just refer to string IDs commonly used for clipboard content. 它们只是引用剪贴板内容中常用的字符串ID。 This immediately implies that you can add custom ones. 这立即意味着您可以添加自定义项。 These custom ones are generally put on the clipboard as byte stream. 这些自定义项通常作为字节流放在剪贴板上。 This answer details the way to store and fetch those byte arrays on the clipboard. 该答案详细说明了在剪贴板上存储和获取这些字节数组的方式。

One of the main ones that is used is DIB (basically, a BMP file without its specific file header), but Office specifically uses these: 使用的主要文件之一是DIB(基本上是没有特定文件头的BMP文件),但是Office专门使用了以下文件:

  • "PNG+Office Art"
  • "JFIF+Office Art"
  • "GIF+Office Art"
  • "PNG"
  • "JFIF"
  • "GIF"

(I heard the "+Office Art" ones are also just images, but I haven't tried that out myself) (我听说“ + Office Art”也只是图像,但我自己还没有尝试过)

So yeah, if you try to fetch these, make a new MemoryStream with the bytes from the clipboard, and make a new Bitmap from the MemoryStream, you should be there. 所以,是的,如果您尝试获取它们,使用剪贴板中的字节创建一个新的MemoryStream ,并从MemoryStream中创建一个新的Bitmap ,那么您应该在那里。 You basically try them until you got something that sticks, starting with the PNG ones. 从PNG开始,您基本上可以尝试使用它们,直到遇到问题为止。

I wrote a more detailed explanation with full code a while ago, which focused specifically on copying and retrieving PNG and DIB on the clipboard. 不久前,我用完整的代码写了一个更详细的解释 ,它专门针对剪贴板上的PNG和DIB进行复制和检索。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM