Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
c3feb6c
fix some ImageSharp color casting
ikkyuland Jul 10, 2025
2d2f799
implement lazyload and overhaul Tiff
ikkyuland Jul 11, 2025
0e127c4
[DW-34] optimize OpenTiffToImageSharp
ikkyuland Jul 12, 2025
3653403
add DW_34_ShouldNotThrowOutOfMemory
ikkyuland Jul 12, 2025
7d6dbc2
[DW-34] add dynamic treshold (.net6+)
ikkyuland Jul 12, 2025
9b74625
reduce iteration of DW_34_ShouldNotThrowOutOfMemory
ikkyuland Jul 12, 2025
5d4086d
[DW-34] optimize GetRGBBuffer by not cast Pixel to Color
ikkyuland Jul 14, 2025
1604c4f
[DW-34] also lazy load Binary
ikkyuland Jul 14, 2025
fb2b8d2
[DW-34] add GetRGBABuffer
ikkyuland Jul 14, 2025
36a8617
[DW-34] use IEnumerable<Image>
ikkyuland Jul 15, 2025
aa9642e
[DW-34] fix GetRGBABuffer and add TestGetRGBABuffer
ikkyuland Jul 15, 2025
f4553a1
optimize RotateFlip, Redact and remove OpenGifToImageSharp
ikkyuland Jul 15, 2025
2a8617d
[DW-34] optimize InternalLoadTiff
ikkyuland Jul 16, 2025
ff49954
[DW-34] always use BmpEncoder
ikkyuland Jul 16, 2025
9e328e4
fix export gif and add tests
ikkyuland Jul 16, 2025
69c3279
catch Width Height BitsPerPixel value for faster operation
ikkyuland Aug 4, 2025
3b1e95e
disable LoadTest1
ikkyuland Aug 4, 2025
11dae53
cache frameCount
ikkyuland Aug 6, 2025
09e572f
[DW-34] optimize ImageSharp casting
ikkyuland Aug 6, 2025
44dcbb4
Binary Thread Safety
ikkyuland Aug 8, 2025
4c55ed7
use _lazyImage?
ikkyuland Aug 8, 2025
347fa9f
optimize (WIP)
ikkyuland Aug 8, 2025
a390fc6
make GetTiffFrameCountFast also count Thumbnail since ImageSharp cann…
ikkyuland Aug 11, 2025
9266321
remove unused LoadTest1()
ikkyuland Aug 11, 2025
7c823bf
fix tryWithLibTiff logic
ikkyuland Aug 11, 2025
b1e1340
improve readability
ikkyuland Aug 11, 2025
248e645
fixed image loaded while Disposing
ikkyuland Aug 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
implement lazyload and overhaul Tiff
  • Loading branch information
ikkyuland committed Jul 11, 2025
commit 2d2f799c162ef03f93e626c10604e2f9e1a90cd7
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,14 @@ public void Create_AnyBitmap_by_Filename()
string imagePath = GetRelativeFilePath("Mona-Lisa-oil-wood-panel-Leonardo-da.webp");

var bitmap = AnyBitmap.FromFile(imagePath);
bitmap.IsImageLoaded().Should().BeFalse();

bitmap.SaveAs("result.bmp");

bitmap.IsImageLoaded().Should().BeTrue();
//should still be the original bytes
bitmap.Length.Should().Be((int)new FileInfo(imagePath).Length);

Assert.Equal(671, bitmap.Width);
Assert.Equal(1000, bitmap.Height);
Assert.Equal(74684, bitmap.Length);
Expand All @@ -47,7 +54,14 @@ public void Create_AnyBitmap_by_Byte()
byte[] bytes = File.ReadAllBytes(imagePath);

var bitmap = AnyBitmap.FromBytes(bytes);
bitmap.IsImageLoaded().Should().BeFalse();

_ = bitmap.TrySaveAs("result.bmp");

bitmap.IsImageLoaded().Should().BeTrue();
//should still be the original bytes
bitmap.Length.Should().Be(bytes.Length);

AssertImageAreEqual(imagePath, "result.bmp");

bitmap = new AnyBitmap(bytes);
Expand All @@ -63,7 +77,14 @@ public void Create_AnyBitmap_by_Stream()
Stream ms = new MemoryStream(bytes);

