Skip to content

Commit 62ed1aa

Browse files
BramClocktimizerOceania2018
authored andcommitted
Fixes #457 Bitmap.ToArray() does not handle images with odd width
1 parent a7fdcbc commit 62ed1aa

4 files changed

Lines changed: 33 additions & 3 deletions

File tree

src/NumSharp.Bitmap/np_.extensions.cs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,14 @@ public static unsafe NDArray ToNDArray(this System.Drawing.Bitmap image, bool fl
8787
{
8888
if (bmpData.Stride / bmpData.Width == 4) //1byte-per-color
8989
{
90-
return ret.reshape(1, bmpData.Height, bmpData.Width, bmpData.Stride / bmpData.Width) //reshape
90+
return ReshapeFlatData(ret, bmpData) // reshape
9191
[Slice.All, Slice.All, Slice.All, new Slice(stop: 3)] //slice
9292
.flat; //flatten
9393
}
9494

9595
if (bmpData.Stride / bmpData.Width == 8) //2bytes-per-color
9696
{
97-
return ret.reshape(1, bmpData.Height, bmpData.Width, bmpData.Stride / bmpData.Width) //reshape
97+
return ReshapeFlatData(ret, bmpData) // reshape
9898
[Slice.All, Slice.All, Slice.All, new Slice(stop: 6)] //slice
9999
.flat; //flatten
100100
}
@@ -106,7 +106,7 @@ public static unsafe NDArray ToNDArray(this System.Drawing.Bitmap image, bool fl
106106
}
107107
else
108108
{
109-
ret = ret.reshape(1, bmpData.Height, bmpData.Width, bmpData.Stride / bmpData.Width); //reshape
109+
ret = ReshapeFlatData(ret, bmpData); //reshape
110110
if (discardAlpha)
111111
{
112112
if (ret.shape[3] == 4) //1byte-per-color
@@ -122,6 +122,25 @@ public static unsafe NDArray ToNDArray(this System.Drawing.Bitmap image, bool fl
122122
}
123123
}
124124

125+
/// <summary>
126+
/// Reshapes the flat data to match the size of the bitmap.
127+
/// </summary>
128+
/// <param name="ret">flat 1-dimensional array containing the bitmap data</param>
129+
/// <param name="bmpData">Source bitmap</param>
130+
/// <returns>An 4-dimensional NDArray that holds the bitmap data contained in `ret`</returns>
131+
private static NDArray ReshapeFlatData(NDArray ret, BitmapData bmpData)
132+
{
133+
var colorBytes = bmpData.Stride / bmpData.Width;
134+
var strideWidth = bmpData.Stride / colorBytes; // For odd widths, this width is not equal to bmpData.Width
135+
ret = ret.reshape(1, bmpData.Height, strideWidth, bmpData.Stride / bmpData.Width);
136+
if (strideWidth != bmpData.Width)
137+
{
138+
ret = ret[Slice.All, Slice.All, new Slice(stop: bmpData.Width), new Slice(stop: colorBytes)];
139+
}
140+
141+
return ret;
142+
}
143+
125144
/// <summary>
126145
/// Creates <see cref="NDArray"/> from given <see cref="Image"/>.
127146
/// </summary>

test/NumSharp.UnitTest/NumSharp.Bitmap/BitmapWithAlphaTests.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,15 @@ public void ToNDArray_Case4()
4040
var nd = bitmap.ToNDArray(discardAlpha: false, copy: false);
4141
nd.Should().BeShaped(1, 165, 400, 4);
4242
}
43+
44+
45+
[TestMethod]
46+
public void ToNDArray_Odd_Width()
47+
{
48+
var bitmap = EmbeddedBitmap("odd-width");
49+
var nd = bitmap.ToNDArray(discardAlpha: false, copy: false);
50+
nd.Should().BeShaped(1, 554, 475, 3);
51+
}
4352

4453
[TestMethod]
4554
public void ToNDArray_Case5_flat()
459 KB
Loading

test/NumSharp.UnitTest/NumSharp.UnitTest.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
<EmbeddedResource Remove="data\**" />
2525
<None Remove="Backends\Unmanaged\Iterators\**" />
2626
<None Remove="data\**" />
27+
<None Remove="NumSharp.Bitmap\resources\odd-width.png" />
28+
<EmbeddedResource Include="NumSharp.Bitmap\resources\odd-width.png" />
2729
</ItemGroup>
2830

2931
<ItemGroup>

0 commit comments

Comments
 (0)