@@ -52,6 +52,7 @@ public partial class AnyBitmap : IDisposable, IAnyImage
5252 private byte [ ] Binary { get ; set ; }
5353 private IImageFormat Format { get ; set ; }
5454 private TiffCompression TiffCompression { get ; set ; } = TiffCompression . Lzw ;
55+ private bool PreserveOriginalFormat { get ; set ; } = true ;
5556
5657 /// <summary>
5758 /// Width of the image.
@@ -138,7 +139,7 @@ public MemoryStream GetStream()
138139 /// <returns></returns>
139140 public AnyBitmap Clone ( )
140141 {
141- return new AnyBitmap ( Binary ) ;
142+ return new AnyBitmap ( Binary , PreserveOriginalFormat ) ;
142143 }
143144
144145 /// <summary>
@@ -462,87 +463,99 @@ public T ToBitmap<T>()
462463 /// Create a new Bitmap from a a Byte Span.
463464 /// </summary>
464465 /// <param name="span">A Byte Span of image data in any common format.</param>
465- public static AnyBitmap FromSpan ( ReadOnlySpan < byte > span )
466+ /// <param name="preserveOriginalFormat">Determine whether to load <see cref="SixLabors.ImageSharp.Image"/> as its original pixel format or Rgba32.
467+ /// Default is true. Set to false to load as Rgba32.</param>
468+ public static AnyBitmap FromSpan ( ReadOnlySpan < byte > span , bool preserveOriginalFormat = true )
466469 {
467- return new AnyBitmap ( span ) ;
470+ return new AnyBitmap ( span , preserveOriginalFormat ) ;
468471 }
469472
470473 /// <summary>
471474 /// Create a new Bitmap from a a Byte Array.
472475 /// </summary>
473476 /// <param name="bytes">A ByteArray of image data in any common format.</param>
474- public static AnyBitmap FromBytes ( byte [ ] bytes )
477+ /// <param name="preserveOriginalFormat">Determine whether to load <see cref="SixLabors.ImageSharp.Image"/> as its original pixel format or Rgba32.
478+ /// Default is true. Set to false to load as Rgba32.</param>
479+ public static AnyBitmap FromBytes ( byte [ ] bytes , bool preserveOriginalFormat = true )
475480 {
476- return new AnyBitmap ( bytes ) ;
481+ return new AnyBitmap ( bytes , preserveOriginalFormat ) ;
477482 }
478483
479484 /// <summary>
480485 /// Create a new Bitmap from a <see cref="Stream"/> (bytes).
481486 /// </summary>
482- /// <param name="stream">A <see cref="Stream"/> of image data in any
483- /// common format.</param>
484- /// <seealso cref="FromStream(Stream)"/>
487+ /// <param name="stream">A <see cref="Stream"/> of image data in any common format.</param>
488+ /// <param name="preserveOriginalFormat">Determine whether to load <see cref="SixLabors.ImageSharp.Image"/> as its original pixel format or Rgba32.
489+ /// Default is true. Set to false to load as Rgba32.</param>
490+ /// <seealso cref="FromStream(Stream, bool)"/>
485491 /// <seealso cref="AnyBitmap"/>
486- public static AnyBitmap FromStream ( MemoryStream stream )
492+ public static AnyBitmap FromStream ( MemoryStream stream , bool preserveOriginalFormat = true )
487493 {
488- return new AnyBitmap ( stream ) ;
494+ return new AnyBitmap ( stream , preserveOriginalFormat ) ;
489495 }
490496
491497 /// <summary>
492498 /// Create a new Bitmap from a <see cref="Stream"/> (bytes).
493499 /// </summary>
494- /// <param name="stream">A <see cref="Stream"/> of image data in any
495- /// common format.</param>
496- /// <seealso cref="FromStream(MemoryStream)"/>
500+ /// <param name="stream">A <see cref="Stream"/> of image data in any common format.</param>
501+ /// <param name="preserveOriginalFormat">Determine whether to load <see cref="SixLabors.ImageSharp.Image"/> as its original pixel format or Rgba32.
502+ /// Default is true. Set to false to load as Rgba32.</param>
503+ /// <seealso cref="FromStream(MemoryStream, bool)"/>
497504 /// <seealso cref="AnyBitmap"/>
498- public static AnyBitmap FromStream ( Stream stream )
505+ public static AnyBitmap FromStream ( Stream stream , bool preserveOriginalFormat = true )
499506 {
500- return new AnyBitmap ( stream ) ;
507+ return new AnyBitmap ( stream , preserveOriginalFormat ) ;
501508 }
502509
503510 /// <summary>
504511 /// Construct a new Bitmap from binary data (byte span).
505512 /// </summary>
506513 /// <param name="span">A byte span of image data in any common format.</param>
514+ /// <param name="preserveOriginalFormat">Determine whether to load <see cref="SixLabors.ImageSharp.Image"/> as its original pixel format or Rgba32.
515+ /// Default is true. Set to false to load as Rgba32.</param>
507516 /// <seealso cref="AnyBitmap"/>
508- public AnyBitmap ( ReadOnlySpan < byte > span )
517+ public AnyBitmap ( ReadOnlySpan < byte > span , bool preserveOriginalFormat = true )
509518 {
510- LoadImage ( span ) ;
519+ LoadImage ( span , preserveOriginalFormat ) ;
511520 }
512521
513522 /// <summary>
514523 /// Construct a new Bitmap from binary data (bytes).
515524 /// </summary>
516525 /// <param name="bytes">A ByteArray of image data in any common format.</param>
526+ /// <param name="preserveOriginalFormat">Determine whether to load <see cref="SixLabors.ImageSharp.Image"/> as its original pixel format or Rgba32.
527+ /// Default is true. Set to false to load as Rgba32.</param>
517528 /// <seealso cref="FromBytes"/>
518529 /// <seealso cref="AnyBitmap"/>
519- public AnyBitmap ( byte [ ] bytes )
530+ public AnyBitmap ( byte [ ] bytes , bool preserveOriginalFormat = true )
520531 {
521- LoadImage ( bytes ) ;
532+ LoadImage ( bytes , preserveOriginalFormat ) ;
522533 }
523534
524535 /// <summary>
525536 /// Construct a new Bitmap from a <see cref="Stream"/> (bytes).
526537 /// </summary>
527- /// <param name="stream">A <see cref="Stream"/> of image data in any
528- /// common format.</param>
529- /// <seealso cref="FromStream(Stream)"/>
538+ /// <param name="stream">A <see cref="Stream"/> of image data in any common format.</param>
539+ /// <param name="preserveOriginalFormat">Determine whether to load <see cref="SixLabors.ImageSharp.Image"/> as its original pixel format or Rgba32.
540+ /// Default is true. Set to false to load as Rgba32.</param>
541+ /// <seealso cref="FromStream(Stream, bool)"/>
530542 /// <seealso cref="AnyBitmap"/>
531- public AnyBitmap ( MemoryStream stream )
543+ public AnyBitmap ( MemoryStream stream , bool preserveOriginalFormat = true )
532544 {
533- LoadImage ( stream . ToArray ( ) ) ;
545+ LoadImage ( stream . ToArray ( ) , preserveOriginalFormat ) ;
534546 }
535547
536548 /// <summary>
537549 /// Construct a new Bitmap from a <see cref="Stream"/> (bytes).
538550 /// </summary>
539- /// <param name="stream">A <see cref="Stream"/> of image data in any
540- /// common format.</param>
541- /// <seealso cref="FromStream(MemoryStream)"/>
551+ /// <param name="stream">A <see cref="Stream"/> of image data in any common format.</param>
552+ /// <param name="preserveOriginalFormat">Determine whether to load <see cref="SixLabors.ImageSharp.Image"/> as its original pixel format or Rgba32.
553+ /// Default is true. Set to false to load as Rgba32.</param>
554+ /// <seealso cref="FromStream(MemoryStream, bool)"/>
542555 /// <seealso cref="AnyBitmap"/>
543- public AnyBitmap ( Stream stream )
556+ public AnyBitmap ( Stream stream , bool preserveOriginalFormat = true )
544557 {
545- LoadImage ( stream ) ;
558+ LoadImage ( stream , preserveOriginalFormat ) ;
546559 }
547560
548561 /// <summary>
@@ -561,25 +574,29 @@ public AnyBitmap(AnyBitmap original, int width, int height)
561574 /// Construct a new Bitmap from a file.
562575 /// </summary>
563576 /// <param name="file">A fully qualified file path./</param>
577+ /// <param name="preserveOriginalFormat">Determine whether to load <see cref="SixLabors.ImageSharp.Image"/> as its original pixel format or Rgba32.
578+ /// Default is true. Set to false to load as Rgba32.</param>
564579 /// <seealso cref="FromFile"/>
565580 /// <seealso cref="AnyBitmap"/>
566- public AnyBitmap ( string file )
581+ public AnyBitmap ( string file , bool preserveOriginalFormat = true )
567582 {
568- LoadImage ( File . ReadAllBytes ( file ) ) ;
583+ LoadImage ( File . ReadAllBytes ( file ) , preserveOriginalFormat ) ;
569584 }
570585
571586 /// <summary>
572587 /// Construct a new Bitmap from a Uri
573588 /// </summary>
574589 /// <param name="uri">The uri of the image.</param>
590+ /// <param name="preserveOriginalFormat">Determine whether to load <see cref="SixLabors.ImageSharp.Image"/> as its original pixel format or Rgba32.
591+ /// Default is true. Set to false to load as Rgba32.</param>
575592 /// <seealso cref="FromUriAsync"/>
576593 /// <seealso cref="AnyBitmap"/>
577- public AnyBitmap ( Uri uri )
594+ public AnyBitmap ( Uri uri , bool preserveOriginalFormat = true )
578595 {
579596 try
580597 {
581598 using Stream stream = LoadUriAsync ( uri ) . GetAwaiter ( ) . GetResult ( ) ;
582- LoadImage ( stream ) ;
599+ LoadImage ( stream , preserveOriginalFormat ) ;
583600 }
584601 catch ( Exception e )
585602 {
@@ -602,34 +619,38 @@ public AnyBitmap(int width, int height, Color backgroundColor = null)
602619 /// Create a new Bitmap from a file.
603620 /// </summary>
604621 /// <param name="file">A fully qualified file path.</param>
622+ /// <param name="preserveOriginalFormat">Determine whether to load <see cref="SixLabors.ImageSharp.Image"/> as its original pixel format or Rgba32.
623+ /// Default is true. Set to false to load as Rgba32.</param>
605624 /// <seealso cref="FromFile"/>
606625 /// <seealso cref="AnyBitmap"/>
607- public static AnyBitmap FromFile ( string file )
626+ public static AnyBitmap FromFile ( string file , bool preserveOriginalFormat = true )
608627 {
609628 if ( file . ToLower ( ) . EndsWith ( ".svg" ) )
610629 {
611- return LoadSVGImage ( file ) ;
630+ return LoadSVGImage ( file , preserveOriginalFormat ) ;
612631 }
613632 else
614633 {
615- return new AnyBitmap ( file ) ;
634+ return new AnyBitmap ( file , preserveOriginalFormat ) ;
616635 }
617636 }
618637
619638 /// <summary>
620639 /// Construct a new Bitmap from a Uri
621640 /// </summary>
622641 /// <param name="uri">The uri of the image.</param>
642+ /// <param name="preserveOriginalFormat">Determine whether to load <see cref="SixLabors.ImageSharp.Image"/> as its original pixel format or Rgba32.
643+ /// Default is true. Set to false to load as Rgba32.</param>
623644 /// <returns></returns>
624645 /// <seealso cref="AnyBitmap"/>
625646 /// <seealso cref="FromUri"/>
626647 /// <seealso cref="FromUriAsync"/>
627- public static async Task < AnyBitmap > FromUriAsync ( Uri uri )
648+ public static async Task < AnyBitmap > FromUriAsync ( Uri uri , bool preserveOriginalFormat = true )
628649 {
629650 try
630651 {
631652 using Stream stream = await LoadUriAsync ( uri ) ;
632- return new AnyBitmap ( stream ) ;
653+ return new AnyBitmap ( stream , preserveOriginalFormat ) ;
633654 }
634655 catch ( Exception e )
635656 {
@@ -641,13 +662,15 @@ public static async Task<AnyBitmap> FromUriAsync(Uri uri)
641662 /// Construct a new Bitmap from a Uri
642663 /// </summary>
643664 /// <param name="uri">The uri of the image.</param>
665+ /// <param name="preserveOriginalFormat">Determine whether to load <see cref="SixLabors.ImageSharp.Image"/> as its original pixel format or Rgba32.
666+ /// Default is true. Set to false to load as Rgba32.</param>
644667 /// <returns></returns>
645668 /// <seealso cref="AnyBitmap"/>
646669 /// <seealso cref="FromUriAsync"/>
647670#if NET6_0_OR_GREATER
648671 [ Obsolete ( "FromUri(Uri) is obsolete for net60 or greater because it uses WebClient which is obsolete. Consider using FromUriAsync(Uri) method." ) ]
649672#endif
650- public static AnyBitmap FromUri ( Uri uri )
673+ public static AnyBitmap FromUri ( Uri uri , bool preserveOriginalFormat = true )
651674 {
652675 try
653676 {
@@ -2017,19 +2040,33 @@ private void CreateNewImageInstance(int width, int height, Color backgroundColor
20172040 Binary = stream . ToArray ( ) ;
20182041 }
20192042
2020- private void LoadImage ( ReadOnlySpan < byte > bytes )
2043+ private void LoadImage ( ReadOnlySpan < byte > bytes , bool preserveOriginalFormat )
20212044 {
20222045 Format = Image . DetectFormat ( bytes ) ;
20232046 try
20242047 {
20252048 if ( Format is TiffFormat )
20262049 OpenTiffToImageSharp ( bytes ) ;
2027-
20282050 else
20292051 {
20302052 Binary = bytes . ToArray ( ) ;
2031- Image = Image . Load ( bytes ) ;
2032-
2053+
2054+ if ( preserveOriginalFormat )
2055+ Image = Image . Load ( bytes ) ;
2056+ else
2057+ {
2058+ PreserveOriginalFormat = preserveOriginalFormat ;
2059+ Image = Image . Load < Rgba32 > ( bytes ) ;
2060+
2061+ // .png image pre-processing
2062+ if ( Format . Name == "PNG" )
2063+ Image . Mutate ( img => img . BackgroundColor ( SixLabors . ImageSharp . Color . White ) ) ;
2064+ }
2065+
2066+ // Fix if the input image is auto-rotated; this issue is acknowledged by SixLabors.ImageSharp community
2067+ // ref: https://github.com/SixLabors/ImageSharp/discussions/2685
2068+ Image . Mutate ( x => x . AutoOrient ( ) ) ;
2069+
20332070 var resolutionUnit = this . Image . Metadata . ResolutionUnits ;
20342071 var horizontal = this . Image . Metadata . HorizontalResolution ;
20352072 var vertical = this . Image . Metadata . VerticalResolution ;
@@ -2067,7 +2104,7 @@ private void LoadImage(ReadOnlySpan<byte> bytes)
20672104 }
20682105 }
20692106
2070- private void LoadImage ( Stream stream )
2107+ private void LoadImage ( Stream stream , bool preserveOriginalFormat )
20712108 {
20722109 byte [ ] buffer = new byte [ 16 * 1024 ] ;
20732110 using MemoryStream ms = new ( ) ;
@@ -2077,17 +2114,17 @@ private void LoadImage(Stream stream)
20772114 ms . Write ( buffer , 0 , read ) ;
20782115 }
20792116
2080- LoadImage ( ms . ToArray ( ) ) ;
2117+ LoadImage ( ms . ToArray ( ) , preserveOriginalFormat ) ;
20812118 }
20822119
2083- private static AnyBitmap LoadSVGImage ( string file )
2120+ private static AnyBitmap LoadSVGImage ( string file , bool preserveOriginalFormat )
20842121 {
20852122 try
20862123
20872124 {
20882125 return new AnyBitmap (
20892126 DecodeSVG ( file ) . Encode ( SKEncodedImageFormat . Png , 100 )
2090- . ToArray ( ) ) ;
2127+ . ToArray ( ) , preserveOriginalFormat ) ;
20912128 }
20922129 catch ( DllNotFoundException e )
20932130 {
0 commit comments