Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何让PDFSharp在旋转页面后在正确的位置绘制内容?_C#_Wpf_Rotation_Position_Pdfsharp - Fatal编程技术网

C# 如何让PDFSharp在旋转页面后在正确的位置绘制内容?

C# 如何让PDFSharp在旋转页面后在正确的位置绘制内容?,c#,wpf,rotation,position,pdfsharp,C#,Wpf,Rotation,Position,Pdfsharp,我正在编写一个桌面WPF应用程序,允许人们打开扫描过的PDF文件,如果需要的话进行旋转,然后根据需要进行编辑。使用PDFium将页面呈现到屏幕上,以便用户可以看到需要执行的操作。如果需要旋转,则单击“旋转”按钮进行旋转。如果需要编辑,他们单击相应的按钮,然后使用鼠标在画布上绘制System.Windows.Shapes.Rectangle。然后单击“保存”按钮将修订保存到pdf文件中。对PDF的实际更改是使用PDFSharp v1.50.4000-beta3b进行的,该版本通过Visual St

我正在编写一个桌面WPF应用程序,允许人们打开扫描过的PDF文件,如果需要的话进行旋转,然后根据需要进行编辑。使用PDFium将页面呈现到屏幕上,以便用户可以看到需要执行的操作。如果需要旋转,则单击“旋转”按钮进行旋转。如果需要编辑,他们单击相应的按钮,然后使用鼠标在画布上绘制System.Windows.Shapes.Rectangle。然后单击“保存”按钮将修订保存到pdf文件中。对PDF的实际更改是使用PDFSharp v1.50.4000-beta3b进行的,该版本通过Visual Studio 2013中的NuGet下载

如果页面正面朝上,即旋转值为0,则一切正常。我可以毫无问题地画满地方的盒子。当“旋转”值不是0时会出现问题。如果我将页面沿任意方向旋转90度(旋转=90或-90),那么当我试图在页面上绘制框时,它会把事情搞砸。它似乎在交换页面的高度和宽度(将其从横向转换为纵向,反之亦然),而不改变页面的内容。然后,它在页面再旋转90度时所处的点绘制矩形

为了更好地证明我的意思,这里有一个例子: 我有一个标准大小的pdf页面(A4,字母,没关系)。它在文件的上三分之一处有一个大大的笑脸,其余部分为文本,旋转设置为0,方向为纵向。我在我的程序中打开它并将其旋转90度。现在是横向的,笑脸在页面右三分之一的侧面。我试着在页面的右上角画一个方框。当我单击“保存”按钮时,它会更改文件,现在它以纵向显示,但是内容没有更改,因此现在笑脸在页面右边缘不可见。我试图放置在右上角的长方体就好像它已经旋转过一样,现在它位于右下角。如果我把它做成一个漂亮的长方形,我可以看到它看起来确实像是在整个页面上旋转,但没有内容。如果我在右上角使用另一个框再次执行此操作,然后单击“保存”,它将再次交换高度和宽度,并将我的框旋转到与放置它的位置相差90度的位置。现在我又能看到笑脸了,但盒子还是不在我想要的地方

另外,如果页面旋转是180度,那么当它保存框时,它会以180度的方式旋转它应该处于的位置。因此,如果我的笑脸在页面底部倒置,我在他的眼睛上画了一个方框(在页面底部),它会将方框保存在页面顶部

最奇怪的是,它在几周前工作得很好,但现在不行了。在我的测试中,似乎更改是在PdfDocument.Save()方法中进行的,因为在该点之前,矩形的坐标是页面当前方向/位置的坐标

不管怎样,既然我已经解释了这个问题,下面是我的代码

首先,我们有处理旋转的代码。它位于helper类中,它存储文件的路径和总页数。它需要一个页码列表来旋转。此外,我必须将方向设置为纵向(无论是否应该),因为PDFSharp会在其他位置自动设置,但如果我在此处手动设置,它会正确旋转页面,如果我不在此处设置,页面内容将旋转,而不会改变页面本身的大小/方向

