PageRenderTime 137ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

/BlogEngine/DotNetSlave.BusinessLogic/FileSystem/Image.cs

#
C# | 275 lines | 177 code | 27 blank | 71 comment | 8 complexity | 3e828711510a934abe95d6606329d96a MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0, BSD-3-Clause
  1. using System;
  2. using System.Drawing;
  3. using System.Drawing.Drawing2D;
  4. using System.IO;
  5. using System.Linq;
  6. using BlogEngine.Core.Providers;
  7. using System.Drawing.Imaging;
  8. using System.Reflection;
  9. namespace BlogEngine.Core.FileSystem
  10. {
  11. /// <summary>
  12. /// image specific class, will contain the extra methods and properties of an image
  13. /// </summary>
  14. public partial class Image : File
  15. {
  16. #region Fields , Constants & Enums
  17. /// <summary>
  18. /// the current image bitmap. call the accessor directly
  19. /// </summary>
  20. private Bitmap bitmap;
  21. /// <summary>
  22. /// enum for the file modification methods
  23. /// </summary>
  24. public enum ModificationType
  25. {
  26. FlipHorizontal,
  27. FlipVertical,
  28. RotateLeft,
  29. RotateRight
  30. }
  31. #endregion
  32. #region Ctor
  33. /// <summary>
  34. /// ctor, copys all the properties from the file object into the new object.
  35. /// </summary>
  36. public Image(File obj)
  37. {
  38. if (obj != null)
  39. {
  40. var qry = typeof(File).GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(p => p.CanRead && p.CanWrite);
  41. foreach (var pi in qry)
  42. this.GetType().GetProperty(pi.Name).SetValue(this, pi.GetValue(obj, null), null);
  43. }
  44. if (!this.IsImage)
  45. throw new Exception("File not of an image type");
  46. }
  47. /// <summary>
  48. /// ctor, property free constructor, initiates the this.Image(file) passing in a null file reference
  49. /// </summary>
  50. public Image()
  51. : this(null) { }
  52. #endregion
  53. #region Properties
  54. /// <summary>
  55. /// gets the bitmap of the current image Item
  56. /// </summary>
  57. /// <remarks>
  58. /// set accessor set to internal
  59. /// </remarks>
  60. public Bitmap bitMap
  61. {
  62. get
  63. {
  64. if (this.bitmap == null)
  65. bitMap = ArrayToBmp(this.FileContents);
  66. return this.bitmap;
  67. }
  68. internal set
  69. {
  70. this.bitmap = value;
  71. }
  72. }
  73. /// <summary>
  74. /// gets the full download path to the file, using the file handler
  75. /// </summary>
  76. public string ImageUrl
  77. {
  78. get
  79. {
  80. return string.Format("{0}IMAGES{1}.jpgx", Utils.RelativeWebRoot, this.SafeFilePath);
  81. }
  82. }
  83. #endregion
  84. #region Methods
  85. /// <summary>
  86. /// resizes the image to a new size. The image will be replaced
  87. /// </summary>
  88. /// <param name="newSize">the new Size for the image</param>
  89. /// <returns>the new image</returns>
  90. public Image ResizeImage(Size newSize)
  91. {
  92. this.bitMap = (Bitmap)resizeImage((System.Drawing.Image)this.bitMap, newSize);
  93. var nfile = BlogService.UploadFile(BmpToArray(this.bitMap), this.Name, this.ParentDirectory, true);
  94. this.FileContents = nfile.FileContents;
  95. nfile.Dispose();
  96. return this;
  97. }
  98. public static byte[] ResizeImageThumbnail(int MaxSize, byte[] originalContents)
  99. {
  100. var bmp = ArrayToBmp(originalContents);
  101. bmp = (Bitmap)resizeImage((System.Drawing.Image)bmp, new Size(MaxSize, MaxSize));
  102. originalContents = BmpToArray(bmp);
  103. bmp.Dispose();
  104. return originalContents;
  105. }
  106. /// <summary>
  107. /// resizes the image to a new size based on a percentage
  108. /// </summary>
  109. /// <param name="newSize">the percentage to resize</param>
  110. /// <returns>the new image</returns>
  111. /// <remarks>
  112. /// This may not be exactly to the percent as we must maintain aspect ratios.
  113. /// </remarks>
  114. public Image ResizeImage(decimal Percent)
  115. {
  116. int sizeX = (int)Math.Ceiling((decimal)this.bitMap.Width * (decimal)((decimal)Percent / 100));
  117. int sizeY = (int)Math.Ceiling((decimal)this.bitMap.Height * (decimal)((decimal)Percent / 100));
  118. var newSize = new Size(sizeX, sizeY);
  119. this.bitMap = (Bitmap)resizeImage((System.Drawing.Image)this.bitMap, newSize);
  120. var nfile = BlogService.UploadFile(BmpToArray(this.bitMap), this.Name, this.ParentDirectory, true);
  121. this.FileContents = nfile.FileContents;
  122. nfile.Dispose();
  123. return this;
  124. }
  125. /// <summary>
  126. /// accepts change requests for an image for rotate & flip
  127. /// </summary>
  128. /// <param name="modifications">a list of changes, will be executed in the order recieved</param>
  129. /// <returns>the original image</returns>
  130. public Image ModifyImage(params ModificationType[] modifications)
  131. {
  132. foreach (var change in modifications)
  133. {
  134. switch (change)
  135. {
  136. case ModificationType.RotateLeft:
  137. this.bitMap.RotateFlip(RotateFlipType.Rotate270FlipNone);
  138. break;
  139. case ModificationType.RotateRight:
  140. this.bitMap.RotateFlip(RotateFlipType.Rotate90FlipNone);
  141. break;
  142. case ModificationType.FlipHorizontal:
  143. this.bitMap.RotateFlip(RotateFlipType.RotateNoneFlipX);
  144. break;
  145. case ModificationType.FlipVertical:
  146. this.bitMap.RotateFlip(RotateFlipType.RotateNoneFlipY);
  147. break;
  148. }
  149. }
  150. var nfile = BlogService.UploadFile(BmpToArray(this.bitMap), this.Name, this.ParentDirectory, true);
  151. this.FileContents = nfile.FileContents;
  152. nfile.Dispose();
  153. return this;
  154. }
  155. /// <summary>
  156. /// Crops an image by giving the crop start x & y co-ordinates and then the height & width to crop to. Making a perfect rectangle of the crop area.
  157. /// </summary>
  158. /// <param name="x">the x co-ordinate</param>
  159. /// <param name="y">the y co-ordinate</param>
  160. /// <param name="width">the width to crop</param>
  161. /// <param name="height">the height to crop</param>
  162. /// <returns>the new object, on exception the image will not be modified.</returns>
  163. public Image CropImage(int x, int y, int width, int height)
  164. {
  165. try
  166. {
  167. Rectangle cropArea = new Rectangle(x, y, width, height);
  168. Bitmap target = new Bitmap(cropArea.Width, cropArea.Height);
  169. using (Graphics g = Graphics.FromImage(target))
  170. {
  171. g.DrawImage(this.bitMap, new Rectangle(0, 0, width, height),
  172. new Rectangle(x, y, target.Width, target.Height),
  173. GraphicsUnit.Pixel);
  174. }
  175. //Bitmap bmpCrop = this.bitMap.Clone(cropArea, PixelFormat.DontCare);
  176. //this.bitMap = bmpCrop;
  177. //var nfile = BlogService.UploadFile(BmpToArray(this.bitMap), this.Name, this.ParentDirectory, true);
  178. //this.FileContents = nfile.FileContents;
  179. //nfile.Dispose();
  180. var nfile = BlogService.UploadFile(BmpToArray(target), this.Name, this.ParentDirectory, true);
  181. this.FileContents = nfile.FileContents;
  182. this.bitMap.Dispose();
  183. this.bitMap = null;
  184. return this;
  185. }
  186. catch
  187. {
  188. return this;
  189. }
  190. }
  191. /// <summary>
  192. /// converts a byte array to a bitmap
  193. /// </summary>
  194. /// <param name="inArray">the in array</param>
  195. /// <returns>the new bitmap</returns>
  196. private static Bitmap ArrayToBmp(byte[] inArray)
  197. {
  198. using (MemoryStream ms = new MemoryStream(inArray))
  199. {
  200. Bitmap bmp = (Bitmap)System.Drawing.Image.FromStream(ms);
  201. return bmp;
  202. }
  203. }
  204. /// <summary>
  205. /// converts a bitmap to an array
  206. /// </summary>
  207. /// <param name="bmp">the bitmap to convert</param>
  208. /// <returns>the byte array object</returns>
  209. private static byte[] BmpToArray(Bitmap bmp)
  210. {
  211. MemoryStream ms = new MemoryStream();
  212. bmp.Save(ms, ImageFormat.Jpeg);
  213. byte[] bmpBytes = ms.GetBuffer();
  214. bmp.Dispose();
  215. ms.Close();
  216. return bmpBytes;
  217. }
  218. /// <summary>
  219. /// resizes an image to specific size
  220. /// </summary>
  221. /// <param name="imgToResize">the image to resize</param>
  222. /// <param name="size">the new size</param>
  223. /// <returns>new resized image</returns>
  224. private static System.Drawing.Image resizeImage(System.Drawing.Image imgToResize, Size size)
  225. {
  226. int sourceWidth = imgToResize.Width;
  227. int sourceHeight = imgToResize.Height;
  228. float nPercent = 0;
  229. float nPercentW = 0;
  230. float nPercentH = 0;
  231. nPercentW = ((float)size.Width / (float)sourceWidth);
  232. nPercentH = ((float)size.Height / (float)sourceHeight);
  233. if (nPercentH < nPercentW)
  234. nPercent = nPercentH;
  235. else
  236. nPercent = nPercentW;
  237. int destWidth = (int)(sourceWidth * nPercent);
  238. int destHeight = (int)(sourceHeight * nPercent);
  239. Bitmap b = new Bitmap(destWidth, destHeight);
  240. Graphics g = Graphics.FromImage((System.Drawing.Image)b);
  241. g.InterpolationMode = InterpolationMode.HighQualityBicubic;
  242. g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
  243. g.Dispose();
  244. return (System.Drawing.Image)b;
  245. }
  246. #endregion
  247. }
  248. }