PageRenderTime 32ms CodeModel.GetById 12ms app.highlight 15ms RepoModel.GetById 2ms app.codeStats 0ms

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

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