public bool RotatePages(List<int> pageNums)
    {
        if (pageNums.Count > 0)
        {
            PdfDocument currDoc = PdfReader.Open(fullPath, PdfDocumentOpenMode.Modify);

            for (int i = 0; i < totalPageCount; i++)
            {
                PdfPage newPage = currDoc.Pages[i]; //newDoc.AddPage();

                if (pageNums.Contains(i))
                {
                    newPage.Orientation = PdfSharp.PageOrientation.Portrait;

                    newPage.Rotate = (newPage.Rotate + 90) % 360;
                }
            }

            currDoc.Save(fullPath);

            return true;
        }
        else
            return false;
    }
通过一步一步地走过去,我的数学和一切看起来都像它应该做的那样,直到
currDoc.Save(fullPath)

我不知道这里发生了什么,也不知道如何修复它。它以前工作,我不记得我做了什么改变,所以它停止工作。我整天都在寻找解决办法,到目前为止运气都不好。任何帮助都将不胜感激。

所以我终于找到了答案。显然,PDFSharp在处理页面旋转方面存在一些问题。为了修复它,我首先必须调整PDFSharp的源代码

public bool Redact(List<Rect> redactions, List<System.Windows.Media.Color> redactionColors, System.Windows.Media.Matrix matrix, int pageNum)
    {
        if (pageNum >= 0 && pageNum < totalPageCount && redactions.Count > 0 && redactions.Count == redactionColors.Count)
        {
            PdfDocument currDoc = PdfReader.Open(fullPath, PdfDocumentOpenMode.Modify);
            int angle = currDoc.Pages[pageNum].Rotate;
            PdfPage oldPage = currDoc.Pages[pageNum];
            XBrush brush = null;
            XGraphics gfx = XGraphics.FromPdfPage(oldPage);
            XPoint pagePoint = new XPoint(0, 0);

            if (angle == 180)
            {
                pagePoint.X = oldPage.Width / 2;
                pagePoint.Y = oldPage.Height / 2;
                gfx.RotateAtTransform(180, pagePoint);
            }

            for (int i = 0; i < redactions.Count; i++)
            {
                Rect redaction = redactions[i];
                System.Windows.Media.Color redactionColor = redactionColors[i];
                double scaleValue = oldPage.Height / matrix.OffsetX;

                if (angle == 180 || angle == 0)
                {
                    redaction.X = redaction.X / (matrix.OffsetX / oldPage.Width);
                    redaction.Y = redaction.Y / (matrix.OffsetY / oldPage.Height);
                    redaction.Width = redaction.Width / (matrix.OffsetX / oldPage.Width);
                    redaction.Height = redaction.Height / (matrix.OffsetY / oldPage.Height);

                    redaction.Width = redaction.Width / matrix.M11;
                    redaction.Height = redaction.Height / matrix.M12;
                }
                else if (angle == 90 || angle == 270)
                {
                    Rect tempRect = redaction;

                    tempRect.X = redaction.X * scaleValue;
                    tempRect.Y = redaction.Y * scaleValue;

                    tempRect.Height = redaction.Height * scaleValue;
                    tempRect.Width = redaction.Width * scaleValue;

                    redaction.Width = tempRect.Height;
                    redaction.Height = tempRect.Width;

                    tempRect.Width = tempRect.Width / matrix.M11;
                    tempRect.Height = tempRect.Height / matrix.M12;

                    redaction.X = oldPage.Width - tempRect.Y - tempRect.Height;
                    redaction.Y = tempRect.X;

                    if (angle == 90)
                        gfx.RotateAtTransform(180, new XPoint(oldPage.Width / 2, oldPage.Height / 2));

                    redaction.Width = tempRect.Height;
                    redaction.Height = tempRect.Width;
                }

                brush = new XSolidBrush(XColor.FromArgb(redactionColor.A, redactionColor));
                gfx.DrawRectangle(brush, redaction);
            }

            gfx.Save();
            currDoc.Save(fullPath);

            return true;
        }
        else
            return false;
    }
当页面设置为横向时,我不得不注释掉交换高度/宽度值的代码。显然,PDFSharp使用“orientation”变量来存储方向,尽管PDF没有这样的设置。通过注释掉这些行,我终于开始为旋转页面获得正确的高度和宽度。这是对PdfPage.cs的更改

