2023-11-17 13:46:38 +01:00

193 lines
5.4 KiB
C#

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using DigitalData.Modules.Base;
using DigitalData.Modules.Logging;
using GdPicture14;
using Newtonsoft.Json;
namespace EnvelopeGenerator.Web.Classes
{
public partial class PDFBurner : BaseClass
{
private readonly string LicenseKey;
private readonly AnnotationManager Manager;
private readonly LicenseManager LicenseManager;
private const string ANNOTATION_TYPE_IMAGE = "pspdfkit/image";
private const string ANNOTATION_TYPE_INK = "pspdfkit/ink";
public PDFBurner(LogConfig pLogConfig, string pGDPictureLicenseKey) : base(pLogConfig)
{
LicenseKey = pGDPictureLicenseKey;
LicenseManager = new LicenseManager();
LicenseManager.RegisterKEY(pGDPictureLicenseKey);
Manager = new AnnotationManager();
}
public bool BurnInstantJSONAnnotationsToPDF(string pSourcePath, List<string> pInstantJSONList, string pDestinationPath)
{
if (Manager.InitFromFile(pSourcePath) != GdPictureStatus.OK)
{
Logger.Warn("Could not open file [{0}] for burning.", pSourcePath);
return false;
}
foreach (var oJSON in pInstantJSONList)
{
if (AddInstantJSONAnnotationToPDF(oJSON) == false)
{
Logger.Warn("Adding Annotation failed. Exiting");
return false;
}
}
try
{
Manager.BurnAnnotationsToPage(RemoveInitialAnnots: true, VectorMode: true);
Manager.SaveDocumentToPDF(pDestinationPath);
Manager.Close();
return true;
}
catch (Exception ex)
{
Logger.Warn("Could not burn and save annotations to file [{0}]!", pDestinationPath);
Logger.Error(ex);
return false;
}
}
private bool AddInstantJSONAnnotationToPDF(string pInstantJSON)
{
try
{
var oAnnotationData = JsonConvert.DeserializeObject<AnnotationData>(pInstantJSON);
foreach (Annotation oAnnotation in oAnnotationData.annotations)
{
switch (oAnnotation.type)
{
case ANNOTATION_TYPE_IMAGE:
{
AddImageAnnotation(oAnnotation, oAnnotationData.attachments);
break;
}
case ANNOTATION_TYPE_INK:
{
AddInkAnnotation(oAnnotation);
break;
}
}
}
return true;
}
catch (Exception ex)
{
Logger.Warn("Could not create annotation from InstantJSON");
Logger.Error(ex);
return false;
}
}
private bool AddImageAnnotation(Annotation pAnnotation, Dictionary<string, Attachment> pAttachments)
{
try
{
var oAttachment = pAttachments.Where(a => (a.Key ?? "") == (pAnnotation.imageAttachmentId ?? "")).SingleOrDefault();
// Convert pixels to Inches
var oBounds = pAnnotation.bbox.Select(ToInches).ToList();
float oX = oBounds[0];
float oY = oBounds[1];
float oWidth = oBounds[2];
float oHeight = oBounds[3];
Manager.AddEmbeddedImageAnnotFromBase64(oAttachment.Value.binary, oX, oY, oWidth, oHeight);
return true;
}
catch (Exception ex)
{
Logger.Warn("Could not add image annotation!");
Logger.Error(ex);
return false;
}
}
private bool AddInkAnnotation(Annotation pAnnotation)
{
try
{
var oSegments = pAnnotation.lines.points;
var oColor = ColorTranslator.FromHtml(pAnnotation.strokeColor);
Manager.SelectPage(pAnnotation.pageIndex);
foreach (List<List<float>> oSegment in oSegments)
{
var oPoints = oSegment.Select(ToPointF).ToArray();
Manager.AddFreeHandAnnot(oColor, oPoints);
}
return true;
}
catch (Exception ex)
{
Logger.Warn("Could not add image annotation!");
Logger.Error(ex);
return false;
}
}
private PointF ToPointF(List<float> pPoints)
{
var oPoints = pPoints.Select(ToInches).ToList();
return new PointF(oPoints[0], oPoints[1]);
}
private float ToInches(float pValue)
{
return pValue / 72f;
}
internal partial class AnnotationData
{
public List<Annotation> annotations { get; set; }
public Dictionary<string, Attachment> attachments { get; set; }
}
internal partial class Annotation
{
public string id { get; set; }
public List<float> bbox { get; set; }
public string type { get; set; }
public bool isSignature { get; set; }
public string imageAttachmentId { get; set; }
public Lines lines { get; set; }
public int pageIndex { get; set; }
public string strokeColor { get; set; }
}
internal partial class Lines
{
public List<List<List<float>>> points { get; set; }
}
internal partial class Attachment
{
public string binary { get; set; }
public string contentType { get; set; }
}
}
}