var bitmap = AnyBitmap.FromStream(ms);
bitmap.IsImageLoaded().Should().BeFalse();

_ = bitmap.TrySaveAs("result.bmp");

bitmap.IsImageLoaded().Should().BeTrue();
//should still be the original bytes
bitmap.Length.Should().Be(bytes.Length);

AssertImageAreEqual(imagePath, "result.bmp");

ms.Position = 0;
Expand All @@ -80,12 +101,21 @@ public void Create_AnyBitmap_by_MemoryStream()
var ms = new MemoryStream(bytes);

var bitmap = AnyBitmap.FromStream(ms);
bitmap.IsImageLoaded().Should().BeFalse();

_ = bitmap.TrySaveAs("result.bmp");

bitmap.IsImageLoaded().Should().BeTrue();
//should still be the original bytes
bitmap.Length.Should().Be(bytes.Length);

AssertImageAreEqual(imagePath, "result.bmp");

bitmap = new AnyBitmap(ms);
bitmap.SaveAs("result.bmp");
AssertImageAreEqual(imagePath, "result.bmp");


}

[FactWithAutomaticDisplayName]
Expand Down Expand Up @@ -245,6 +275,16 @@ public void AnyBitmap_should_set_Pixel()

// Check the pixel color has changed
Assert.Equal(bitmap.GetPixel(0, 0), Color.Black);

#if NETFRAMEWORK
//windows only
// SetPixel makes the image dirty so it should update AnyBitmap.Binary value

System.Drawing.Bitmap temp1 = bitmap;
AnyBitmap temp2 = (AnyBitmap)temp1;
Assert.Equal(temp1.GetPixel(0, 0).ToArgb(), System.Drawing.Color.Black.ToArgb());
Assert.Equal(temp2.GetPixel(0, 0), Color.Black);
#endif
}
}

Expand Down
213 changes: 213 additions & 0 deletions IronSoftware.Drawing/IronSoftware.Drawing.Common/AnyBitmap.Enum.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
using System;
using System.IO;

