11package qupath .ext .imglib2 .accesses ;
22
3- import net .imglib2 .img .basictypeaccess .ByteAccess ;
3+ import net .imglib2 .img .basictypeaccess .array . ByteArray ;
44import net .imglib2 .img .basictypeaccess .volatiles .VolatileAccess ;
55import qupath .ext .imglib2 .SizableDataAccess ;
66import qupath .lib .common .ColorTools ;
77
88import java .awt .image .BufferedImage ;
99import java .awt .image .DataBuffer ;
1010import java .awt .image .DataBufferInt ;
11+ import java .awt .image .Raster ;
1112import java .awt .image .SinglePixelPackedSampleModel ;
1213
1314/**
14- * An {@link ByteAccess } whose elements are computed from an RGB {@link BufferedImage}.
15+ * An {@link ByteArray } whose elements are computed from an RGB {@link BufferedImage}.
1516 * <p>
1617 * The alpha component is not taken into account.
1718 * <p>
18- * This {@link ByteAccess } is immutable; any attempt to changes its values will result in a
19+ * This {@link ByteArray } is immutable; any attempt to changes its values will result in a
1920 * {@link UnsupportedOperationException}.
2021 * <p>
2122 * This data access is marked as volatile but always contain valid data.
2223 */
23- public class ByteBufferedImageAccess implements ByteAccess , SizableDataAccess , VolatileAccess {
24+ public class ByteBufferedImageAccess extends ByteArray implements SizableDataAccess , VolatileAccess {
2425
25- private final BufferedImage image ;
26- private final DataBuffer dataBuffer ;
27- private final int width ;
28- private final int planeSize ;
29- private final boolean canUseDataBuffer ;
3026 private final int size ;
3127
3228 /**
@@ -36,33 +32,9 @@ public class ByteBufferedImageAccess implements ByteAccess, SizableDataAccess, V
3632 * @throws NullPointerException if the provided image is null
3733 */
3834 public ByteBufferedImageAccess (BufferedImage image ) {
39- this .image = image ;
40- this .dataBuffer = this .image .getRaster ().getDataBuffer ();
35+ super (createArrayFromImage (image ));
4136
42- this .width = this .image .getWidth ();
43- this .planeSize = width * this .image .getHeight ();
44-
45- this .canUseDataBuffer = image .getRaster ().getDataBuffer () instanceof DataBufferInt &&
46- image .getRaster ().getSampleModel () instanceof SinglePixelPackedSampleModel ;
47-
48- this .size = AccessTools .getSizeOfDataBufferInBytes (this .dataBuffer );
49- }
50-
51- @ Override
52- public byte getValue (int index ) {
53- int channel = index / planeSize ;
54- int xyIndex = index % planeSize ;
55-
56- int pixel = canUseDataBuffer ?
57- dataBuffer .getElem (0 , xyIndex ) :
58- image .getRGB (xyIndex % width , xyIndex / width );
59-
60- return switch (channel ) {
61- case 0 -> (byte ) ColorTools .red (pixel );
62- case 1 -> (byte ) ColorTools .green (pixel );
63- case 2 -> (byte ) ColorTools .blue (pixel );
64- default -> throw new IllegalArgumentException (String .format ("The provided index %d is out of bounds" , index ));
65- };
37+ this .size = AccessTools .getSizeOfDataBufferInBytes (image .getRaster ().getDataBuffer ());
6638 }
6739
6840 @ Override
@@ -79,4 +51,47 @@ public int getSizeBytes() {
7951 public boolean isValid () {
8052 return true ;
8153 }
54+
55+ private static byte [] createArrayFromImage (BufferedImage image ) {
56+ Raster raster = image .getRaster ();
57+ int width = raster .getWidth ();
58+ int height = raster .getHeight ();
59+ int planeSize = width * height ;
60+ int numBands = 3 ;
61+
62+ byte [] array = new byte [planeSize * numBands ];
63+ if (raster .getSampleModel () instanceof SinglePixelPackedSampleModel && raster .getDataBuffer () instanceof DataBufferInt ) {
64+ DataBuffer dataBuffer = raster .getDataBuffer ();
65+
66+ for (int b =0 ; b <numBands ; b ++) {
67+ for (int i =0 ; i <planeSize ; i ++) {
68+ int pixel = dataBuffer .getElem (0 , i );
69+
70+ array [i + b * planeSize ] = (byte ) switch (b ) {
71+ case 0 -> ColorTools .red (pixel );
72+ case 1 -> ColorTools .green (pixel );
73+ case 2 -> ColorTools .blue (pixel );
74+ default -> throw new IllegalArgumentException (String .format ("The provided channel %d is out of bounds" , b ));
75+ };
76+ }
77+ }
78+ } else {
79+ for (int b =0 ; b <numBands ; b ++) {
80+ for (int y =0 ; y <height ; y ++) {
81+ for (int x =0 ; x <width ; x ++) {
82+ int pixel = image .getRGB (x , y );
83+
84+ array [x + y * width + b * planeSize ] = (byte ) switch (b ) {
85+ case 0 -> ColorTools .red (pixel );
86+ case 1 -> ColorTools .green (pixel );
87+ case 2 -> ColorTools .blue (pixel );
88+ default -> throw new IllegalArgumentException (String .format ("The provided channel %d is out of bounds" , b ));
89+ };
90+ }
91+ }
92+ }
93+ }
94+
95+ return array ;
96+ }
8297}
0 commit comments