C# 将文档转换为PNG时图像模糊

C# 将文档转换为PNG时图像模糊,c#,asp.net,office-interop,C#,Asp.net,Office Interop,好吧,我有一个问题再次困扰着我。我有一些代码可以将DOC文件转换为PNG文件。当我在本地主机上执行此操作时,图像很好。当我把相同的代码放在live server上时,图像非常小(与我从中获取文档文件的点文件大小相同,基本上点被填充并变成文档)。现在。。。这是疯狂的部分。如果我以管理员的身份登录到托管服务器,然后访问live网站,即使我从iPhone访问该网站,图像也会大而清晰。当我从托管服务器注销并刷新live页面时,图像又变小了。下面是我用来将文档转换为PNG的代码。另一方面,如果我使用方法2

好吧,我有一个问题再次困扰着我。我有一些代码可以将DOC文件转换为PNG文件。当我在本地主机上执行此操作时,图像很好。当我把相同的代码放在live server上时,图像非常小(与我从中获取文档文件的点文件大小相同,基本上点被填充并变成文档)。现在。。。这是疯狂的部分。如果我以管理员的身份登录到托管服务器,然后访问live网站,即使我从iPhone访问该网站,图像也会大而清晰。当我从托管服务器注销并刷新live页面时,图像又变小了。下面是我用来将文档转换为PNG的代码。另一方面,如果我使用方法2,我可以使图像更大,分辨率更高,但字体不合适

    private void ConvertDocToPNG(string startupPath, string filename1)
    {
        var docPath = Path.Combine(startupPath, filename1);
        Application app = new Application();
        Microsoft.Office.Interop.Word.Document doc = new Microsoft.Office.Interop.Word.Document();
        app.Visible = false;
        doc = app.Documents.Open(docPath);
        app.WindowState = Microsoft.Office.Interop.Word.WdWindowState.wdWindowStateMaximize;
        app.ActiveWindow.ActivePane.View.Zoom.Percentage = 100;
        doc.ShowGrammaticalErrors = false;
        doc.ShowRevisions = false;
        doc.ShowSpellingErrors = false;

        //Opens the word document and fetch each page and converts to image
        foreach (Microsoft.Office.Interop.Word.Window window in doc.Windows)
        {
            foreach (Microsoft.Office.Interop.Word.Pane pane in window.Panes)
            {
                for (var i = 1; i <= pane.Pages.Count; i++)
                {
                    Microsoft.Office.Interop.Word.Page page = null;
                    bool populated = false;
                    while (!populated)
                    {
                        try
                        {
                            // This !@#$ variable won't always be ready to spill its pages. If you step through
                            // the code, it will always work.  If you just execute it, it will crash.  So what
                            // I am doing is letting the code catch up a little by letting the thread sleep
                            // for a microsecond.  The second time around, this variable should populate ok.
                            page = pane.Pages[i];
                            populated = true;
                        }
                        catch (COMException ex)
                        {
                            Thread.Sleep(1);
                        }
                    }
                    var bits = page.EnhMetaFileBits;
                    var target = Path.Combine(startupPath + "\\", string.Format("{1}_page_{0}", i, filename1.Split('.')[0]));

                    try
                    {
                        using (var ms = new MemoryStream((byte[])(bits)))
                        {
                            var image = System.Drawing.Image.FromStream(ms);
                            var pngTarget = Path.ChangeExtension(target, "png");

                            // Method 2
                            image.Save(pngTarget, System.Drawing.Imaging.ImageFormat.Png);

                            // Another way to save it using custom size
                            //float width = Convert.ToInt32(hfIdCardMaxWidth.Value);
                            //float height = Convert.ToInt32(hfIdCardMaxHeight.Value);
                            //float scale = Math.Min(width / image.Width, height / image.Height);
                            //int resizedWidth = (int)Math.Round(image.Width * scale);
                            //int resizedHeight = (int)Math.Round(image.Height * scale);
                            //Bitmap myBitmap = new Bitmap(image, new Size(resizedWidth, resizedHeight));
                            //myBitmap.Save(pngTarget, System.Drawing.Imaging.ImageFormat.Png);
                        }
                    }
                    catch (System.Exception ex)
                    {
                        doc.Close(true, Type.Missing, Type.Missing);
                        Marshal.ReleaseComObject(doc);
                        doc = null;
                        app.Quit(true, Type.Missing, Type.Missing);
                        Marshal.ReleaseComObject(app);
                        app = null;
                        throw ex;
                    }
                }
            }
        }
        doc.Close(true, Type.Missing, Type.Missing);
        Marshal.ReleaseComObject(doc);
        doc = null;
        app.Quit(true, Type.Missing, Type.Missing);
        Marshal.ReleaseComObject(app);
        app = null;
    }
