VectSharp  2.2.1
A light library for C# vector graphics
ImageURIParser.cs
1 /*
2  VectSharp - A light library for C# vector graphics.
3  Copyright (C) 2020 Giorgio Bianchini
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Affero General Public License as
7  published by the Free Software Foundation, version 3.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU Affero General Public License for more details.
13 
14  You should have received a copy of the GNU Affero General Public License
15  along with this program. If not, see <http://www.gnu.org/licenses/>
16 */
17 
18 using MuPDFCore;
19 using System;
20 using System.IO;
21 using System.Linq;
22 using System.Runtime.InteropServices;
23 
25 {
26  /// <summary>
27  /// Provides a method to parse an image URI into a page.
28  /// </summary>
29  public static class ImageURIParser
30  {
31  /// <summary>
32  /// Parses an image URI into a page. This is intended to replace the default image URI interpreter in <c>VectSharp.SVG.Parser.ParseImageURI</c>. To do this, use something like:
33  /// <code>VectSharp.SVG.Parser.ParseImageURI = VectSharp.MuPDFUtils.ImageURIParser.Parser(VectSharp.SVG.Parser.ParseSVGURI);</code>
34  /// </summary>
35  /// <param name="parseSVG">A function to parse an SVG image uri into a page. You should pass <c>VectSharp.SVG.Parser.ParseSVGURI</c> as this argument.</param>
36  /// <returns>A function to parse an image URI into a page.</returns>
37  public static Func<string, bool, Page> Parser(Func<string, bool, Page> parseSVG)
38  {
39  return (string uri, bool interpolate) =>
40  {
41  if (uri.StartsWith("data:"))
42  {
43  string mimeType = uri.Substring(uri.IndexOf(":") + 1, uri.IndexOf(";") - uri.IndexOf(":") - 1);
44 
45  string type = uri.Substring(uri.IndexOf(";") + 1, uri.IndexOf(",") - uri.IndexOf(";") - 1);
46 
47  if (mimeType != "image/svg+xml")
48  {
49  int offset = uri.IndexOf(",") + 1;
50 
51  byte[] parsed;
52 
53  bool isVector = false;
54 
55  InputFileTypes fileType;
56 
57  switch (mimeType)
58  {
59  case "image/png":
60  fileType = InputFileTypes.PNG;
61  break;
62  case "image/jpeg":
63  case "image/jpg":
64  fileType = InputFileTypes.JPEG;
65  break;
66  case "image/gif":
67  fileType = InputFileTypes.GIF;
68  break;
69  case "image/bmp":
70  fileType = InputFileTypes.BMP;
71  break;
72  case "image/tiff":
73  case "image/tif":
74  fileType = InputFileTypes.TIFF;
75  break;
76  case "application/oxps":
77  case "application/vnd.ms-xpsdocument":
78  fileType = InputFileTypes.XPS;
79  isVector = true;
80  break;
81  case "application/x-cbz":
82  fileType = InputFileTypes.CBZ;
83  break;
84  case "application/epub+zip":
85  fileType = InputFileTypes.EPUB;
86  isVector = true;
87  break;
88  case "text/fb2+xml":
89  fileType = InputFileTypes.FB2;
90  break;
91  case "image/x-portable-anymap":
92  fileType = InputFileTypes.PNM;
93  break;
94  case "image/x-portable-arbitrarymap":
95  fileType = InputFileTypes.PAM;
96  break;
97  case "application/pdf":
98  fileType = InputFileTypes.PDF;
99  isVector = true;
100  break;
101  default:
102  fileType = InputFileTypes.PDF;
103  break;
104  }
105 
106  string substring = uri.Substring(offset);
107 
108 
109  switch (type)
110  {
111  case "base64":
112  parsed = Convert.FromBase64String(uri.Substring(offset));
113  break;
114  case "":
115  parsed = (from el in System.Web.HttpUtility.UrlDecode(uri.Substring(offset)) select (byte)el).ToArray();
116  break;
117  default:
118  throw new InvalidDataException("Unknown data stream type!");
119  }
120 
121  if (!isVector)
122  {
123  GCHandle handle = GCHandle.Alloc(parsed, GCHandleType.Pinned);
124 
125  RasterImageStream img = new RasterImageStream(handle.AddrOfPinnedObject(), parsed.Length, fileType, interpolate: interpolate);
126 
127  handle.Free();
128 
129  Page pag = new Page(img.Width, img.Height);
130 
131  pag.Graphics.DrawRasterImage(0, 0, img);
132 
133  return pag;
134  }
135  else
136  {
137  string tempFile = Path.GetTempFileName();
138 
139  using (MuPDFContext context = new MuPDFContext())
140  {
141  using (MuPDFDocument document = new MuPDFDocument(context, parsed, fileType))
142  {
143  MuPDFDocument.CreateDocument(context, tempFile, DocumentOutputFileTypes.SVG, true, document.Pages[0]);
144  }
145  }
146 
147  string tbr = "data:image/svg+xml;," + System.Web.HttpUtility.UrlEncode(File.ReadAllText(tempFile));
148 
149  File.Delete(tempFile);
150 
151  return parseSVG(tbr, interpolate);
152  }
153  }
154  else
155  {
156  return parseSVG(uri, interpolate);
157  }
158  }
159 
160  return null;
161  };
162  }
163  }
164 }
VectSharp.MuPDFUtils
Definition: ImageURIParser.cs:25
VectSharp.MuPDFUtils.ImageURIParser
Provides a method to parse an image URI into a page.
Definition: ImageURIParser.cs:30
VectSharp.Graphics.DrawRasterImage
void DrawRasterImage(int sourceX, int sourceY, int sourceWidth, int sourceHeight, double destinationX, double destinationY, double destinationWidth, double destinationHeight, RasterImage image, string tag=null)
Draw a raster image.
Definition: Graphics.cs:467
VectSharp.Page
Represents a Graphics object with a width and height.
Definition: Document.cs:48
VectSharp.RasterImage.Width
int Width
The width in pixels of the image.
Definition: RasterImage.cs:123
VectSharp.MuPDFUtils.RasterImageStream
A RasterImage created from a stream.
Definition: RasterImages.cs:70
VectSharp.Page.Graphics
Graphics Graphics
Graphics surface of the page.
Definition: Document.cs:62
VectSharp.MuPDFUtils.ImageURIParser.Parser
static Func< string, bool, Page > Parser(Func< string, bool, Page > parseSVG)
Parses an image URI into a page. This is intended to replace the default image URI interpreter in Vec...
Definition: ImageURIParser.cs:37
VectSharp.RasterImage.Height
int Height
The height in pixels of the image.
Definition: RasterImage.cs:128