BioGTK  5.1.1
A .NET library & program for annotating, editing various microscopy imaging formats using Bioformats supported images.
Loading...
Searching...
No Matches
Bio.ImageUtil Class Reference

Static Public Member Functions

static Image< Rgb24 > JoinRGB24 (IEnumerable< Tuple< Extent, byte[]> > srcPixelTiles, Extent srcPixelExtent, Extent dstPixelExtent)
 Join by srcPixelTiles and cut by srcPixelExtent then scale to dstPixelExtent (only height an width is useful).
 
static Image< L16 > Join16 (IEnumerable< Tuple< Extent, byte[]> > srcPixelTiles, Extent srcPixelExtent, Extent dstPixelExtent)
 Join by srcPixelTiles and cut by srcPixelExtent then scale to dstPixelExtent (only height an width is useful).
 
static unsafe NetVips.Image JoinVipsRGB24 (IEnumerable< Tuple< Extent, byte[]> > srcPixelTiles, Extent srcPixelExtent, Extent dstPixelExtent)
 Join by srcPixelTiles and cut by srcPixelExtent then scale to dstPixelExtent (only height an width is useful).
 
static unsafe NetVips.Image JoinVips16 (IEnumerable< Tuple< Extent, byte[]> > srcPixelTiles, Extent srcPixelExtent, Extent dstPixelExtent)
 Join by srcPixelTiles and cut by srcPixelExtent then scale to dstPixelExtent (only height an width is useful).
 
static SixLabors.ImageSharp.Image CreateImageFromBytes (byte[] rgbBytes, int width, int height, PixelFormat px)
 

Member Function Documentation

◆ CreateImageFromBytes()

static SixLabors.ImageSharp.Image Bio.ImageUtil.CreateImageFromBytes ( byte[]  rgbBytes,
int  width,
int  height,
PixelFormat  px 
)
inlinestatic
274 {
275 if (px == PixelFormat.Format24bppRgb)
276 {
277 if (rgbBytes.Length != width * height * 3)
278 {
279 throw new ArgumentException("Byte array size does not match the dimensions of the image");
280 }
281
282 // Create a new image of the specified size
283 Image<Rgb24> image = new Image<Rgb24>(width, height);
284
285 // Index for the byte array
286 int byteIndex = 0;
287
288 // Iterate over the image pixels
289 for (int y = 0; y < height; y++)
290 {
291 for (int x = 0; x < width; x++)
292 {
293 // Create a color from the next three bytes
294 Rgb24 color = new Rgb24(rgbBytes[byteIndex], rgbBytes[byteIndex + 1], rgbBytes[byteIndex + 2]);
295 byteIndex += 3;
296 // Set the pixel
297 image[x, y] = color;
298 }
299 }
300
301 return image;
302 }
303 else
304 if (px == PixelFormat.Format16bppGrayScale)
305 {
306 if (rgbBytes.Length != width * height * 2)
307 {
308 throw new ArgumentException("Byte array size does not match the dimensions of the image");
309 }
310
311 // Create a new image of the specified size
312 Image<L16> image = new Image<L16>(width, height);
313
314 // Index for the byte array
315 int byteIndex = 0;
316
317 // Iterate over the image pixels
318 for (int y = 0; y < height; y++)
319 {
320 for (int x = 0; x < width; x++)
321 {
322 // Create a color from the next three bytes
323 L16 color = new L16(BitConverter.ToUInt16(rgbBytes, byteIndex));
324 byteIndex += 2;
325 // Set the pixel
326 image[x, y] = color;
327 }
328 }
329
330 return image;
331 }
332 else
333 if (px == PixelFormat.Format32bppArgb)
334 {
335 if (rgbBytes.Length != width * height * 4)
336 {
337 throw new ArgumentException("Byte array size does not match the dimensions of the image");
338 }
339
340 // Create a new image of the specified size
341 Image<Bgra32> image = new Image<Bgra32>(width, height);
342
343 // Index for the byte array
344 int byteIndex = 0;
345
346 // Iterate over the image pixels
347 for (int y = 0; y < height; y++)
348 {
349 for (int x = 0; x < width; x++)
350 {
351 // Create a color from the next three bytes
352 Bgra32 color = new Bgra32(rgbBytes[byteIndex], rgbBytes[byteIndex + 1], rgbBytes[byteIndex + 2], rgbBytes[byteIndex + 3]);
353 byteIndex += 4;
354 // Set the pixel
355 image[x, y] = color;
356 }
357 }
358
359 return image;
360 }
361 return null;
362 }
SixLabors.ImageSharp.Image Image
Definition ISlideSource.cs:11

