PDFRenderer.iOS.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. using InABox.Core;
  2. namespace InABox.Avalonia.Platform.iOS;
  3. public class iOS_PdfRenderer : IPdfRenderer
  4. {
  5. public Logger? Logger { get; set; }
  6. private byte[] PdfDocToImage(CGPDFDocument document, int pageIndex, int dpi)
  7. {
  8. float scale = 2F;
  9. using var page = document.GetPage(pageIndex + 1); // Pages are 1-indexed
  10. var pageRect = page.GetBoxRect(CGPDFBox.Media);
  11. var scaledSize = new CGSize(pageRect.Width * scale, pageRect.Height * scale);
  12. // Step 2: Render the page to an image
  13. UIGraphics.BeginImageContextWithOptions(scaledSize, false, 1.0f);
  14. using (var context = UIGraphics.GetCurrentContext())
  15. {
  16. context.SaveState();
  17. context.TranslateCTM(0, scaledSize.Height);
  18. context.ScaleCTM(scale, -scale); // Flip and scale
  19. context.DrawPDFPage(page);
  20. context.RestoreState();
  21. }
  22. using var image = UIGraphics.GetImageFromCurrentImageContext();
  23. UIGraphics.EndImageContext();
  24. // Step 3: Convert UIImage to PNG byte array
  25. using var pngData = image.AsPNG();
  26. return pngData.ToArray();
  27. }
  28. public byte[]? PdfToImage(byte[]? pdf, int pageIndex, int dpi)
  29. {
  30. if (pdf is null || pdf.Length == 0)
  31. return null;
  32. // Step 1: Load the PDF document from byte array
  33. using var data = NSData.FromArray(pdf);
  34. using var provider = new CGDataProvider(data);
  35. using var pdfDoc = new CGPDFDocument(provider);
  36. // Validate page index
  37. int pageCount = (int)pdfDoc.Pages;
  38. if (pageIndex < 0 || pageIndex >= pageCount)
  39. throw new ArgumentOutOfRangeException(nameof(pageIndex), "Invalid PDF page index.");
  40. return PdfDocToImage(pdfDoc, pageIndex, dpi);
  41. }
  42. public byte[][]? PdfToImages(byte[]? pdf, int dpi)
  43. {
  44. if (pdf is null || pdf.Length == 0)
  45. return null;
  46. float scale = 2F;
  47. // Step 1: Load the PDF document from byte array
  48. using var data = NSData.FromArray(pdf);
  49. using var provider = new CGDataProvider(data);
  50. using var pdfDoc = new CGPDFDocument(provider);
  51. // Validate page index
  52. int pageCount = (int)pdfDoc.Pages;
  53. return Enumerable.Range(0, pageCount).Select(pageIndex =>
  54. {
  55. return PdfDocToImage(pdfDoc, pageIndex, dpi);
  56. }).ToArray();
  57. }
  58. public int? PdfPageCount(byte[]? pdf)
  59. {
  60. if (pdf is null || pdf.Length == 0)
  61. return null;
  62. // Step 1: Load the PDF document from byte array
  63. using var data = NSData.FromArray(pdf);
  64. using var provider = new CGDataProvider(data);
  65. using var pdfDoc = new CGPDFDocument(provider);
  66. return (int)pdfDoc.Pages;
  67. }
  68. public Task<byte[]?> PdfToImageAsync(byte[]? pdf, int page, int dpi)
  69. {
  70. var tcs = new TaskCompletionSource<byte[]?>();
  71. UIApplication.SharedApplication.BeginInvokeOnMainThread(() =>
  72. {
  73. try
  74. {
  75. var result = PdfToImage(pdf, page, dpi);
  76. tcs.SetResult(result);
  77. }
  78. catch (Exception ex)
  79. {
  80. tcs.SetException(ex);
  81. }
  82. });
  83. return tcs.Task;
  84. }
  85. public Task<byte[][]?> PdfToImagesAsync(byte[]? pdf, int dpi)
  86. {
  87. var tcs = new TaskCompletionSource<byte[][]?>();
  88. UIApplication.SharedApplication.BeginInvokeOnMainThread(() =>
  89. {
  90. try
  91. {
  92. var result = PdfToImages(pdf, dpi);
  93. tcs.SetResult(result);
  94. }
  95. catch (Exception ex)
  96. {
  97. tcs.SetException(ex);
  98. }
  99. });
  100. return tcs.Task;
  101. }
  102. public Task<int?> PdfPageCountAsync(byte[]? pdf)
  103. {
  104. var tcs = new TaskCompletionSource<int?>();
  105. UIApplication.SharedApplication.BeginInvokeOnMainThread(() =>
  106. {
  107. try
  108. {
  109. var result = PdfPageCount(pdf);
  110. tcs.SetResult(result);
  111. }
  112. catch (Exception ex)
  113. {
  114. tcs.SetException(ex);
  115. }
  116. });
  117. return tcs.Task;
  118. }
  119. public byte[]? ImageToPdf(byte[]? image)
  120. {
  121. return null;
  122. }
  123. public Task<byte[]?> ImageToPdfAsync(byte[]? image)
  124. {
  125. var tcs = new TaskCompletionSource<byte[]?>();
  126. UIApplication.SharedApplication.BeginInvokeOnMainThread(() =>
  127. {
  128. try
  129. {
  130. var result = ImageToPdf(image);
  131. tcs.SetResult(result);
  132. }
  133. catch (Exception ex)
  134. {
  135. tcs.SetException(ex);
  136. }
  137. });
  138. return tcs.Task;
  139. }
  140. }