8
8
using SixLabors . ImageSharp ;
9
9
using SixLabors . ImageSharp . PixelFormats ;
10
10
using AForge ;
11
+ using Image = SixLabors . ImageSharp . Image ;
11
12
namespace BioImager
12
13
{
13
14
public class LruCache < TileInformation , TValue >
@@ -62,6 +63,13 @@ public void Add(Info key, TValue value)
62
63
lruList . AddLast ( newNode ) ;
63
64
cacheMap [ key ] = newNode ;
64
65
}
66
+ public void Dispose ( )
67
+ {
68
+ foreach ( LinkedListNode < ( Info key , TValue value ) > item in cacheMap . Values )
69
+ {
70
+ lruList . Remove ( item ) ;
71
+ }
72
+ }
65
73
}
66
74
public class TileCache
67
75
{
@@ -110,6 +118,10 @@ private async Task<byte[]> LoadTile(TileInformation tileId)
110
118
return null ;
111
119
}
112
120
}
121
+ public void Dispose ( )
122
+ {
123
+ cache . Dispose ( ) ;
124
+ }
113
125
}
114
126
115
127
public class TileInformation
@@ -160,7 +172,6 @@ public static ISlideSource Create(BioImage source, SlideImage im, bool enableCac
160
172
}
161
173
#endregion
162
174
public double MinUnitsPerPixel { get ; protected set ; }
163
- public static byte [ ] LastSlice ;
164
175
public static Extent destExtent ;
165
176
public static Extent sourceExtent ;
166
177
public static double curUnitsPerPixel = 1 ;
@@ -194,9 +205,12 @@ public async Task<byte[]> GetSlice(SliceInfo sliceInfo)
194
205
{
195
206
try
196
207
{
197
- NetVips . Image im = OpenSlideGTK . ImageUtil . JoinVips ( tiles , srcPixelExtent , new Extent ( 0 , 0 , dstPixelWidth , dstPixelHeight ) ) ;
198
- LastSlice = im . WriteToMemory ( ) ;
199
- return LastSlice ;
208
+ NetVips . Image im = null ;
209
+ if ( this . Image . BioImage . Resolutions [ curLevel ] . PixelFormat == PixelFormat . Format16bppGrayScale )
210
+ im = ImageUtil . JoinVips16 ( tiles , srcPixelExtent , new Extent ( 0 , 0 , dstPixelWidth , dstPixelHeight ) ) ;
211
+ else if ( this . Image . BioImage . Resolutions [ curLevel ] . PixelFormat == PixelFormat . Format24bppRgb )
212
+ im = ImageUtil . JoinVipsRGB24 ( tiles , srcPixelExtent , new Extent ( 0 , 0 , dstPixelWidth , dstPixelHeight ) ) ;
213
+ return im . WriteToMemory ( ) ;
200
214
}
201
215
catch ( Exception e )
202
216
{
@@ -207,16 +221,28 @@ public async Task<byte[]> GetSlice(SliceInfo sliceInfo)
207
221
}
208
222
try
209
223
{
210
- Image < Rgb24 > im = OpenSlideGTK . ImageUtil . Join ( tiles , srcPixelExtent , new Extent ( 0 , 0 , dstPixelWidth , dstPixelHeight ) ) ;
211
- LastSlice = GetRgb24Bytes ( im ) ;
212
- im . Dispose ( ) ;
224
+ Image im = null ;
225
+ if ( this . Image . BioImage . Resolutions [ curLevel ] . PixelFormat == PixelFormat . Format16bppGrayScale )
226
+ {
227
+ im = ImageUtil . Join16 ( tiles , srcPixelExtent , new Extent ( 0 , 0 , dstPixelWidth , dstPixelHeight ) ) ;
228
+ byte [ ] bts = Get16Bytes ( ( Image < L16 > ) im ) ;
229
+ im . Dispose ( ) ;
230
+ return bts ;
231
+ }
232
+ else if ( this . Image . BioImage . Resolutions [ curLevel ] . PixelFormat == PixelFormat . Format24bppRgb )
233
+ {
234
+ im = ImageUtil . JoinRGB24 ( tiles , srcPixelExtent , new Extent ( 0 , 0 , dstPixelWidth , dstPixelHeight ) ) ;
235
+ byte [ ] bts = GetRgb24Bytes ( ( Image < Rgb24 > ) im ) ;
236
+ im . Dispose ( ) ;
237
+ return bts ;
238
+ }
213
239
}
214
240
catch ( Exception er )
215
241
{
216
242
Console . WriteLine ( er . Message ) ;
217
243
return null ;
218
244
}
219
- return LastSlice ;
245
+ return null ;
220
246
}
221
247
public byte [ ] GetRgb24Bytes ( Image < Rgb24 > image )
222
248
{
@@ -230,14 +256,34 @@ public byte[] GetRgb24Bytes(Image<Rgb24> image)
230
256
for ( int x = 0 ; x < width ; x ++ )
231
257
{
232
258
Rgb24 pixel = image [ x , y ] ;
233
- rgbBytes [ byteIndex ++ ] = pixel . R ;
234
- rgbBytes [ byteIndex ++ ] = pixel . G ;
235
259
rgbBytes [ byteIndex ++ ] = pixel . B ;
260
+ rgbBytes [ byteIndex ++ ] = pixel . G ;
261
+ rgbBytes [ byteIndex ++ ] = pixel . R ;
236
262
}
237
263
}
238
264
239
265
return rgbBytes ;
240
266
}
267
+ public byte [ ] Get16Bytes ( Image < L16 > image )
268
+ {
269
+ int width = image . Width ;
270
+ int height = image . Height ;
271
+ byte [ ] bytes = new byte [ width * height * 2 ] ;
272
+
273
+ int byteIndex = 0 ;
274
+ for ( int y = 0 ; y < height ; y ++ )
275
+ {
276
+ for ( int x = 0 ; x < width ; x ++ )
277
+ {
278
+ L16 pixel = image [ x , y ] ;
279
+ byte [ ] bts = BitConverter . GetBytes ( pixel . PackedValue ) ;
280
+ bytes [ byteIndex ++ ] = bts [ 0 ] ;
281
+ bytes [ byteIndex ++ ] = bts [ 1 ] ;
282
+ }
283
+ }
284
+
285
+ return bytes ;
286
+ }
241
287
242
288
public SlideImage Image { get ; set ; }
243
289
@@ -291,11 +337,7 @@ public async Task<byte[]> GetTileAsync(TileInformation tileInfo)
291
337
var curTileWidth = ( int ) ( tileInfo . Extent . MaxX > Schema . Extent . Width ? tileWidth - ( tileInfo . Extent . MaxX - Schema . Extent . Width ) / r : tileWidth ) ;
292
338
var curTileHeight = ( int ) ( - tileInfo . Extent . MinY > Schema . Extent . Height ? tileHeight - ( - tileInfo . Extent . MinY - Schema . Extent . Height ) / r : tileHeight ) ;
293
339
var bgraData = await Image . ReadRegionAsync ( tileInfo . Index . Level , ( long ) curLevelOffsetXPixel , ( long ) curLevelOffsetYPixel , curTileWidth , curTileHeight , tileInfo . Coordinate ) ;
294
- //We check to see if the data is valid.
295
- if ( bgraData . Length != curTileWidth * curTileHeight * 4 )
296
- return null ;
297
- byte [ ] bm = ConvertRgbaToRgb ( bgraData ) ;
298
- return bm ;
340
+ return bgraData ;
299
341
}
300
342
public async Task < byte [ ] > GetTileAsync ( BruTile . TileInfo tileInfo )
301
343
{
@@ -309,11 +351,7 @@ public async Task<byte[]> GetTileAsync(BruTile.TileInfo tileInfo)
309
351
var curTileWidth = ( int ) ( tileInfo . Extent . MaxX > Schema . Extent . Width ? tileWidth - ( tileInfo . Extent . MaxX - Schema . Extent . Width ) / r : tileWidth ) ;
310
352
var curTileHeight = ( int ) ( - tileInfo . Extent . MinY > Schema . Extent . Height ? tileHeight - ( - tileInfo . Extent . MinY - Schema . Extent . Height ) / r : tileHeight ) ;
311
353
var bgraData = await Image . ReadRegionAsync ( tileInfo . Index . Level , ( long ) curLevelOffsetXPixel , ( long ) curLevelOffsetYPixel , curTileWidth , curTileHeight , new ZCT ( ) ) ;
312
- //We check to see if the data is valid.
313
- if ( bgraData . Length != curTileWidth * curTileHeight * 4 )
314
- return null ;
315
- byte [ ] bm = ConvertRgbaToRgb ( bgraData ) ;
316
- return bm ;
354
+ return bgraData ;
317
355
}
318
356
public static byte [ ] ConvertRgbaToRgb ( byte [ ] rgbaArray )
319
357
{
0 commit comments