◆ Join16()

static Image< L16 > Bio.ImageUtil.Join16 ( IEnumerable< Tuple< Extent, byte[]> >  srcPixelTiles,
Extent  srcPixelExtent,
Extent  dstPixelExtent 
)
inlinestatic

Join by srcPixelTiles and cut by srcPixelExtent then scale to dstPixelExtent (only height an width is useful).

Parameters
srcPixelTilestile with tile extent collection
srcPixelExtentcanvas extent
dstPixelExtentjpeg output size
Returns
93 {
94 if (srcPixelTiles == null || srcPixelTiles.Count() == 0)
95 return null;
96 srcPixelExtent = srcPixelExtent.ToIntegerExtent();
97 dstPixelExtent = dstPixelExtent.ToIntegerExtent();
98 int canvasWidth = (int)srcPixelExtent.Width;
99 int canvasHeight = (int)srcPixelExtent.Height;
100 var dstWidth = (int)dstPixelExtent.Width;
101 var dstHeight = (int)dstPixelExtent.Height;
102 Image<L16> canvas = new Image<L16>(canvasWidth, canvasHeight);
103 foreach (var tile in srcPixelTiles)
104 {
105 try
106 {
107 var tileExtent = tile.Item1.ToIntegerExtent();
108 var intersect = srcPixelExtent.Intersect(tileExtent);
109 if (intersect.Width == 0 || intersect.Height == 0)
110 continue;
111 if (tile.Item2 == null)
112 continue;
113 Image<L16> tileRawData = (Image<L16>)CreateImageFromBytes(tile.Item2, (int)tileExtent.Width, (int)tileExtent.Height, PixelFormat.Format16bppGrayScale);
114 var tileOffsetPixelX = (int)Math.Ceiling(intersect.MinX - tileExtent.MinX);
115 var tileOffsetPixelY = (int)Math.Ceiling(intersect.MinY - tileExtent.MinY);
116 var canvasOffsetPixelX = (int)Math.Ceiling(intersect.MinX - srcPixelExtent.MinX);
117 var canvasOffsetPixelY = (int)Math.Ceiling(intersect.MinY - srcPixelExtent.MinY);
118 //We copy the tile region to the canvas.
119 for (int y = 0; y < intersect.Height; y++)
120 {
121 for (int x = 0; x < intersect.Width; x++)
122 {
123 int indx = canvasOffsetPixelX + x;
124 int indy = canvasOffsetPixelY + y;
125 int tindx = tileOffsetPixelX + x;
126 int tindy = tileOffsetPixelY + y;
127 canvas[indx, indy] = tileRawData[tindx, tindy];
128 }
129 }
130 tileRawData.Dispose();
131 }
132 catch (Exception e)
133 {
134 Console.WriteLine(e.ToString());
135 }
136
137 }
138 if (dstWidth != canvasWidth || dstHeight != canvasHeight)
139 {
140 try
141 {
142 canvas.Mutate(x => x.Resize(dstWidth, dstHeight));
143 return canvas;
144 }
145 catch (Exception e)
146 {
147 Console.WriteLine(e.Message);
148 }
149
150 }
151 return canvas;
152 }
static SixLabors.ImageSharp.Image CreateImageFromBytes(byte[] rgbBytes, int width, int height, PixelFormat px)
Definition Utilities.cs:273

◆ JoinRGB24()

static Image< Rgb24 > Bio.ImageUtil.JoinRGB24 ( IEnumerable< Tuple< Extent, byte[]> >  srcPixelTiles,
Extent  srcPixelExtent,
Extent  dstPixelExtent 
)
inlinestatic

Join by srcPixelTiles and cut by srcPixelExtent then scale to dstPixelExtent (only height an width is useful).

