Free cookie consent management tool by TermsFeed Policy Generator

source: branches/Async/HeuristicLab.ExtLibs/HeuristicLab.EPPlus/4.0.3/EPPlus-4.0.3/Drawing/ExcelPicture.cs @ 13401

Last change on this file since 13401 was 12074, checked in by sraggl, 10 years ago

#2341: Added EPPlus-4.0.3 to ExtLibs

File size: 15.9 KB
Line 
1/*******************************************************************************
2 * You may amend and distribute as you like, but don't remove this header!
3 *
4 * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.
5 * See http://www.codeplex.com/EPPlus for details.
6 *
7 * Copyright (C) 2011  Jan Källman
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
17 * See the GNU Lesser General Public License for more details.
18 *
19 * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php
20 * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html
21 *
22 * All code and executables are provided "as is" with no warranty either express or implied.
23 * The author accepts no liability for any damage or loss of business that this product may cause.
24 *
25 * Code change notes:
26 *
27 * Author             Change            Date
28 * ******************************************************************************
29 * Jan Källman                    Initial Release           2009-10-01
30 * Jan Källman    License changed GPL-->LGPL 2011-12-16
31 *******************************************************************************/
32using System;
33using System.Collections.Generic;
34using System.Globalization;
35using System.Text;
36using System.Xml;
37using System.IO;
38using System.Drawing;
39using System.Drawing.Imaging;
40using System.Diagnostics;
41using OfficeOpenXml.Utils;
42
43namespace OfficeOpenXml.Drawing
44{
45    /// <summary>
46    /// An image object
47    /// </summary>
48    public sealed class ExcelPicture : ExcelDrawing
49    {
50        #region "Constructors"
51        internal ExcelPicture(ExcelDrawings drawings, XmlNode node) :
52            base(drawings, node, "xdr:pic/xdr:nvPicPr/xdr:cNvPr/@name")
53        {
54            XmlNode picNode = node.SelectSingleNode("xdr:pic/xdr:blipFill/a:blip", drawings.NameSpaceManager);
55            if (picNode != null)
56            {
57                RelPic = drawings.Part.GetRelationship(picNode.Attributes["r:embed"].Value);
58                UriPic = UriHelper.ResolvePartUri(drawings.UriDrawing, RelPic.TargetUri);
59
60                Part = drawings.Part.Package.GetPart(UriPic);
61                FileInfo f = new FileInfo(UriPic.OriginalString);
62                ContentType = GetContentType(f.Extension);
63                _image = Image.FromStream(Part.GetStream());
64                ImageConverter ic=new ImageConverter();
65                var iby=(byte[])ic.ConvertTo(_image, typeof(byte[]));
66                var ii = _drawings._package.LoadImage(iby, UriPic, Part);
67                ImageHash = ii.Hash;
68
69                string relID = GetXmlNodeString("xdr:pic/xdr:nvPicPr/xdr:cNvPr/a:hlinkClick/@r:id");
70                if (!string.IsNullOrEmpty(relID))
71                {
72                    HypRel = drawings.Part.GetRelationship(relID);
73                    if (HypRel.TargetUri.IsAbsoluteUri)
74                    {
75                        _hyperlink = new ExcelHyperLink(HypRel.TargetUri.AbsoluteUri);
76                    }
77                    else
78                    {
79                        _hyperlink = new ExcelHyperLink(HypRel.TargetUri.OriginalString, UriKind.Relative);
80                    }
81                    ((ExcelHyperLink)_hyperlink).ToolTip = GetXmlNodeString("xdr:pic/xdr:nvPicPr/xdr:cNvPr/a:hlinkClick/@tooltip");
82                }
83            }
84        }
85        internal ExcelPicture(ExcelDrawings drawings, XmlNode node, Image image) :
86           this(drawings, node, image, null)
87        {
88        }
89        internal ExcelPicture(ExcelDrawings drawings, XmlNode node, Image image, Uri hyperlink) :
90            base(drawings, node, "xdr:pic/xdr:nvPicPr/xdr:cNvPr/@name")
91        {
92            XmlElement picNode = node.OwnerDocument.CreateElement("xdr", "pic", ExcelPackage.schemaSheetDrawings);
93            node.InsertAfter(picNode,node.SelectSingleNode("xdr:to",NameSpaceManager));
94            _hyperlink = hyperlink;
95            picNode.InnerXml = PicStartXml();
96
97            node.InsertAfter(node.OwnerDocument.CreateElement("xdr", "clientData", ExcelPackage.schemaSheetDrawings), picNode);
98
99            var package = drawings.Worksheet._package.Package;
100            //Get the picture if it exists or save it if not.
101            _image = image;
102            string relID = SavePicture(image);
103
104            //Create relationship
105            node.SelectSingleNode("xdr:pic/xdr:blipFill/a:blip/@r:embed", NameSpaceManager).Value = relID;
106
107            SetPosDefaults(image);
108            package.Flush();
109        }
110        internal ExcelPicture(ExcelDrawings drawings, XmlNode node, FileInfo imageFile) :
111           this(drawings,node,imageFile,null)
112        {
113        }
114        internal ExcelPicture(ExcelDrawings drawings, XmlNode node, FileInfo imageFile, Uri hyperlink) :
115            base(drawings, node, "xdr:pic/xdr:nvPicPr/xdr:cNvPr/@name")
116        {
117            XmlElement picNode = node.OwnerDocument.CreateElement("xdr", "pic", ExcelPackage.schemaSheetDrawings);
118            node.InsertAfter(picNode, node.SelectSingleNode("xdr:to", NameSpaceManager));
119            _hyperlink = hyperlink;
120            picNode.InnerXml = PicStartXml();
121
122            node.InsertAfter(node.OwnerDocument.CreateElement("xdr", "clientData", ExcelPackage.schemaSheetDrawings), picNode);
123
124            //Changed to stream 2/4-13 (issue 14834). Thnx SClause
125            var package = drawings.Worksheet._package.Package;
126            ContentType = GetContentType(imageFile.Extension);
127            var imagestream = new FileStream(imageFile.FullName, FileMode.Open, FileAccess.Read);
128            _image = Image.FromStream(imagestream);
129            ImageConverter ic = new ImageConverter();
130            var img = (byte[])ic.ConvertTo(_image, typeof(byte[]));
131            imagestream.Close();
132
133            UriPic = GetNewUri(package, "/xl/media/{0}" + imageFile.Name);
134            var ii = _drawings._package.AddImage(img, UriPic, ContentType);
135            string relID;
136            if(!drawings._hashes.ContainsKey(ii.Hash))
137            {
138                Part = ii.Part;
139                RelPic = drawings.Part.CreateRelationship(UriHelper.GetRelativeUri(drawings.UriDrawing, ii.Uri), Packaging.TargetMode.Internal, ExcelPackage.schemaRelationships + "/image");
140                relID = RelPic.Id;
141                _drawings._hashes.Add(ii.Hash, relID);
142                AddNewPicture(img, relID);
143            }
144            else
145            {
146                relID = drawings._hashes[ii.Hash];
147                var rel = _drawings.Part.GetRelationship(relID);
148                UriPic = UriHelper.ResolvePartUri(rel.SourceUri, rel.TargetUri);
149            }
150            SetPosDefaults(Image);
151            //Create relationship
152            node.SelectSingleNode("xdr:pic/xdr:blipFill/a:blip/@r:embed", NameSpaceManager).Value = relID;
153            package.Flush();
154        }
155
156        internal static string GetContentType(string extension)
157        {
158            switch (extension.ToLower(CultureInfo.InvariantCulture))
159            {
160                case ".bmp":
161                    return  "image/bmp";
162                case ".jpg":
163                case ".jpeg":
164                    return "image/jpeg";
165                case ".gif":
166                    return "image/gif";
167                case ".png":
168                    return "image/png";
169                case ".cgm":
170                    return "image/cgm";
171                case ".emf":
172                    return "image/x-emf";
173                case ".eps":
174                    return "image/x-eps";
175                case ".pcx":
176                    return "image/x-pcx";
177                case ".tga":
178                    return "image/x-tga";
179                case ".tif":
180                case ".tiff":
181                    return "image/x-tiff";
182                case ".wmf":
183                    return "image/x-wmf";
184                default:
185                    return "image/jpeg";
186
187            }
188        }
189        //Add a new image to the compare collection
190        private void AddNewPicture(byte[] img, string relID)
191        {
192            var newPic = new ExcelDrawings.ImageCompare();
193            newPic.image = img;
194            newPic.relID = relID;
195            //_drawings._pics.Add(newPic);
196        }
197        #endregion
198        private string SavePicture(Image image)
199        {
200            ImageConverter ic = new ImageConverter();
201            byte[] img = (byte[])ic.ConvertTo(image, typeof(byte[]));
202            var ii = _drawings._package.AddImage(img);
203
204            if (_drawings._hashes.ContainsKey(ii.Hash))
205            {
206                var relID = _drawings._hashes[ii.Hash];
207                var rel = _drawings.Part.GetRelationship(relID);
208                UriPic = UriHelper.ResolvePartUri(rel.SourceUri, rel.TargetUri);
209                return relID;
210            }
211            else
212            {
213                UriPic = ii.Uri;
214            }
215
216            //Set the Image and save it to the package.
217            RelPic = _drawings.Part.CreateRelationship(UriHelper.GetRelativeUri(_drawings.UriDrawing, UriPic), Packaging.TargetMode.Internal, ExcelPackage.schemaRelationships + "/image");
218           
219            //AddNewPicture(img, picRelation.Id);
220            _drawings._hashes.Add(ii.Hash, RelPic.Id);
221            ImageHash = ii.Hash;
222
223            return RelPic.Id;
224        }
225        private void SetPosDefaults(Image image)
226        {
227            EditAs = eEditAs.OneCell;
228            SetPixelWidth(image.Width, image.HorizontalResolution);
229            SetPixelHeight(image.Height, image.VerticalResolution);
230        }
231
232        private string PicStartXml()
233        {
234            StringBuilder xml = new StringBuilder();
235           
236            xml.Append("<xdr:nvPicPr>");
237           
238            if (_hyperlink == null)
239            {
240                xml.AppendFormat("<xdr:cNvPr id=\"{0}\" descr=\"\" />", _id);
241            }
242            else
243            {
244               HypRel = _drawings.Part.CreateRelationship(_hyperlink, Packaging.TargetMode.External, ExcelPackage.schemaHyperlink);
245               xml.AppendFormat("<xdr:cNvPr id=\"{0}\" descr=\"\">", _id);
246               if (HypRel != null)
247               {
248                   if (_hyperlink is ExcelHyperLink)
249                   {
250                       xml.AppendFormat("<a:hlinkClick xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" r:id=\"{0}\" tooltip=\"{1}\"/>",
251                         HypRel.Id, ((ExcelHyperLink)_hyperlink).ToolTip);
252                   }
253                   else
254                   {
255                       xml.AppendFormat("<a:hlinkClick xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" r:id=\"{0}\" />",
256                         HypRel.Id);
257                   }
258               }
259               xml.Append("</xdr:cNvPr>");
260            }
261           
262            xml.Append("<xdr:cNvPicPr><a:picLocks noChangeAspect=\"1\" /></xdr:cNvPicPr></xdr:nvPicPr><xdr:blipFill><a:blip xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" r:embed=\"\" cstate=\"print\" /><a:stretch><a:fillRect /> </a:stretch> </xdr:blipFill> <xdr:spPr> <a:xfrm> <a:off x=\"0\" y=\"0\" />  <a:ext cx=\"0\" cy=\"0\" /> </a:xfrm> <a:prstGeom prst=\"rect\"> <a:avLst /> </a:prstGeom> </xdr:spPr>");
263
264            return xml.ToString();
265        }
266
267        internal string ImageHash { get; set; }
268        Image _image = null;
269        /// <summary>
270        /// The Image
271        /// </summary>
272        public Image Image
273        {
274            get
275            {
276                return _image;
277            }
278            set
279            {
280                if (value != null)
281                {
282                    _image = value;
283                    try
284                    {
285                        string relID = SavePicture(value);
286
287                        //Create relationship
288                        TopNode.SelectSingleNode("xdr:pic/xdr:blipFill/a:blip/@r:embed", NameSpaceManager).Value = relID;
289                        //_image.Save(Part.GetStream(FileMode.Create, FileAccess.Write), _imageFormat);   //Always JPEG here at this point.
290                    }
291                    catch(Exception ex)
292                    {
293                        throw(new Exception("Can't save image - " + ex.Message, ex));
294                    }
295                }
296            }
297        }
298        ImageFormat _imageFormat=ImageFormat.Jpeg;
299        /// <summary>
300        /// Image format
301        /// If the picture is created from an Image this type is always Jpeg
302        /// </summary>
303        public ImageFormat ImageFormat
304        {
305            get
306            {
307                return _imageFormat;
308            }
309            internal set
310            {
311                _imageFormat = value;
312            }
313        }
314        internal string ContentType
315        {
316            get;
317            set;
318        }
319        /// <summary>
320        /// Set the size of the image in percent from the orginal size
321        /// Note that resizing columns / rows after using this function will effect the size of the picture
322        /// </summary>
323        /// <param name="Percent">Percent</param>
324        public override void SetSize(int Percent)
325        {
326            if(Image == null)
327            {
328                base.SetSize(Percent);
329            }
330            else
331            {
332                int width = Image.Width;
333                int height = Image.Height;
334
335                width = (int)(width * ((decimal)Percent / 100));
336                height = (int)(height * ((decimal)Percent / 100));
337
338                SetPixelWidth(width, Image.HorizontalResolution);
339                SetPixelHeight(height, Image.VerticalResolution);
340            }
341        }
342        internal Uri UriPic { get; set; }
343        internal Packaging.ZipPackageRelationship RelPic {get; set;}
344        internal Packaging.ZipPackageRelationship HypRel { get; set; }
345        internal Packaging.ZipPackagePart Part;
346
347        internal new string Id
348        {
349            get { return Name; }
350        }
351        ExcelDrawingFill _fill = null;
352        /// <summary>
353        /// Fill
354        /// </summary>
355        public ExcelDrawingFill Fill
356        {
357            get
358            {
359                if (_fill == null)
360                {
361                    _fill = new ExcelDrawingFill(NameSpaceManager, TopNode, "xdr:pic/xdr:spPr");
362                }
363                return _fill;
364            }
365        }
366        ExcelDrawingBorder _border = null;
367        /// <summary>
368        /// Border
369        /// </summary>
370        public ExcelDrawingBorder Border
371        {
372            get
373            {
374                if (_border == null)
375                {
376                    _border = new ExcelDrawingBorder(NameSpaceManager, TopNode, "xdr:pic/xdr:spPr/a:ln");
377                }
378                return _border;
379            }
380        }
381
382        private Uri _hyperlink = null;
383        /// <summary>
384        /// Hyperlink
385        /// </summary>
386        public Uri Hyperlink
387        {
388           get
389           {
390              return _hyperlink;
391           }
392        }
393        internal override void DeleteMe()
394        {
395            _drawings._package.RemoveImage(ImageHash);
396            base.DeleteMe();
397        }
398        public override void Dispose()
399        {
400            base.Dispose();
401            _hyperlink = null;
402            _image.Dispose();
403            _image = null;           
404        }
405    }
406}
Note: See TracBrowser for help on using the repository browser.