병합 후 주석 (스탬프) 누락

유 스웰

itextsharp5.5.13.1에 의해 병합 된 후 주석 (PdfName.STAMP)이 누락되었습니다. 두 개의 pdf가 있습니다. 하나는 작동하고 다른 하나는 작동하지 않습니다. 어떤 아이디어라도 감사하겠습니다.

코드는 다음과 같습니다.

string outFile = inputFile + "_f.pdf";
using (PdfReader pdfReader = new PdfReader(inputFileName))
{
    PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(outFile, FileMode.Create, FileAccess.Write, FileShare.None))

    //pdfStamper.FormFlattening = true;
    //pdfStamper.FreeTextFlattening = true;
    pdfStamper.AnnotationFlattening = true;
    //pdfStamper.AcroFields.GenerateAppearances = true;

}
mkl

원인 은 iTextSharp의 버그입니다. 경계 상자가 원점을 왼쪽 아래 모서리로 사용하지 않으면 주석 병합이 병합 된 주석의 위치를 ​​올바르게 계산하지 못합니다.

의 코드를 보면 경계 상자가 원점에 있거나 모양 경계 상자를 주석 사각형에 맞추기 위해 크기 조정이 필요하지 않은 경우에만 블록 PdfStamperImp.FlattenAnnotations(bool)의 계산 if (app != null)이 의미가 있음을 금방 알 수 있습니다.

(경계 상자의 왼쪽 아래 모서리가 원점 인 경우가 많기 때문에 자주 표시되지 않습니다.)

따라서 이러한 주석 을 병합 하려면 다음과 같이 다른 병합 방법을 사용해야합니다 .

using (PdfReader pdfReader = new PdfReader(inputFileName))
{
    PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(outFile, FileMode.Create, FileAccess.Write, FileShare.None));
    ImprovedAnnotationFlattening(pdfStamper);
    pdfStamper.Close();
}

다음 도우미 메서드를 사용합니다.

void ImprovedAnnotationFlattening(PdfStamper pdfStamper)
{
    double[] DEFAULT_MATRIX = { 1, 0, 0, 1, 0, 0 };

    PdfReader reader = pdfStamper.Reader;

    for (int page = 1; page <= reader.NumberOfPages; ++page)
    {
        PdfDictionary pageDic = reader.GetPageN(page);
        PdfArray annots = pageDic.GetAsArray(PdfName.ANNOTS);

        if (annots == null)
            continue;

        for (int idx = 0; idx < annots.Size; ++idx)
        {
            PdfObject annoto = annots.GetDirectObject(idx);
            if (!(annoto is PdfDictionary))
                continue;

            PdfDictionary annDic = (PdfDictionary)annoto;

            PdfNumber ff = annDic.GetAsNumber(PdfName.F);
            int flags = ff != null ? ff.IntValue : 0;
            if ((flags & PdfFormField.FLAGS_PRINT) == 0 || (flags & PdfFormField.FLAGS_HIDDEN) != 0)
                continue;

            PdfObject obj1 = annDic.Get(PdfName.AP);
            if (obj1 == null)
                continue;
            PdfDictionary appDic = obj1 is PdfIndirectReference
                ? (PdfDictionary)PdfReader.GetPdfObject(obj1)
                : (PdfDictionary)obj1;
            PdfObject obj = appDic.Get(PdfName.N);
            PdfStream objDict = appDic.GetAsStream(PdfName.N);

            if (objDict != null)
            {
                Rectangle rect = PdfReader.GetNormalizedRectangle(annDic.GetAsArray(PdfName.RECT));
                Rectangle bbox = PdfReader.GetNormalizedRectangle(objDict.GetAsArray(PdfName.BBOX));

                PdfContentByte cb = pdfStamper.GetOverContent(page);
                cb.SetLiteral("Q ");

                PdfArray matrixArray = objDict.GetAsArray(PdfName.MATRIX);
                double[] matrix = matrixArray != null ? matrixArray.AsDoubleArray() : DEFAULT_MATRIX;
                AffineTransform transform = new AffineTransform(matrix);

                double[] bboxCorners = { bbox.Left, bbox.Bottom, bbox.Right, bbox.Bottom, bbox.Right, bbox.Top, bbox.Left, bbox.Top };
                transform.Transform(bboxCorners, 0, bboxCorners, 0, 4);
                double minX = Min(bboxCorners, 0, 2);
                double maxX = Max(bboxCorners, 0, 2);
                double minY = Min(bboxCorners, 1, 2);
                double maxY = Max(bboxCorners, 1, 2);

                transform.preConcatenate(AffineTransform.GetTranslateInstance(-minX, -minY));
                transform.preConcatenate(AffineTransform.GetScaleInstance(rect.Width/(maxX-minX), rect.Height/(maxY-minY)));
                transform.preConcatenate(AffineTransform.GetTranslateInstance(rect.Left, rect.Bottom));

                transform.GetMatrix(matrix);

                cb.AddFormXObj(objDict, GenerateName(), matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);

                cb.SetLiteral("q ");

                annots.Remove(idx);
                --idx;
            }
        }
    }
}

double Min(double[] array, int start, int step)
{
    double result = array[start];

    for (int i = start + step; i < array.Length; i+=step)
    {
        result = Math.Min(result, array[i]);
    }

    return result;
}

double Max(double[] array, int start, int step)
{
    double result = array[start];

    for (int i = start + step; i < array.Length; i += step)
    {
        result = Math.Max(result, array[i]);
    }

    return result;
}

PdfName GenerateName()
{
    PdfName name = new PdfName("XXX" + formXObjectsCounter);
    ++formXObjectsCounter;
    return name;
}