Parameters
srcPixelTilestile with tile extent collection
srcPixelExtentcanvas extent
dstPixelExtentjpeg output size
Returns
24 {
25 if (srcPixelTiles == null || srcPixelTiles.Count() == 0)
26 return null;
27 srcPixelExtent = srcPixelExtent.ToIntegerExtent();
28 dstPixelExtent = dstPixelExtent.ToIntegerExtent();
29 int canvasWidth = (int)srcPixelExtent.Width;
30 int canvasHeight = (int)srcPixelExtent.Height;
31 var dstWidth = (int)dstPixelExtent.Width;
32 var dstHeight = (int)dstPixelExtent.Height;
33 Image<Rgb24> canvas = new Image<Rgb24>(canvasWidth, canvasHeight);
34 foreach (var tile in srcPixelTiles)
35 {
36 try
37 {
38 var tileExtent = tile.Item1.ToIntegerExtent();
39 var intersect = srcPixelExtent.Intersect(tileExtent);
40 if (intersect.Width == 0 || intersect.Height == 0)
41 continue;
42 if(tile.Item2 == null)
43 continue;
44 Image<Rgb24> tileRawData = (Image<Rgb24>)CreateImageFromBytes(tile.Item2, (int)tileExtent.Width, (int)tileExtent.Height,PixelFormat.Format24bppRgb);
45 var tileOffsetPixelX = (int)Math.Ceiling(intersect.MinX - tileExtent.MinX);
46 var tileOffsetPixelY = (int)Math.Ceiling(intersect.MinY - tileExtent.MinY);
47 var canvasOffsetPixelX = (int)Math.Ceiling(intersect.MinX - srcPixelExtent.MinX);
48 var canvasOffsetPixelY = (int)Math.Ceiling(intersect.MinY - srcPixelExtent.MinY);
49 //We copy the tile region to the canvas.
50 for (int y = 0; y < intersect.Height; y++)
51 {
52 for (int x = 0; x < intersect.Width; x++)
53 {
54 int indx = canvasOffsetPixelX + x;
55 int indy = canvasOffsetPixelY + y;
56 int tindx = tileOffsetPixelX + x;
57 int tindy = tileOffsetPixelY + y;
58 canvas[indx, indy] = tileRawData[tindx, tindy];
59 }
60 }
61 tileRawData.Dispose();
62 }
63 catch (Exception e)
64 {
65 Console.WriteLine(e.ToString());
66 }
67
68 }
69 if (dstWidth != canvasWidth || dstHeight != canvasHeight)
70 {
71 try
72 {
73 canvas.Mutate(x => x.Resize(dstWidth, dstHeight));
74 return canvas;
75 }
76 catch (Exception e)
77 {
78 Console.WriteLine(e.Message);
79 }
80
81 }
82 return canvas;
83 }

◆ JoinVips16()

static unsafe NetVips.Image Bio.ImageUtil.JoinVips16 ( IEnumerable< Tuple< Extent, byte[]> >  srcPixelTiles,
Extent  srcPixelExtent,
Extent  dstPixelExtent 
)
inlinestatic

Join by srcPixelTiles and cut by srcPixelExtent then scale to dstPixelExtent (only height an width is useful).

Parameters
srcPixelTilestile with tile extent collection
srcPixelExtentcanvas extent
dstPixelExtentjpeg output size
Returns
221 {
222 if (srcPixelTiles == null || !srcPixelTiles.Any())
223 return null;
224
225 srcPixelExtent = srcPixelExtent.ToIntegerExtent();
226 dstPixelExtent = dstPixelExtent.ToIntegerExtent();
227 int canvasWidth = (int)srcPixelExtent.Width;
228 int canvasHeight = (int)srcPixelExtent.Height;
229
230 // Create a base canvas. Adjust as necessary, for example, using a transparent image if needed.
231 Bitmap bf = new Bitmap(canvasWidth, canvasHeight, PixelFormat.Format16bppGrayScale);
232 NetVips.Image canvas = NetVips.Image.NewFromMemory(bf.Bytes, bf.SizeX, bf.SizeX, 1, Enums.BandFormat.Ushort);
233
234 foreach (var tile in srcPixelTiles)
235 {
236 if (tile.Item2 == null)
237 continue;
238
239 fixed (byte* pTileData = tile.Item2)
240 {
241 var tileExtent = tile.Item1.ToIntegerExtent();
242 NetVips.Image tileImage = NetVips.Image.NewFromMemory((IntPtr)pTileData, (ulong)tile.Item2.Length, (int)tileExtent.Width, (int)tileExtent.Height, 1, Enums.BandFormat.Ushort);
243
244 // Calculate positions and sizes for cropping and inserting
245 var intersect = srcPixelExtent.Intersect(tileExtent);
246 if (intersect.Width == 0 || intersect.Height == 0)
247 continue;
248
249 int tileOffsetPixelX = (int)Math.Ceiling(intersect.MinX - tileExtent.MinX);
250 int tileOffsetPixelY = (int)Math.Ceiling(intersect.MinY - tileExtent.MinY);
251 int canvasOffsetPixelX = (int)Math.Ceiling(intersect.MinX - srcPixelExtent.MinX);
252 int canvasOffsetPixelY = (int)Math.Ceiling(intersect.MinY - srcPixelExtent.MinY);
253
254 using (var croppedTile = tileImage.Crop(tileOffsetPixelX, tileOffsetPixelY, (int)intersect.Width, (int)intersect.Height))
255 {
256 // Instead of inserting directly, we composite over the base canvas
257 canvas = canvas.Composite2(croppedTile, Enums.BlendMode.Over, canvasOffsetPixelX, canvasOffsetPixelY);
258 }
259 }
260 }
261
262 // Resize if the destination extent differs from the source canvas size
263 if ((int)dstPixelExtent.Width != canvasWidth || (int)dstPixelExtent.Height != canvasHeight)
264 {
265 double scaleX = (double)dstPixelExtent.Width / canvasWidth;
266 double scaleY = (double)dstPixelExtent.Height / canvasHeight;
267 canvas = canvas.Resize(scaleX, vscale: scaleY, kernel: Enums.Kernel.Nearest);
268 }
269
270 return canvas;
271 }
AForge.Bitmap Bitmap
Definition Bio.cs:21
@ Nearest
Nearest.

