MultiImageObject.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. using FastReport;
  2. using FastReport.Utils;
  3. using InABox.Core;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.ComponentModel;
  7. using System.Linq;
  8. using System.Drawing;
  9. namespace InABox.Wpf.Reports.CustomObjects
  10. {
  11. public class MultiImageObject : MultiItemObject
  12. {
  13. private List<byte[]>? imageData { get; set; }
  14. [Category("Data")]
  15. public string? DataColumn { get; set; }
  16. [Category("Data")]
  17. public List<Image>? Images { get; set; }
  18. public override void GetData()
  19. {
  20. base.GetData();
  21. if (!string.IsNullOrEmpty(DataColumn))
  22. {
  23. // reset the image
  24. Images = null;
  25. imageData = null;
  26. object data = Report.GetColumnValueNullable(DataColumn);
  27. if (data is List<byte[]> list)
  28. {
  29. SetImageData(list);
  30. }
  31. else if (data is IEnumerable<byte[]> enumerable)
  32. {
  33. SetImageData(enumerable);
  34. }
  35. }
  36. }
  37. private void SetImageData(IEnumerable<byte[]> imageData)
  38. {
  39. this.imageData = imageData.ToList();
  40. }
  41. private void SetImageData(List<byte[]> imageData)
  42. {
  43. this.imageData = imageData.ToList();
  44. }
  45. private class ImageItem : Item
  46. {
  47. public Image Image;
  48. public float Width => Image.Width;
  49. public float Height => Image.Height;
  50. public ImageItem(Image image)
  51. {
  52. Image = image;
  53. }
  54. }
  55. #region Serialization
  56. public override void Serialize(FRWriter writer)
  57. {
  58. base.Serialize(writer);
  59. if(writer.DiffObject is MultiImageObject c)
  60. {
  61. if (DataColumn != c.DataColumn)
  62. writer.WriteValue("DataColumn", DataColumn);
  63. if (writer.SerializeTo != SerializeTo.SourcePages)
  64. {
  65. if (writer.SerializeTo == SerializeTo.Preview || String.IsNullOrEmpty(DataColumn))
  66. {
  67. if (Images == null && imageData != null)
  68. writer.WriteStr("Images", Serialization.Serialize(imageData));
  69. else if (!writer.AreEqual(Images, c.Images))
  70. writer.WriteValue("Images", Images);
  71. }
  72. }
  73. }
  74. }
  75. public override void Deserialize(FRReader reader)
  76. {
  77. base.Deserialize(reader);
  78. if (reader.HasProperty("Images"))
  79. {
  80. SetImageData(Serialization.Deserialize<List<byte[]>>(reader.ReadStr("Images")));
  81. }
  82. }
  83. #endregion
  84. public override void Assign(Base source)
  85. {
  86. base.Assign(source);
  87. if (source is MultiImageObject src)
  88. {
  89. DataColumn = src.DataColumn;
  90. Images = src.Images == null ? null : src.Images.Select(x => x.Clone() as Image).ToList();
  91. if(src.Images == null && src.imageData != null)
  92. {
  93. imageData = src.imageData;
  94. }
  95. }
  96. }
  97. #region Drawing
  98. public static Image? Load(byte[] bytes)
  99. {
  100. if (bytes != null && bytes.Length > 0)
  101. {
  102. try
  103. {
  104. #if CROSSPLATFORM
  105. // TODO memory leaks image converter
  106. return Image.FromStream(new MemoryStream(bytes));
  107. #else
  108. return new ImageConverter().ConvertFrom(bytes) as Image;
  109. #endif
  110. }
  111. catch
  112. {
  113. Bitmap errorBmp = new Bitmap(10, 10);
  114. using (Graphics g = Graphics.FromImage(errorBmp))
  115. {
  116. g.DrawLine(Pens.Red, 0, 0, 10, 10);
  117. g.DrawLine(Pens.Red, 0, 10, 10, 0);
  118. }
  119. return errorBmp;
  120. }
  121. }
  122. return null;
  123. }
  124. private void LoadImages()
  125. {
  126. if (imageData == null) return;
  127. Images = new();
  128. for(int i = 0; i < imageData.Count; i++) {
  129. var saveImageData = imageData[i];
  130. // FImageData will be reset after this line, keep it
  131. var newImage = Load(imageData[i]);
  132. if(newImage != null)
  133. {
  134. Images.Add(newImage);
  135. }
  136. imageData[i] = saveImageData;
  137. }
  138. }
  139. protected override void DrawItem(FRPaintEventArgs e, Item item, float x, float y, float w, float h)
  140. {
  141. if(item is ImageItem image)
  142. {
  143. e.Graphics.DrawImage(image.Image, x * e.ScaleX, y * e.ScaleY, w * e.ScaleX, h * e.ScaleY);
  144. }
  145. }
  146. protected override IList<Item>? LoadItems()
  147. {
  148. if (Images == null)
  149. {
  150. LoadImages();
  151. }
  152. if (Images == null)
  153. {
  154. return null;
  155. }
  156. return Images.Select(x => new ImageItem(x) as Item).ToList();
  157. }
  158. #endregion
  159. }
  160. }