private void ConvertDocToPNG(字符串startupPath,字符串filename1)
{
var docPath=Path.Combine(startupPath,filename1);
应用程序app=新应用程序();
Microsoft.Office.Interop.Word.Document doc=新的Microsoft.Office.Interop.Word.Document();
app.Visible=false;
doc=app.Documents.Open(docPath);
app.WindowState=Microsoft.Office.Interop.Word.WdWindowState.WdWindowState;
app.ActiveWindow.ActivePane.View.Zoom.Percentage=100;
doc.show语法错误=false;
doc.ShowRevisions=false;
doc.ShowSpellingErrors=false;
//打开word文档,获取每页并转换为图像
foreach(doc.Windows中的Microsoft.Office.Interop.Word.Window窗口)
{
foreach(window.Panes中的Microsoft.Office.Interop.Word.Pane窗格)
{

对于(var i=1;i考虑到您以无人参与的方式使用interop,各种奇怪/意外的事情都可能发生。我承认,我不知道为什么您在不同的环境中遇到测试用例时会出现这种症状。我强烈感觉无人参与是罪魁祸首。interop在用户登录时运行上下文,如果没有用户…好吧…是的。那么,如何绕过这个问题,仍然保持无人值守?首先想到的是使用OpenXML SDK。这是以无人值守的方式操作office文档的安全方法。我自己使用它来生成无人值守的报告

假设:

  • 标准DOCX格式
  • 文档包含文字/图片/样式/任何东西。它不仅仅是一袋图片(如果是,有更简单的方法来完成你需要的)
API:

但是,你不能用OpenXML将文档转换成图像!我想到了一个解决方法,但这没有经过测试。想法是将文档转换成html,然后渲染html并将其填充到图像中

以下是使用OpenXML将word文档转换为HTML的方法:

一大套电动工具,可以做各种方便的事情:

您将需要的特定模块:

下面是一个方便的库,用于呈现HTML并将其转储到图像中:

假设您希望此代码以无人参与的方式运行是否安全?以这种方式使用interop(或任何MS office interop)一词是一个坏主意,但我们可以使用OpenXML SDK为您提供一些功能。如果此代码以交互方式运行,则忽略以下注释:)的确是无人参与的方式。这有点过分了,因为我真正需要做的就是提高图像分辨率,从整个过程中获得一个可行的图像,将MemoryStream转换成字节数组,然后转换成位图,从中我可以根据需要调整其大小。问题是,当你以100%缩放打开文档时,它已经非常小了,所以从某种意义上说,代码是按预期工作的。我只是感到困惑的是,登录给了我更好的视角(2023x1279比200x120)。尽管如此,我还是会投你一票,赞成写得好的回答:)尽管这并不是我想要的。谢谢!我同意这有点过分,但在无人值守的windows服务中使用interop时,我遇到了太多的地雷,以至于我非常害怕它。请避免只使用代码的答案。更新你的帖子,用简单的语言详细阐述你的想法。
using (var ms = new MemoryStream((byte[])(bits)))
        {
            var emf = new Metafile(ms);
            var scale = 400 / emf.HorizontalResolution;
            var Width= emf.Width * scale;
            var Height = emf.Height * scale;
            System.Drawing.Bitmap b = new System.Drawing.Bitmap((Int32)Width, (Int32)Height);
            var G = System.Drawing.Graphics.FromImage(b);
            G.Clear(System.Drawing.Color.White);
            G.DrawImage(emf, 0, 0, (float)Width, (float)Height);
            b.Save(pngTarget, System.Drawing.Imaging.ImageFormat.Png);
        }