◆ JoinVipsRGB24()

static unsafe NetVips.Image Bio.ImageUtil.JoinVipsRGB24 ( IEnumerable< Tuple< Extent, byte[]> >  srcPixelTiles,
Extent  srcPixelExtent,
Extent  dstPixelExtent 
)
inlinestatic

Join by srcPixelTiles and cut by srcPixelExtent then scale to dstPixelExtent (only height an width is useful).

Parameters
srcPixelTilestile with tile extent collection
srcPixelExtentcanvas extent
dstPixelExtentjpeg output size
Returns
162 {
163 if (srcPixelTiles == null || !srcPixelTiles.Any())
164 return null;
165
166 srcPixelExtent = srcPixelExtent.ToIntegerExtent();
167 dstPixelExtent = dstPixelExtent.ToIntegerExtent();
168 int canvasWidth = (int)srcPixelExtent.Width;
169 int canvasHeight = (int)srcPixelExtent.Height;
170
171 // Create a base canvas. Adjust as necessary, for example, using a transparent image if needed.
172 NetVips.Image canvas = NetVips.Image.Black(canvasWidth, canvasHeight, bands: 3);
173
174 foreach (var tile in srcPixelTiles)
175 {
176 if (tile.Item2 == null)
177 continue;
178
179 fixed (byte* pTileData = tile.Item2)
180 {
181 var tileExtent = tile.Item1.ToIntegerExtent();
182 NetVips.Image tileImage = NetVips.Image.NewFromMemory((IntPtr)pTileData, (ulong)tile.Item2.Length, (int)tileExtent.Width, (int)tileExtent.Height, 3, Enums.BandFormat.Uchar);
183
184 // Calculate positions and sizes for cropping and inserting
185 var intersect = srcPixelExtent.Intersect(tileExtent);
186 if (intersect.Width == 0 || intersect.Height == 0)
187 continue;
188
189 int tileOffsetPixelX = (int)Math.Ceiling(intersect.MinX - tileExtent.MinX);
190 int tileOffsetPixelY = (int)Math.Ceiling(intersect.MinY - tileExtent.MinY);
191 int canvasOffsetPixelX = (int)Math.Ceiling(intersect.MinX - srcPixelExtent.MinX);
192 int canvasOffsetPixelY = (int)Math.Ceiling(intersect.MinY - srcPixelExtent.MinY);
193
194 using (var croppedTile = tileImage.Crop(tileOffsetPixelX, tileOffsetPixelY, (int)intersect.Width, (int)intersect.Height))
195 {
196 // Instead of inserting directly, we composite over the base canvas
197 canvas = canvas.Composite2(croppedTile, Enums.BlendMode.Over, canvasOffsetPixelX, canvasOffsetPixelY);
198 }
199 }
200 }
201
202 // Resize if the destination extent differs from the source canvas size
203 if ((int)dstPixelExtent.Width != canvasWidth || (int)dstPixelExtent.Height != canvasHeight)
204 {
205 double scaleX = (double)dstPixelExtent.Width / canvasWidth;
206 double scaleY = (double)dstPixelExtent.Height / canvasHeight;
207 canvas = canvas.Resize(scaleX, vscale: scaleY, kernel: Enums.Kernel.Nearest);
208 }
209
210 return canvas;
211 }

The documentation for this class was generated from the following file: