【问题标题】:Compare picture in Word file and in a folder?比较Word文件和文件夹中的图片?
【发布时间】:2012-09-10 13:23:52
【问题描述】:

所以我使用 Word.Interloop 并且为了比较两张图片,我想我必须将当前图片(在 word 文件中)转换为位图图像,然后将其与桌面上的位图图像对象进行比较? 或者也许这是一种更简单的方法?

Word.InlineShape x;
x.isEqual( Picture from Desktop/ bitmapImage.Object);

【问题讨论】:

    标签: c# ms-word


    【解决方案1】:

    我制作了一个小样本来展示如何实现这一点。主要思想是将桌面上的图像表示为Bitmap 实例,然后将其逐个像素地与文档中的Bitmap 实例进行比较。比较的方法是首先将内联形状复制到剪贴板,然后将其转换为 Bitmap,然后将其与参考(来自桌面)进行比较 - 首先按大小,然后逐像素。

    该示例使用 .NET 4.5、Microsoft Office 对象库版本 15.0 和 Microsoft Word 对象库版本 15.0 实现为 C# 控制台应用程序。

    using System;
    using System.Drawing;
    using System.Threading;
    using System.Windows.Forms;
    using Application = Microsoft.Office.Interop.Word.Application;
    
    namespace WordDocStats
    {
        class Program
        {
            // General idea is based on: https://stackoverflow.com/a/7937590/700926
            static void Main()
            {
                // Open a doc file
                var wordApplication = new Application();
                var document = wordApplication.Documents.Open(@"C:\Users\Username\Documents\document.docx");
    
                // Load the image to compare against.
                var bitmapToCompareAgainst = new Bitmap(@"C:\Users\Username\Documents\image.png");
    
                // For each inline shape, do a comparison
                // By inspection you can see that the first inline shape have index 1 ( and not zero as one might expect )
                for (var i = 1; i <= wordApplication.ActiveDocument.InlineShapes.Count; i++)
                {
                    // closure
                    // http://confluence.jetbrains.net/display/ReSharper/Access+to+modified+closure
                    var inlineShapeId = i; 
    
                    // parameterized thread start
                    // https://stackoverflow.com/a/1195915/700926
                    var thread = new Thread(() => CompareInlineShapeAndBitmap(inlineShapeId, bitmapToCompareAgainst, wordApplication));
    
                    // STA is needed in order to access the clipboard
                    // https://stackoverflow.com/a/518724/700926
                    thread.SetApartmentState(ApartmentState.STA);
                    thread.Start();
                    thread.Join();
                }
    
                // Close word
                wordApplication.Quit();
                Console.ReadLine();
            }
    
            // General idea is based on: https://stackoverflow.com/a/7937590/700926
            protected static void CompareInlineShapeAndBitmap(int inlineShapeId, Bitmap bitmapToCompareAgainst, Application wordApplication)
            {
                // Get the shape, select, and copy it to the clipboard
                var inlineShape = wordApplication.ActiveDocument.InlineShapes[inlineShapeId];
                inlineShape.Select();
                wordApplication.Selection.Copy();
    
                // Check data is in the clipboard
                if (Clipboard.GetDataObject() != null)
                {
                    var data = Clipboard.GetDataObject();
    
                    // Check if the data conforms to a bitmap format
                    if (data != null && data.GetDataPresent(DataFormats.Bitmap))
                    {
                        // Fetch the image and convert it to a Bitmap
                        var image = (Image)data.GetData(DataFormats.Bitmap, true);
                        var currentBitmap = new Bitmap(image);
                        var imagesAreEqual = true;
    
                        // Compare the images - first by size and then pixel by pixel
                        // Based on: http://www.c-sharpcorner.com/uploadfile/prathore/image-comparison-using-C-Sharp/
                        if(currentBitmap.Width == bitmapToCompareAgainst.Width && currentBitmap.Height == bitmapToCompareAgainst.Height)
                        {
                            for (var i = 0; i < currentBitmap.Width; i++)
                            {
                                if(!imagesAreEqual)
                                    break;
    
                                for (var j = 0; j < currentBitmap.Height; j++)
                                {
                                    if (currentBitmap.GetPixel(i, j).Equals(bitmapToCompareAgainst.GetPixel(i, j)))
                                        continue;
    
                                    imagesAreEqual = false;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            imagesAreEqual = false;
                        }
                        Console.WriteLine("Inline shape #{0} is equal to the 'external' bitmap: {1}", inlineShapeId, imagesAreEqual);
                    }
                    else
                    {
                        Console.WriteLine("Clipboard data is not in an image format");
                    }
                }
                else
                {
                    Console.WriteLine("Clipboard is empty");
                }
            }
        }
    }
    

    参考资料:

    【讨论】:

      猜你喜欢
      • 2018-12-11
      • 1970-01-01
      • 2015-01-15
      • 2020-12-26
      • 2021-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多