VectSharp  2.2.1
A light library for C# vector graphics
RasterImages.cs
1 /*
2  VectSharp - A light library for C# vector graphics.
3  Copyright (C) 2020-2022 Giorgio Bianchini
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  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 Lesser General Public License for more details.
13 
14  You should have received a copy of the GNU Lesser General Public License
15  along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17 
18 using SixLabors.ImageSharp;
19 using SixLabors.ImageSharp.Advanced;
20 using SixLabors.ImageSharp.Processing;
21 using System;
22 using System.IO;
23 using System.Runtime.InteropServices;
24 
26 {
27  /// <summary>
28  /// A <see cref="RasterImage"/> created from a file.
29  /// </summary>
31  {
32  /// <summary>
33  /// Creates a new <see cref="RasterImage"/> from the specified file.
34  /// </summary>
35  /// <param name="fileName">The path to the file containing the image.</param>
36  /// <param name="alpha">A boolean value indicating whether transparency (alpha) data from the image should be preserved or not.</param>
37  /// <param name="interpolate">A boolean value indicating whether the image should be interpolated when it is resized or not.</param>
38  public RasterImageFile(string fileName, bool alpha = true, bool interpolate = true)
39  {
40  Image image;
41 
42  if (alpha)
43  {
44  image = Image.Load<SixLabors.ImageSharp.PixelFormats.Rgba32>(fileName, out SixLabors.ImageSharp.Formats.IImageFormat format);
45  }
46  else
47  {
48  image = Image.Load<SixLabors.ImageSharp.PixelFormats.Rgb24>(fileName, out SixLabors.ImageSharp.Formats.IImageFormat format);
49  }
50 
51  image.Mutate(x => x.AutoOrient());
52 
53  int stride = image.Width * (alpha ? 4 : 3);
54  int size = stride * image.Height;
55 
56  IntPtr tbr = Marshal.AllocHGlobal(size);
57  GC.AddMemoryPressure(size);
58 
59  IntPtr pointer = tbr;
60 
61  unsafe
62  {
63  if (alpha)
64  {
65  Image<SixLabors.ImageSharp.PixelFormats.Rgba32> img = (Image<SixLabors.ImageSharp.PixelFormats.Rgba32>)image;
66 
67  for (int y = 0; y < image.Height; y++)
68  {
69  Memory<SixLabors.ImageSharp.PixelFormats.Rgba32> row = img.DangerousGetPixelRowMemory(y);
70 
71  Span<SixLabors.ImageSharp.PixelFormats.Rgba32> newRow = new Span<SixLabors.ImageSharp.PixelFormats.Rgba32>(pointer.ToPointer(), row.Length);
72  row.Span.CopyTo(newRow);
73 
74  pointer = IntPtr.Add(pointer, stride);
75  }
76  }
77  else
78  {
79  Image<SixLabors.ImageSharp.PixelFormats.Rgb24> img = (Image<SixLabors.ImageSharp.PixelFormats.Rgb24>)image;
80 
81  for (int y = 0; y < image.Height; y++)
82  {
83  Memory<SixLabors.ImageSharp.PixelFormats.Rgb24> row = img.DangerousGetPixelRowMemory(y);
84 
85  Span<SixLabors.ImageSharp.PixelFormats.Rgb24> newRow = new Span<SixLabors.ImageSharp.PixelFormats.Rgb24>(pointer.ToPointer(), row.Length);
86  row.Span.CopyTo(newRow);
87 
88  pointer = IntPtr.Add(pointer, stride);
89  }
90  }
91  }
92 
93  this.Width = image.Width;
94  this.Height = image.Height;
95  this.HasAlpha = alpha;
96  this.Interpolate = interpolate;
97  this.Id = Guid.NewGuid().ToString();
98  this.ImageDataAddress = tbr;
99  this.DataHolder = new DisposableIntPtr(tbr);
100  }
101  }
102 
103  /// <summary>
104  /// A <see cref="RasterImage"/> created from a stream.
105  /// </summary>
107  {
108  /// <summary>
109  /// Creates a new <see cref="RasterImage"/> from the specified stream.
110  /// </summary>
111  /// <param name="imageStream">The stream containing the image data.</param>
112  /// <param name="alpha">A boolean value indicating whether transparency (alpha) data from the image should be preserved or not.</param>
113  /// <param name="interpolate">A boolean value indicating whether the image should be interpolated when it is resized or not.</param>
114  public RasterImageStream(Stream imageStream, bool alpha = true, bool interpolate = true)
115  {
116  Image image;
117 
118  if (alpha)
119  {
120  image = Image.Load<SixLabors.ImageSharp.PixelFormats.Rgba32>(imageStream, out SixLabors.ImageSharp.Formats.IImageFormat format);
121  }
122  else
123  {
124  image = Image.Load<SixLabors.ImageSharp.PixelFormats.Rgb24>(imageStream, out SixLabors.ImageSharp.Formats.IImageFormat format);
125  }
126 
127  image.Mutate(x => x.AutoOrient());
128 
129  int stride = image.Width * (alpha ? 4 : 3);
130  int size = stride * image.Height;
131 
132  IntPtr tbr = Marshal.AllocHGlobal(size);
133  GC.AddMemoryPressure(size);
134 
135  IntPtr pointer = tbr;
136 
137  unsafe
138  {
139  if (alpha)
140  {
141  Image<SixLabors.ImageSharp.PixelFormats.Rgba32> img = (Image<SixLabors.ImageSharp.PixelFormats.Rgba32>)image;
142 
143  for (int y = 0; y < image.Height; y++)
144  {
145  Memory<SixLabors.ImageSharp.PixelFormats.Rgba32> row = img.DangerousGetPixelRowMemory(y);
146 
147  Span<SixLabors.ImageSharp.PixelFormats.Rgba32> newRow = new Span<SixLabors.ImageSharp.PixelFormats.Rgba32>(pointer.ToPointer(), row.Length);
148  row.Span.CopyTo(newRow);
149 
150  pointer = IntPtr.Add(pointer, stride);
151  }
152  }
153  else
154  {
155  Image<SixLabors.ImageSharp.PixelFormats.Rgb24> img = (Image<SixLabors.ImageSharp.PixelFormats.Rgb24>)image;
156 
157  for (int y = 0; y < image.Height; y++)
158  {
159  Memory<SixLabors.ImageSharp.PixelFormats.Rgb24> row = img.DangerousGetPixelRowMemory(y);
160 
161  Span<SixLabors.ImageSharp.PixelFormats.Rgb24> newRow = new Span<SixLabors.ImageSharp.PixelFormats.Rgb24>(pointer.ToPointer(), row.Length);
162  row.Span.CopyTo(newRow);
163 
164  pointer = IntPtr.Add(pointer, stride);
165  }
166  }
167  }
168 
169  this.Width = image.Width;
170  this.Height = image.Height;
171  this.HasAlpha = alpha;
172  this.Interpolate = interpolate;
173  this.Id = Guid.NewGuid().ToString();
174  this.ImageDataAddress = tbr;
175  this.DataHolder = new DisposableIntPtr(tbr);
176  }
177 
178  /// <summary>
179  /// Creates a new <see cref="RasterImage"/> from the specified stream.
180  /// </summary>
181  /// <param name="imageAddress">A pointer to the address where the image data is contained.</param>
182  /// <param name="imageLength">The length in bytes of the image data.</param>
183  /// <param name="alpha">A boolean value indicating whether transparency (alpha) data from the image should be preserved or not.</param>
184  /// <param name="interpolate">A boolean value indicating whether the image should be interpolated when it is resized or not.</param>
185  public RasterImageStream(IntPtr imageAddress, int imageLength, bool alpha = true, bool interpolate = true)
186  {
187  unsafe
188  {
189  ReadOnlySpan<byte> imageSpan = new ReadOnlySpan<byte>((void*)imageAddress, imageLength);
190 
191  Image image;
192 
193  if (alpha)
194  {
195  image = Image.Load<SixLabors.ImageSharp.PixelFormats.Rgba32>(imageSpan, out SixLabors.ImageSharp.Formats.IImageFormat format);
196  }
197  else
198  {
199  image = Image.Load<SixLabors.ImageSharp.PixelFormats.Rgb24>(imageSpan, out SixLabors.ImageSharp.Formats.IImageFormat format);
200  }
201 
202  image.Mutate(x => x.AutoOrient());
203 
204  int stride = image.Width * (alpha ? 4 : 3);
205  int size = stride * image.Height;
206 
207  IntPtr tbr = Marshal.AllocHGlobal(size);
208  GC.AddMemoryPressure(size);
209 
210  IntPtr pointer = tbr;
211 
212  if (alpha)
213  {
214  Image<SixLabors.ImageSharp.PixelFormats.Rgba32> img = (Image<SixLabors.ImageSharp.PixelFormats.Rgba32>)image;
215 
216  for (int y = 0; y < image.Height; y++)
217  {
218  Memory<SixLabors.ImageSharp.PixelFormats.Rgba32> row = img.DangerousGetPixelRowMemory(y);
219 
220  Span<SixLabors.ImageSharp.PixelFormats.Rgba32> newRow = new Span<SixLabors.ImageSharp.PixelFormats.Rgba32>(pointer.ToPointer(), row.Length);
221  row.Span.CopyTo(newRow);
222 
223  pointer = IntPtr.Add(pointer, stride);
224  }
225  }
226  else
227  {
228  Image<SixLabors.ImageSharp.PixelFormats.Rgb24> img = (Image<SixLabors.ImageSharp.PixelFormats.Rgb24>)image;
229 
230  for (int y = 0; y < image.Height; y++)
231  {
232  Memory<SixLabors.ImageSharp.PixelFormats.Rgb24> row = img.DangerousGetPixelRowMemory(y);
233 
234  Span<SixLabors.ImageSharp.PixelFormats.Rgb24> newRow = new Span<SixLabors.ImageSharp.PixelFormats.Rgb24>(pointer.ToPointer(), row.Length);
235  row.Span.CopyTo(newRow);
236 
237  pointer = IntPtr.Add(pointer, stride);
238  }
239  }
240 
241  this.Width = image.Width;
242  this.Height = image.Height;
243  this.HasAlpha = alpha;
244  this.Interpolate = interpolate;
245  this.Id = Guid.NewGuid().ToString();
246  this.ImageDataAddress = tbr;
247  this.DataHolder = new DisposableIntPtr(tbr);
248  }
249  }
250  }
251 }
VectSharp.ImageSharpUtils.RasterImageFile.RasterImageFile
RasterImageFile(string fileName, bool alpha=true, bool interpolate=true)
Creates a new RasterImage from the specified file.
Definition: RasterImages.cs:38
VectSharp.RasterImage
Represents a raster image, created from raw pixel data. Consider using the derived classes included i...
Definition: RasterImage.cs:99
VectSharp.DisposableIntPtr
An IDisposable wrapper around an IntPtr that frees the allocated memory when it is disposed.
Definition: RasterImage.cs:54
VectSharp.ImageSharpUtils
Definition: ImageUriParser.cs:25
VectSharp.RasterImage.Width
int Width
The width in pixels of the image.
Definition: RasterImage.cs:123
VectSharp.ImageSharpUtils.RasterImageFile
A RasterImage created from a file.
Definition: RasterImages.cs:31
VectSharp.RasterImage.Interpolate
bool Interpolate
Determines whether the image should be interpolated when it is resized.
Definition: RasterImage.cs:133
VectSharp.ImageSharpUtils.RasterImageStream.RasterImageStream
RasterImageStream(IntPtr imageAddress, int imageLength, bool alpha=true, bool interpolate=true)
Creates a new RasterImage from the specified stream.
Definition: RasterImages.cs:185
VectSharp.RasterImage.HasAlpha
bool HasAlpha
Determines whether the image has an alpha channel.
Definition: RasterImage.cs:118
VectSharp.ImageSharpUtils.RasterImageStream.RasterImageStream
RasterImageStream(Stream imageStream, bool alpha=true, bool interpolate=true)
Creates a new RasterImage from the specified stream.
Definition: RasterImages.cs:114
VectSharp.RasterImage.DataHolder
IDisposable DataHolder
An IDisposable that will be disposed when the image is disposed.
Definition: RasterImage.cs:108
VectSharp.RasterImage.Height
int Height
The height in pixels of the image.
Definition: RasterImage.cs:128
VectSharp.RasterImage.ImageDataAddress
IntPtr ImageDataAddress
The memory address of the image pixel data.
Definition: RasterImage.cs:103
VectSharp.ImageSharpUtils.RasterImageStream
A RasterImage created from a stream.
Definition: RasterImages.cs:107
VectSharp.RasterImage.Id
string Id
A univocal identifier for this image.
Definition: RasterImage.cs:113