You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Picture.cs 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using System.Xml.Linq;
  4. using System.IO.Packaging;
  5. namespace Novacode
  6. {
  7. /// <summary>
  8. /// Represents a Picture in this document, a Picture is a customized view of an Image.
  9. /// </summary>
  10. public class Picture: DocXElement
  11. {
  12. private const int EmusInPixel = 9525;
  13. internal Dictionary<PackagePart, PackageRelationship> picture_rels;
  14. internal Image img;
  15. private string id;
  16. private string name;
  17. private string descr;
  18. private int cx, cy;
  19. //private string fileName;
  20. private uint rotation;
  21. private bool hFlip, vFlip;
  22. private object pictureShape;
  23. private XElement xfrm;
  24. private XElement prstGeom;
  25. /// <summary>
  26. /// Remove this Picture from this document.
  27. /// </summary>
  28. public void Remove()
  29. {
  30. Xml.Remove();
  31. }
  32. /// <summary>
  33. /// Wraps an XElement as an Image
  34. /// </summary>
  35. /// <param name="document"></param>
  36. /// <param name="i">The XElement i to wrap</param>
  37. /// <param name="img"></param>
  38. internal Picture(DocX document, XElement i, Image img):base(document, i)
  39. {
  40. picture_rels = new Dictionary<PackagePart, PackageRelationship>();
  41. this.img = img;
  42. this.id =
  43. (
  44. from e in Xml.Descendants()
  45. where e.Name.LocalName.Equals("blip")
  46. select e.Attribute(XName.Get("embed", "http://schemas.openxmlformats.org/officeDocument/2006/relationships")).Value
  47. ).SingleOrDefault();
  48. if (this.id == null)
  49. {
  50. this.id =
  51. (
  52. from e in Xml.Descendants()
  53. where e.Name.LocalName.Equals("imagedata")
  54. select e.Attribute(XName.Get("id", "http://schemas.openxmlformats.org/officeDocument/2006/relationships")).Value
  55. ).SingleOrDefault();
  56. }
  57. this.name =
  58. (
  59. from e in Xml.Descendants()
  60. let a = e.Attribute(XName.Get("name"))
  61. where (a != null)
  62. select a.Value
  63. ).FirstOrDefault();
  64. if (this.name == null)
  65. {
  66. this.name =
  67. (
  68. from e in Xml.Descendants()
  69. let a = e.Attribute(XName.Get("title"))
  70. where (a != null)
  71. select a.Value
  72. ).FirstOrDefault();
  73. }
  74. this.descr =
  75. (
  76. from e in Xml.Descendants()
  77. let a = e.Attribute(XName.Get("descr"))
  78. where (a != null)
  79. select a.Value
  80. ).FirstOrDefault();
  81. this.cx =
  82. (
  83. from e in Xml.Descendants()
  84. let a = e.Attribute(XName.Get("cx"))
  85. where (a != null)
  86. select int.Parse(a.Value)
  87. ).FirstOrDefault();
  88. if (this.cx == 0)
  89. {
  90. XAttribute style =
  91. (
  92. from e in Xml.Descendants()
  93. let a = e.Attribute(XName.Get("style"))
  94. where (a != null)
  95. select a
  96. ).FirstOrDefault();
  97. string fromWidth = style.Value.Substring(style.Value.IndexOf("width:") + 6);
  98. var widthInt = ((double.Parse((fromWidth.Substring(0, fromWidth.IndexOf("pt"))).Replace(".", ","))) / 72.0) * 914400;
  99. cx = System.Convert.ToInt32(widthInt);
  100. }
  101. this.cy =
  102. (
  103. from e in Xml.Descendants()
  104. let a = e.Attribute(XName.Get("cy"))
  105. where (a != null)
  106. select int.Parse(a.Value)
  107. ).FirstOrDefault();
  108. if (this.cy == 0)
  109. {
  110. XAttribute style =
  111. (
  112. from e in Xml.Descendants()
  113. let a = e.Attribute(XName.Get("style"))
  114. where (a != null)
  115. select a
  116. ).FirstOrDefault();
  117. string fromHeight = style.Value.Substring(style.Value.IndexOf("height:") + 7);
  118. var heightInt = ((double.Parse((fromHeight.Substring(0, fromHeight.IndexOf("pt"))).Replace(".", ","))) / 72.0) * 914400;
  119. cy = System.Convert.ToInt32(heightInt);
  120. }
  121. this.xfrm =
  122. (
  123. from d in Xml.Descendants()
  124. where d.Name.LocalName.Equals("xfrm")
  125. select d
  126. ).SingleOrDefault();
  127. this.prstGeom =
  128. (
  129. from d in Xml.Descendants()
  130. where d.Name.LocalName.Equals("prstGeom")
  131. select d
  132. ).SingleOrDefault();
  133. if (xfrm != null)
  134. this.rotation = xfrm.Attribute(XName.Get("rot")) == null ? 0 : uint.Parse(xfrm.Attribute(XName.Get("rot")).Value);
  135. }
  136. private void SetPictureShape(object shape)
  137. {
  138. this.pictureShape = shape;
  139. XAttribute prst = prstGeom.Attribute(XName.Get("prst"));
  140. if (prst == null)
  141. prstGeom.Add(new XAttribute(XName.Get("prst"), "rectangle"));
  142. prstGeom.Attribute(XName.Get("prst")).Value = shape.ToString();
  143. }
  144. /// <summary>
  145. /// Set the shape of this Picture to one in the BasicShapes enumeration.
  146. /// </summary>
  147. /// <param name="shape">A shape from the BasicShapes enumeration.</param>
  148. public void SetPictureShape(BasicShapes shape)
  149. {
  150. SetPictureShape((object)shape);
  151. }
  152. /// <summary>
  153. /// Set the shape of this Picture to one in the RectangleShapes enumeration.
  154. /// </summary>
  155. /// <param name="shape">A shape from the RectangleShapes enumeration.</param>
  156. public void SetPictureShape(RectangleShapes shape)
  157. {
  158. SetPictureShape((object)shape);
  159. }
  160. /// <summary>
  161. /// Set the shape of this Picture to one in the BlockArrowShapes enumeration.
  162. /// </summary>
  163. /// <param name="shape">A shape from the BlockArrowShapes enumeration.</param>
  164. public void SetPictureShape(BlockArrowShapes shape)
  165. {
  166. SetPictureShape((object)shape);
  167. }
  168. /// <summary>
  169. /// Set the shape of this Picture to one in the EquationShapes enumeration.
  170. /// </summary>
  171. /// <param name="shape">A shape from the EquationShapes enumeration.</param>
  172. public void SetPictureShape(EquationShapes shape)
  173. {
  174. SetPictureShape((object)shape);
  175. }
  176. /// <summary>
  177. /// Set the shape of this Picture to one in the FlowchartShapes enumeration.
  178. /// </summary>
  179. /// <param name="shape">A shape from the FlowchartShapes enumeration.</param>
  180. public void SetPictureShape(FlowchartShapes shape)
  181. {
  182. SetPictureShape((object)shape);
  183. }
  184. /// <summary>
  185. /// Set the shape of this Picture to one in the StarAndBannerShapes enumeration.
  186. /// </summary>
  187. /// <param name="shape">A shape from the StarAndBannerShapes enumeration.</param>
  188. public void SetPictureShape(StarAndBannerShapes shape)
  189. {
  190. SetPictureShape((object)shape);
  191. }
  192. /// <summary>
  193. /// Set the shape of this Picture to one in the CalloutShapes enumeration.
  194. /// </summary>
  195. /// <param name="shape">A shape from the CalloutShapes enumeration.</param>
  196. public void SetPictureShape(CalloutShapes shape)
  197. {
  198. SetPictureShape((object)shape);
  199. }
  200. /// <summary>
  201. /// A unique id that identifies an Image embedded in this document.
  202. /// </summary>
  203. public string Id
  204. {
  205. get { return id; }
  206. }
  207. /// <summary>
  208. /// Flip this Picture Horizontally.
  209. /// </summary>
  210. public bool FlipHorizontal
  211. {
  212. get { return hFlip; }
  213. set
  214. {
  215. hFlip = value;
  216. XAttribute flipH = xfrm.Attribute(XName.Get("flipH"));
  217. if (flipH == null)
  218. xfrm.Add(new XAttribute(XName.Get("flipH"), "0"));
  219. xfrm.Attribute(XName.Get("flipH")).Value = hFlip ? "1" : "0";
  220. }
  221. }
  222. /// <summary>
  223. /// Flip this Picture Vertically.
  224. /// </summary>
  225. public bool FlipVertical
  226. {
  227. get { return vFlip; }
  228. set
  229. {
  230. vFlip = value;
  231. XAttribute flipV = xfrm.Attribute(XName.Get("flipV"));
  232. if (flipV == null)
  233. xfrm.Add(new XAttribute(XName.Get("flipV"), "0"));
  234. xfrm.Attribute(XName.Get("flipV")).Value = vFlip ? "1" : "0";
  235. }
  236. }
  237. /// <summary>
  238. /// The rotation in degrees of this image, actual value = value % 360
  239. /// </summary>
  240. public uint Rotation
  241. {
  242. get { return rotation / 60000; }
  243. set
  244. {
  245. rotation = (value % 360) * 60000;
  246. XElement xfrm =
  247. (from d in Xml.Descendants()
  248. where d.Name.LocalName.Equals("xfrm")
  249. select d).Single();
  250. XAttribute rot = xfrm.Attribute(XName.Get("rot"));
  251. if(rot == null)
  252. xfrm.Add(new XAttribute(XName.Get("rot"), 0));
  253. xfrm.Attribute(XName.Get("rot")).Value = rotation.ToString();
  254. }
  255. }
  256. /// <summary>
  257. /// Gets or sets the name of this Image.
  258. /// </summary>
  259. public string Name
  260. {
  261. get { return name; }
  262. set
  263. {
  264. name = value;
  265. foreach (XAttribute a in Xml.Descendants().Attributes(XName.Get("name")))
  266. a.Value = name;
  267. }
  268. }
  269. /// <summary>
  270. /// Gets or sets the description for this Image.
  271. /// </summary>
  272. public string Description
  273. {
  274. get { return descr; }
  275. set
  276. {
  277. descr = value;
  278. foreach (XAttribute a in Xml.Descendants().Attributes(XName.Get("descr")))
  279. a.Value = descr;
  280. }
  281. }
  282. ///<summary>
  283. /// Returns the name of the image file for the picture.
  284. ///</summary>
  285. public string FileName
  286. {
  287. get
  288. {
  289. return img.FileName;
  290. }
  291. }
  292. /// <summary>
  293. /// Get or sets the Width of this Image.
  294. /// </summary>
  295. public int Width
  296. {
  297. get { return cx / EmusInPixel; }
  298. set
  299. {
  300. cx = value * EmusInPixel;
  301. foreach (XAttribute a in Xml.Descendants().Attributes(XName.Get("cx")))
  302. a.Value = (cx).ToString();
  303. }
  304. }
  305. /// <summary>
  306. /// Get or sets the height of this Image.
  307. /// </summary>
  308. public int Height
  309. {
  310. get { return cy / EmusInPixel; }
  311. set
  312. {
  313. cy = value * EmusInPixel;
  314. foreach (XAttribute a in Xml.Descendants().Attributes(XName.Get("cy")))
  315. a.Value = (cy).ToString();
  316. }
  317. }
  318. // refs:
  319. // https://startbigthinksmall.wordpress.com/2010/01/04/points-inches-and-emus-measuring-units-in-office-open-xml/
  320. // http://lcorneliussen.de/raw/dashboards/ooxml/
  321. private const int InchToEmuFactor = 914400;
  322. private const double EmuToInchFactor = 1d / InchToEmuFactor;
  323. /// <summary>
  324. /// Get or sets the Width of this Image (inches).
  325. /// </summary>
  326. public double WidthInches
  327. {
  328. get
  329. {
  330. return Width * EmusInPixel * EmuToInchFactor;
  331. }
  332. set
  333. {
  334. Width = (int)(value * InchToEmuFactor / EmusInPixel);
  335. }
  336. }
  337. /// <summary>
  338. /// Get or sets the Height of this Image (inches).
  339. /// </summary>
  340. public double HeightInches
  341. {
  342. get
  343. {
  344. return Height * EmusInPixel * EmuToInchFactor;
  345. }
  346. set
  347. {
  348. Height = (int)(value * InchToEmuFactor / EmusInPixel);
  349. }
  350. }
  351. //public void Delete()
  352. //{
  353. // // Remove xml
  354. // i.Remove();
  355. // // Rebuild the image collection for this paragraph
  356. // // Requires that every Image have a link to its paragraph
  357. //}
  358. }
  359. }