2121using System . Net . Http ;
2222using System . Runtime . CompilerServices ;
2323using System . Runtime . InteropServices ;
24+ using System . Runtime . InteropServices . ComTypes ;
2425using System . Threading . Tasks ;
2526
2627namespace IronSoftware . Drawing
@@ -451,12 +452,19 @@ public T ToBitmap<T>()
451452 }
452453 }
453454
455+ /// <summary>
456+ /// Create a new Bitmap from a a Byte Span.
457+ /// </summary>
458+ /// <param name="span">A Byte Span of image data in any common format.</param>
459+ public static AnyBitmap FromSpan ( ReadOnlySpan < byte > span )
460+ {
461+ return new AnyBitmap ( span ) ;
462+ }
463+
454464 /// <summary>
455465 /// Create a new Bitmap from a a Byte Array.
456466 /// </summary>
457467 /// <param name="bytes">A ByteArray of image data in any common format.</param>
458- /// <seealso cref="FromBytes"/>
459- /// <seealso cref="AnyBitmap(byte[])"/>
460468 public static AnyBitmap FromBytes ( byte [ ] bytes )
461469 {
462470 return new AnyBitmap ( bytes ) ;
@@ -485,6 +493,17 @@ public static AnyBitmap FromStream(Stream stream)
485493 {
486494 return new AnyBitmap ( stream ) ;
487495 }
496+
497+ /// <summary>
498+ /// Construct a new Bitmap from binary data (byte span).
499+ /// </summary>
500+ /// <param name="span">A byte span of image data in any common format.</param>
501+ /// <seealso cref="AnyBitmap"/>
502+ public AnyBitmap ( ReadOnlySpan < byte > span )
503+ {
504+ LoadImage ( span ) ;
505+ }
506+
488507 /// <summary>
489508 /// Construct a new Bitmap from binary data (bytes).
490509 /// </summary>
@@ -540,7 +559,7 @@ public AnyBitmap(AnyBitmap original, int width, int height)
540559 /// <seealso cref="AnyBitmap"/>
541560 public AnyBitmap ( string file )
542561 {
543- LoadImage ( file ) ;
562+ LoadImage ( File . ReadAllBytes ( file ) ) ;
544563 }
545564
546565 /// <summary>
@@ -1986,68 +2005,29 @@ private void CreateNewImageInstance(int width, int height, Color backgroundColor
19862005 Image . SaveAsBmp ( stream ) ;
19872006 Binary = stream . ToArray ( ) ;
19882007 }
1989-
1990- private void LoadImage ( byte [ ] bytes )
2008+
2009+ private void LoadImage ( ReadOnlySpan < byte > bytes )
19912010 {
2011+ Format = Image . DetectFormat ( bytes ) ;
19922012 try
19932013 {
1994- #if NET6_0_OR_GREATER
1995- Image = Image . Load ( bytes ) ;
1996- Format = Image . Metadata . DecodedImageFormat ;
1997- #else
1998- Image = Image . Load ( bytes , out IImageFormat format ) ;
1999- Format = format ;
2000- #endif
2001- Binary = bytes ;
2002- }
2003- catch ( DllNotFoundException e )
2004- {
2005- throw new DllNotFoundException (
2006- "Please install SixLabors.ImageSharp from NuGet." , e ) ;
2007- }
2008- catch ( Exception )
2009- {
2010- try
2011- {
2014+ if ( Format is TiffFormat )
20122015 OpenTiffToImageSharp ( bytes ) ;
2013- }
2014- catch ( Exception e )
2016+ else
20152017 {
2016- throw new NotSupportedException (
2017- " Image could not be loaded. File format is not supported." , e ) ;
2018+ Binary = bytes . ToArray ( ) ;
2019+ Image = Image . Load ( bytes ) ;
20182020 }
20192021 }
2020- }
2021-
2022- private void LoadImage ( string file )
2023- {
2024- try
2025- {
2026- #if NET6_0_OR_GREATER
2027- Image = Image . Load ( file ) ;
2028- Format = Image . Metadata . DecodedImageFormat ;
2029- #else
2030- Image = Image . Load ( file , out IImageFormat format ) ;
2031- Format = format ;
2032- #endif
2033- Binary = File . ReadAllBytes ( file ) ;
2034- }
20352022 catch ( DllNotFoundException e )
20362023 {
20372024 throw new DllNotFoundException (
20382025 "Please install SixLabors.ImageSharp from NuGet." , e ) ;
20392026 }
2040- catch ( Exception )
2027+ catch ( Exception e )
20412028 {
2042- try
2043- {
2044- OpenTiffToImageSharp ( File . ReadAllBytes ( file ) ) ;
2045- }
2046- catch ( Exception e )
2047- {
2048- throw new NotSupportedException (
2049- "Image could not be loaded. File format is not supported." , e ) ;
2050- }
2029+ throw new NotSupportedException (
2030+ "Image could not be loaded. File format is not supported." , e ) ;
20512031 }
20522032 }
20532033
@@ -2064,14 +2044,6 @@ private void LoadImage(Stream stream)
20642044 LoadImage ( ms . ToArray ( ) ) ;
20652045 }
20662046
2067- private void SetBinaryFromImageSharp ( Image < Rgba32 > tiffImage )
2068- {
2069- using var memoryStream = new MemoryStream ( ) ;
2070- tiffImage . Save ( memoryStream , new TiffEncoder ( ) ) ;
2071- _ = memoryStream . Seek ( 0 , SeekOrigin . Begin ) ;
2072- LoadImage ( memoryStream ) ;
2073- }
2074-
20752047 private static AnyBitmap LoadSVGImage ( string file )
20762048 {
20772049 try
@@ -2224,7 +2196,7 @@ private static SKBitmap OpenTiffToSKBitmap(AnyBitmap anyBitmap)
22242196 }
22252197 }
22262198
2227- private void OpenTiffToImageSharp ( byte [ ] bytes )
2199+ private void OpenTiffToImageSharp ( ReadOnlySpan < byte > bytes )
22282200 {
22292201 try
22302202 {
@@ -2233,7 +2205,7 @@ private void OpenTiffToImageSharp(byte[] bytes)
22332205 List < Image > images = new ( ) ;
22342206
22352207 // create a memory stream out of them
2236- using MemoryStream tiffStream = new ( bytes ) ;
2208+ using MemoryStream tiffStream = new ( bytes . ToArray ( ) ) ;
22372209
22382210 // open a TIFF stored in the stream
22392211 using ( var tif = Tiff . ClientOpen ( "in-memory" , "r" , tiffStream , new TiffStream ( ) ) )
@@ -2254,29 +2226,50 @@ private void OpenTiffToImageSharp(byte[] bytes)
22542226
22552227 using Image < Rgba32 > bmp = new ( width , height ) ;
22562228
2257- byte [ ] bits = PrepareByteArray ( bmp , raster , width , height ) ;
2229+ var bits = PrepareByteArray ( bmp , raster , width , height ) ;
22582230
22592231 images . Add ( Image . LoadPixelData < Rgba32 > ( bits , bmp . Width , bmp . Height ) ) ;
22602232 }
22612233 }
2262-
2263- Image ? . Dispose ( ) ;
2264-
2234+
2235+ // find max
22652236 FindMaxWidthAndHeight ( images , out int maxWidth , out int maxHeight ) ;
22662237
2267- using Image < Rgba32 > tiffImage = CloneAndResizeImageSharp ( images [ 0 ] , maxWidth , maxHeight ) ;
2238+ // mute first image
2239+ images [ 0 ] . Mutate ( img => img . Resize ( new ResizeOptions
2240+ {
2241+ Size = new Size ( maxWidth , maxHeight ) ,
2242+ Mode = ResizeMode . BoxPad ,
2243+ PadColor = SixLabors . ImageSharp . Color . Transparent
2244+ } ) ) ;
2245+
2246+ // iterate through images past the first
22682247 for ( int i = 1 ; i < images . Count ; i ++ )
22692248 {
2270- Image < Rgba32 > image = CloneAndResizeImageSharp ( images [ i ] , maxWidth , maxHeight ) ;
2271- _ = tiffImage . Frames . AddFrame ( image . Frames . RootFrame ) ;
2272- }
2249+ // mute image
2250+ images [ i ] . Mutate ( img => img . Resize ( new ResizeOptions
2251+ {
2252+ Size = new Size ( maxWidth , maxHeight ) ,
2253+ Mode = ResizeMode . BoxPad ,
2254+ PadColor = SixLabors . ImageSharp . Color . Transparent
2255+ } ) ) ;
22732256
2274- SetBinaryFromImageSharp ( tiffImage ) ;
2257+ // add frames to first image
2258+ _ = images [ 0 ] . Frames . AddFrame ( images [ i ] . Frames . RootFrame ) ;
22752259
2276- foreach ( Image image in images )
2277- {
2278- image . Dispose ( ) ;
2260+ // dispose images past the first
2261+ images [ i ] . Dispose ( ) ;
22792262 }
2263+
2264+ // get raw binary
2265+ using var memoryStream = new MemoryStream ( ) ;
2266+ images [ 0 ] . Save ( memoryStream , new TiffEncoder ( ) ) ;
2267+ memoryStream . Seek ( 0 , SeekOrigin . Begin ) ;
2268+
2269+ // store result
2270+ Binary = memoryStream . ToArray ( ) ;
2271+ Image ? . Dispose ( ) ;
2272+ Image = images [ 0 ] ;
22802273 }
22812274 catch ( DllNotFoundException e )
22822275 {
@@ -2288,7 +2281,7 @@ private void OpenTiffToImageSharp(byte[] bytes)
22882281 }
22892282 }
22902283
2291- private byte [ ] PrepareByteArray ( Image < Rgba32 > bmp , int [ ] raster , int width , int height )
2284+ private ReadOnlySpan < byte > PrepareByteArray ( Image < Rgba32 > bmp , int [ ] raster , int width , int height )
22922285 {
22932286 byte [ ] bits = new byte [ GetStride ( bmp ) * height ] ;
22942287
0 commit comments