public XUnit Height
    {
        get
        {
            PdfRectangle rect = MediaBox;
            //return _orientation == PageOrientation.Portrait ? rect.Height : rect.Width;
            return rect.Height;
        }
        set
        {
            PdfRectangle rect = MediaBox;
            //if (_orientation == PageOrientation.Portrait)
                MediaBox = new PdfRectangle(rect.X1, 0, rect.X2, value);
            //else
            //    MediaBox = new PdfRectangle(0, rect.Y1, value, rect.Y2);
            _pageSize = PageSize.Undefined;
        }
    }


public XUnit Width
    {
        get
        {
            PdfRectangle rect = MediaBox;
            //return _orientation == PageOrientation.Portrait ? rect.Width : rect.Height;
            return rect.Width;
        }
        set
        {
            PdfRectangle rect = MediaBox;
            //if (_orientation == PageOrientation.Portrait)
                MediaBox = new PdfRectangle(0, rect.Y1, value, rect.Y2);
            //else
            //    MediaBox = new PdfRectangle(rect.X1, 0, rect.X2, value);
            _pageSize = PageSize.Undefined;
        }
    }
然后我不得不注释掉WriteObject方法中的几行,它们翻转了mediabox的高度和宽度值。这些是我注释掉的行。这阻止了PDFSharp在每次保存时翻转我的旋转页面大小

        //// HACK: temporarily flip media box if Landscape
        //PdfRectangle mediaBox = MediaBox;
        //// TODO: Take /Rotate into account
        //if (_orientation == PageOrientation.Landscape)
        //    MediaBox = new PdfRectangle(mediaBox.X1, mediaBox.Y1, mediaBox.Y2, mediaBox.X2);

...

//if (_orientation == PageOrientation.Landscape)
        //    MediaBox
最后,在我自己的代码中,我必须更改大多数编校代码,以将框以正确的大小放在正确的位置。正确的数学运算需要花费很长时间,代码也很混乱,但它可以工作。任何关于如何清理的建议都将不胜感激

public bool Redact(List<Rect> redactions, List<System.Windows.Media.Color> redactionColors, System.Windows.Media.Matrix matrix, int pageNum)
    {
        if (pageNum >= 0 && pageNum < totalPageCount && redactions.Count > 0 && redactions.Count == redactionColors.Count)
        {
            PdfDocument currDoc = PdfReader.Open(fullPath, PdfDocumentOpenMode.Modify);
            int angle = currDoc.Pages[pageNum].Rotate;
            PdfPage oldPage = currDoc.Pages[pageNum];
            XBrush brush = null;
            XGraphics gfx = XGraphics.FromPdfPage(oldPage);
            XPoint pagePoint = new XPoint(0, 0);

            if (angle == 180)
            {
                pagePoint.X = oldPage.Width / 2;
                pagePoint.Y = oldPage.Height / 2;
                gfx.RotateAtTransform(180, pagePoint);
            }

            for (int i = 0; i < redactions.Count; i++)
            {
                Rect redaction = redactions[i];
                System.Windows.Media.Color redactionColor = redactionColors[i];
                double scaleValue = oldPage.Height / matrix.OffsetX;

                if (angle == 180 || angle == 0)
                {
                    redaction.X = redaction.X / (matrix.OffsetX / oldPage.Width);
                    redaction.Y = redaction.Y / (matrix.OffsetY / oldPage.Height);
                    redaction.Width = redaction.Width / (matrix.OffsetX / oldPage.Width);
                    redaction.Height = redaction.Height / (matrix.OffsetY / oldPage.Height);

                    redaction.Width = redaction.Width / matrix.M11;
                    redaction.Height = redaction.Height / matrix.M12;
                }
                else if (angle == 90 || angle == 270)
                {
                    Rect tempRect = redaction;

                    tempRect.X = redaction.X * scaleValue;
                    tempRect.Y = redaction.Y * scaleValue;

                    tempRect.Height = redaction.Height * scaleValue;
                    tempRect.Width = redaction.Width * scaleValue;

                    redaction.Width = tempRect.Height;
                    redaction.Height = tempRect.Width;

                    tempRect.Width = tempRect.Width / matrix.M11;
                    tempRect.Height = tempRect.Height / matrix.M12;

                    redaction.X = oldPage.Width - tempRect.Y - tempRect.Height;
                    redaction.Y = tempRect.X;

                    if (angle == 90)
                        gfx.RotateAtTransform(180, new XPoint(oldPage.Width / 2, oldPage.Height / 2));

                    redaction.Width = tempRect.Height;
                    redaction.Height = tempRect.Width;
                }

                brush = new XSolidBrush(XColor.FromArgb(redactionColor.A, redactionColor));
                gfx.DrawRectangle(brush, redaction);
            }

            gfx.Save();
            currDoc.Save(fullPath);

            return true;
        }
        else
            return false;
    }