int formXObjectsCounter = 4711;

주의 : 방금이 메서드를 작성하고 (원래 병합 코드에서 가능한 한 많이 복사) 예제 파일로만 테스트했습니다. 일부 국경 조건은 일반 용도로 여전히 고려해야 할 수 있습니다. 특히 나는 모든 관련 null또는 0테스트를 수행하지 않았습니다 . 또한 적절한 태그 지정을 지원하지 않았습니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

데이터 프레임을 병합 할 때 전후를 비교하여 누락 된 행 찾기

분류에서Dev

@Produces 주석이 누락 된 경우 저지 서비스는 무엇을 반환합니까?

분류에서Dev

Entity Framework-[키리스] 데이터 주석 누락

분류에서Dev

PHP에서 PDF 병합 후 채울 수있는 양식 값 누락

분류에서Dev

for 루프 제어 후 javascript-누락)

분류에서Dev

데이터 프레임 병합 및 누락 된 값 채우기

분류에서Dev

리베이스 후 커밋 누락

분류에서Dev

그놈 설치 후 마우스 누락

분류에서Dev

커밋을 누른 후 소스 트리에서 커밋 주석 편집

분류에서Dev

팬더 타임 스탬프를 Epoc 이후 주 정수로 해석하는 방법

분류에서Dev

설치 프로세스 후 Akeneo 누락 파일

분류에서Dev

데이터 주석, 데이터 프레임 병합

분류에서Dev

주어진 타임 스탬프 이후에 댓글 받기

분류에서Dev

병합 후 한눈에 각주 유지

분류에서Dev

병합 된 NTFS 파티션, "프로그램 파일"디렉토리 누락

분류에서Dev

누락 된 값이있는 데이터 프레임을 좌표로 병합

분류에서Dev

타임 스탬프가 일치하면 두 파일을 구문 분석하고 줄을 병합합니다.

분류에서Dev

병합 후 추적없이 변경 사항이 누락되는 이유는 무엇입니까?

분류에서Dev

jQuery : Enter 키를 누른 후 텍스트 영역의 텍스트를 단락에 어떻게 추가합니까?

분류에서Dev

pheatmap에서 주석 및 색상 누락

분류에서Dev

레일에 부분 주석 / _comment 누락

분류에서Dev

새 프로젝트 생성시 분석 서비스 누락

분류에서Dev

Python Pandas : 연속 누락 된 주중 날짜를 반환하고 데이터 프레임에서 누락 된 날짜 옆에 요금을 할당합니다.

분류에서Dev

For 루프 목록 누락 된 Python 조합

분류에서Dev

타임 스탬프 서버에서 서명 된 PDF 누락 타임 스탬프

분류에서Dev

두 쿼리를 결합한 후 누락 된 값

분류에서Dev

에포크 이후 마이크로 초 형식의 타임 스탬프를 어떻게 구문 분석합니까?

분류에서Dev

Rails 프로젝트 복사 후 템플릿 누락

분류에서Dev

Outlook-새 프로필 후 일정 그룹이 누락 됨

Related 관련 기사

  1. 1

    데이터 프레임을 병합 할 때 전후를 비교하여 누락 된 행 찾기

  2. 2

    @Produces 주석이 누락 된 경우 저지 서비스는 무엇을 반환합니까?

  3. 3

    Entity Framework-[키리스] 데이터 주석 누락

  4. 4

    PHP에서 PDF 병합 후 채울 수있는 양식 값 누락

  5. 5

    for 루프 제어 후 javascript-누락)

  6. 6

    데이터 프레임 병합 및 누락 된 값 채우기

  7. 7

    리베이스 후 커밋 누락

  8. 8

    그놈 설치 후 마우스 누락

  9. 9

    커밋을 누른 후 소스 트리에서 커밋 주석 편집

  10. 10

    팬더 타임 스탬프를 Epoc 이후 주 정수로 해석하는 방법

  11. 11

    설치 프로세스 후 Akeneo 누락 파일

  12. 12

    데이터 주석, 데이터 프레임 병합

  13. 13

    주어진 타임 스탬프 이후에 댓글 받기

  14. 14

    병합 후 한눈에 각주 유지

  15. 15

    병합 된 NTFS 파티션, "프로그램 파일"디렉토리 누락

  16. 16

    누락 된 값이있는 데이터 프레임을 좌표로 병합

  17. 17

    타임 스탬프가 일치하면 두 파일을 구문 분석하고 줄을 병합합니다.

  18. 18

    병합 후 추적없이 변경 사항이 누락되는 이유는 무엇입니까?

  19. 19

    jQuery : Enter 키를 누른 후 텍스트 영역의 텍스트를 단락에 어떻게 추가합니까?

  20. 20

    pheatmap에서 주석 및 색상 누락

  21. 21

    레일에 부분 주석 / _comment 누락

  22. 22

    새 프로젝트 생성시 분석 서비스 누락

  23. 23

    Python Pandas : 연속 누락 된 주중 날짜를 반환하고 데이터 프레임에서 누락 된 날짜 옆에 요금을 할당합니다.

  24. 24

    For 루프 목록 누락 된 Python 조합

  25. 25

    타임 스탬프 서버에서 서명 된 PDF 누락 타임 스탬프

  26. 26

    두 쿼리를 결합한 후 누락 된 값

  27. 27

    에포크 이후 마이크로 초 형식의 타임 스탬프를 어떻게 구문 분석합니까?

  28. 28

    Rails 프로젝트 복사 후 템플릿 누락

  29. 29

    Outlook-새 프로필 후 일정 그룹이 누락 됨

뜨겁다태그

보관