namespace IronSoftware.Drawing
{
public partial class AnyBitmap
{
#pragma warning disable CS0618
/// <summary>
/// Converts the legacy <see cref="RotateFlipType"/> to <see cref="RotateMode"/> and <see cref="FlipMode"/>
/// </summary>
[Obsolete("RotateFlipType is legacy support from System.Drawing. " +
"Please use RotateMode and FlipMode instead.")]
internal static (RotateMode, FlipMode) ParseRotateFlipType(RotateFlipType rotateFlipType)
{
return rotateFlipType switch
{
RotateFlipType.RotateNoneFlipNone or RotateFlipType.Rotate180FlipXY => (RotateMode.None, FlipMode.None),
RotateFlipType.Rotate90FlipNone or RotateFlipType.Rotate270FlipXY => (RotateMode.Rotate90, FlipMode.None),
RotateFlipType.RotateNoneFlipXY or RotateFlipType.Rotate180FlipNone => (RotateMode.Rotate180, FlipMode.None),
RotateFlipType.Rotate90FlipXY or RotateFlipType.Rotate270FlipNone => (RotateMode.Rotate270, FlipMode.None),
RotateFlipType.RotateNoneFlipX or RotateFlipType.Rotate180FlipY => (RotateMode.None, FlipMode.Horizontal),
RotateFlipType.Rotate90FlipX or RotateFlipType.Rotate270FlipY => (RotateMode.Rotate90, FlipMode.Horizontal),
RotateFlipType.RotateNoneFlipY or RotateFlipType.Rotate180FlipX => (RotateMode.None, FlipMode.Vertical),
RotateFlipType.Rotate90FlipY or RotateFlipType.Rotate270FlipX => (RotateMode.Rotate90, FlipMode.Vertical),
_ => throw new ArgumentOutOfRangeException(nameof(rotateFlipType), rotateFlipType, null),
};
}

/// <summary>
/// Provides enumeration over how a image should be flipped.
/// </summary>
public enum FlipMode
{
/// <summary>
/// Don't flip the image.
/// </summary>
None,

/// <summary>
/// Flip the image horizontally.
/// </summary>
Horizontal,

/// <summary>
/// Flip the image vertically.
/// </summary>
Vertical
}

/// <summary>
/// Popular image formats which <see cref="AnyBitmap"/> can read and export.
/// </summary>
/// <seealso cref="ExportFile(string, ImageFormat, int)"/>
/// <seealso cref="ExportStream(Stream, ImageFormat, int)"/>
/// <seealso cref="ExportBytes(ImageFormat, int)"/>
public enum ImageFormat
{
/// <summary> The Bitmap image format.</summary>
Bmp = 0,

/// <summary> The Gif image format.</summary>
Gif = 1,

/// <summary> The Tiff image format.</summary>
Tiff = 2,

/// <summary> The Jpeg image format.</summary>
Jpeg = 3,

/// <summary> The PNG image format.</summary>
Png = 4,

/// <summary> The WBMP image format. Will default to BMP if not
/// supported on the runtime platform.</summary>
Wbmp = 5,

/// <summary> The new WebP image format.</summary>
Webp = 6,

/// <summary> The Icon image format.</summary>
Icon = 7,

/// <summary> The Wmf image format.</summary>
Wmf = 8,

/// <summary> The Raw image format.</summary>
RawFormat = 9,

/// <summary> The existing raw image format.</summary>
Default = -1

}

/// <summary>
/// Specifies how much an image is rotated and the axis used to flip
/// the image. This follows the legacy System.Drawing.RotateFlipType
/// notation.
/// </summary>
[Obsolete("RotateFlipType is legacy support from System.Drawing. " +
"Please use RotateMode and FlipMode instead.")]
public enum RotateFlipType
{
/// <summary>
/// Specifies no clockwise rotation and no flipping.
/// </summary>
RotateNoneFlipNone,
/// <summary>
/// Specifies a 180-degree clockwise rotation followed by a
/// horizontal and vertical flip.
/// </summary>
Rotate180FlipXY,

/// <summary>
/// Specifies a 90-degree clockwise rotation without flipping.
/// </summary>
Rotate90FlipNone,
/// <summary>
/// Specifies a 270-degree clockwise rotation followed by a
/// horizontal and vertical flip.
/// </summary>
Rotate270FlipXY,

/// <summary>
/// Specifies no clockwise rotation followed by a horizontal and
/// vertical flip.
/// </summary>
RotateNoneFlipXY,
/// <summary>
/// Specifies a 180-degree clockwise rotation without flipping.
/// </summary>
Rotate180FlipNone,

/// <summary>
/// Specifies a 90-degree clockwise rotation followed by a
/// horizontal and vertical flip.
/// </summary>
Rotate90FlipXY,
/// <summary>
/// Specifies a 270-degree clockwise rotation without flipping.
/// </summary>
Rotate270FlipNone,

/// <summary>
/// Specifies no clockwise rotation followed by a horizontal flip.
/// </summary>
RotateNoneFlipX,
/// <summary>
/// Specifies a 180-degree clockwise rotation followed by a
/// vertical flip.
/// </summary>
Rotate180FlipY,

/// <summary>
/// Specifies a 90-degree clockwise rotation followed by a
/// horizontal flip.
/// </summary>
Rotate90FlipX,
/// <summary>
/// Specifies a 270-degree clockwise rotation followed by a
/// vertical flip.
/// </summary>
Rotate270FlipY,

/// <summary>
/// Specifies no clockwise rotation followed by a vertical flip.
/// </summary>
RotateNoneFlipY,
/// <summary>
/// Specifies a 180-degree clockwise rotation followed by a
/// horizontal flip.
/// </summary>
Rotate180FlipX,

/// <summary>
/// Specifies a 90-degree clockwise rotation followed by a
/// vertical flip.
/// </summary>
Rotate90FlipY,
/// <summary>
/// Specifies a 270-degree clockwise rotation followed by a
/// horizontal flip.
/// </summary>
Rotate270FlipX
}

/// <summary>
/// Provides enumeration over how the image should be rotated.
/// </summary>
public enum RotateMode
{
/// <summary>
/// Do not rotate the image.
/// </summary>
None,

/// <summary>
/// Rotate the image by 90 degrees clockwise.
/// </summary>
Rotate90 = 90,

/// <summary>
/// Rotate the image by 180 degrees clockwise.
/// </summary>
Rotate180 = 180,

/// <summary>
/// Rotate the image by 270 degrees clockwise.
/// </summary>
Rotate270 = 270
}
}
}
Loading