public bool编校(列表编校、列表编校颜色、System.Windows.Media.Matrix矩阵、int pageNum)
{
如果(pageNum>=0&&pageNum0&&redactions.Count==redactionColors.Count)
{
pdfdocumentcurrdoc=PdfReader.Open(完整路径,PdfDocumentOpenMode.Modify);
int angle=currDoc.Pages[pageNum]。旋转;
PdfPage oldPage=currDoc.Pages[pageNum];
XBrush=null;
XGraphics gfx=XGraphics.FromPdfPage(旧页);
XPoint pagePo
public bool Redact(List<Rect> redactions, List<System.Windows.Media.Color> redactionColors, System.Windows.Media.Matrix matrix, int pageNum)
    {
        if (pageNum >= 0 && pageNum < totalPageCount && redactions.Count > 0 && redactions.Count == redactionColors.Count)
        {
            PdfDocument currDoc = PdfReader.Open(fullPath, PdfDocumentOpenMode.Modify);
            int angle = currDoc.Pages[pageNum].Rotate;
            PdfPage oldPage = currDoc.Pages[pageNum];
            XBrush brush = null;
            XGraphics gfx = XGraphics.FromPdfPage(oldPage);
            XPoint pagePoint = new XPoint(0, 0);

            if (angle == 180)
            {
                pagePoint.X = oldPage.Width / 2;
                pagePoint.Y = oldPage.Height / 2;
                gfx.RotateAtTransform(180, pagePoint);
            }

            for (int i = 0; i < redactions.Count; i++)
            {
                Rect redaction = redactions[i];
                System.Windows.Media.Color redactionColor = redactionColors[i];
                double scaleValue = oldPage.Height / matrix.OffsetX;

                if (angle == 180 || angle == 0)
                {
                    redaction.X = redaction.X / (matrix.OffsetX / oldPage.Width);
                    redaction.Y = redaction.Y / (matrix.OffsetY / oldPage.Height);
                    redaction.Width = redaction.Width / (matrix.OffsetX / oldPage.Width);
                    redaction.Height = redaction.Height / (matrix.OffsetY / oldPage.Height);

                    redaction.Width = redaction.Width / matrix.M11;
                    redaction.Height = redaction.Height / matrix.M12;
                }
                else if (angle == 90 || angle == 270)
                {
                    Rect tempRect = redaction;

                    tempRect.X = redaction.X * scaleValue;
                    tempRect.Y = redaction.Y * scaleValue;

                    tempRect.Height = redaction.Height * scaleValue;
                    tempRect.Width = redaction.Width * scaleValue;

                    redaction.Width = tempRect.Height;
                    redaction.Height = tempRect.Width;

                    tempRect.Width = tempRect.Width / matrix.M11;
                    tempRect.Height = tempRect.Height / matrix.M12;

                    redaction.X = oldPage.Width - tempRect.Y - tempRect.Height;
                    redaction.Y = tempRect.X;

                    if (angle == 90)
                        gfx.RotateAtTransform(180, new XPoint(oldPage.Width / 2, oldPage.Height / 2));

                    redaction.Width = tempRect.Height;
                    redaction.Height = tempRect.Width;
                }

                brush = new XSolidBrush(XColor.FromArgb(redactionColor.A, redactionColor));
                gfx.DrawRectangle(brush, redaction);
            }

            gfx.Save();
            currDoc.Save(fullPath);

            return true;
        }
        else
            return false;
    }