Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

268
LINES

< > BotCompany Repo | #1004247 // BWImage (8 bit grayscale)

JavaX fragment (include) [tags: use-pretranspiled]

Libraryless. Click here for Pure Java version (10724L/61K).

1  
static final class BWImage extends Meta implements MakesBufferedImage, IBWImage {
2  
  int width, height;
3  
  byte[] pixels;
4  
5  
  // color returned when getPixel is called with a position outside the actual image
6  
  float borderColor = 0.0f;
7  
  
8  
  // for unstructure()
9  
  *() {}
10  
11  
  // BLACK!
12  
  *(int *width, int *height) {
13  
    pixels = new byte[width*height];
14  
  }
15  
16  
  *(int *width, int *height, float brightness) {
17  
    pixels = new byte[width*height];
18  
    fillArrayUnlessZero(pixels, _toByte(brightness));
19  
  }
20  
  
21  
  *(int *width, int *height, float[] pixels) {
22  
    this.pixels = new byte[pixels.length];
23  
    for (int i = 0; i < pixels.length; i++)
24  
      this.pixels[i] = _toByte(pixels[i]);
25  
  }
26  
27  
  public BWImage(int width, int height, byte[] pixels) {
28  
    this.height = height;
29  
    this.width = width;
30  
    this.pixels = pixels;
31  
  }
32  
33  
  public BWImage(BWImage image) {
34  
    width = image.getWidth();
35  
    height = image.getHeight();
36  
    byte[] pixels = this.pixels = new byte[width*height];
37  
    for (int y = 0; y < height; y++)
38  
      for (int x = 0; x < width; x++)
39  
        pixels[y*width+x] = image.getByte(x, y);
40  
  }
41  
42  
  // TODO: optimize!
43  
  *(RGBImage image) {
44  
    width = image.getWidth();
45  
    height = image.getHeight();
46  
    byte[] pixels = this.pixels = new byte[height*width];
47  
    for (int y = 0; y < height; y++)
48  
      for (int x = 0; x < width; x++) {
49  
        RGB rgb = image.getRGB(x, y);
50  
        pixels[y*width+x] = BWImage._toByte(rgb.getBrightness());
51  
      }
52  
  }
53  
54  
  /*public BWImage(BufferedImage image) {
55  
    this(new RGBImage(image));
56  
  }*/
57  
58  
  *(BufferedImage image) ctex {
59  
    width = image.getWidth();
60  
    height = image.getHeight();
61  
    int[] pixels = new int[width*height];
62  
    byte[] bytePixels = this.pixels = new byte[width*height];
63  
    PixelGrabber pixelGrabber = new PixelGrabber(image, 0, 0, width, height, pixels, 0, width);
64  
    if (!pixelGrabber.grabPixels())
65  
      fail("Could not grab pixels");
66  
    int n = width*height;
67  
    
68  
    for (int i = 0; i < n; i++) {
69  
      //bytePixels[i] = pixelToByte(pixels[i]);
70  
      int packed = pixels[i];
71  
      /*float r = ((packed >> 16) & 0xFF)/255f;
72  
      float g = ((packed >> 8) & 0xFF)/255f;
73  
      float b = (packed & 0xFF)/255f;
74  
      bytePixels[i] = (byte) iround((r+g+b)/3.0f*255f);*/
75  
      int r = ((packed >> 16) & 0xFF);
76  
      int g = ((packed >> 8) & 0xFF);
77  
      int b = (packed & 0xFF);
78  
      bytePixels[i] = (byte) ((r+g+b+1)/3);
79  
    }
80  
  }
81  
  
82  
  // TODO: does it exactly match the other method? (asRGB+getBrightness+_toByte)
83  
  static byte pixelToByte(int packed) {
84  
    /*int r = (packed >> 16) & 0xFF;
85  
    int g = (packed >> 8) & 0xFF;
86  
    int b = packed & 0xFF;
87  
    ret (byte) ((r+g+b)/3.0f);*/
88  
    float r = ((packed >> 16) & 0xFF)/255f;
89  
    float g = ((packed >> 8) & 0xFF)/255f;
90  
    float b = (packed & 0xFF)/255f;
91  
    ret (byte) ((r+g+b)/3.0f*255f);
92  
  }
93  
94  
  public byte getByte(int x, int y) {
95  
    return inRange(x, y) ? getByte_noRangeCheck(x, y) : _toByte(borderColor);
96  
  }
97  
  
98  
  // pretty bad function name
99  
  // gets brightness (0 to 255) at pixel
100  
  public int getInt(int x, int y) {
101  
    ret ubyteToInt(getByte(x, y));
102  
  }
103  
  
104  
  // idx = index in pixel array
105  
  public int getInt_noRangeCheck(int idx) {
106  
    ret ubyteToInt(pixels[idx]);
107  
  }
108  
  
109  
  // gets brightness (0 to 255) at pixel with default if out of image
110  
  public int getInt(int x, int y, int defaultValue) {
111  
    ret inRange(x, y) ? getInt(x, y) : defaultValue;
112  
  }
113  
  
114  
  public double averageBrightness() {
115  
    double sum = 0;
116  
    int n = width*height;
117  
    for i to n:
118  
      sum += getInt_noRangeCheck(i);
119  
    ret sum/n;
120  
  }
121  
122  
  public float minimumBrightness() {
123  
    float min = 1;
124  
    for (int y = 0; y < height; y++)
125  
      for (int x = 0; x < width; x++)
126  
        min = Math.min(min, getPixel(x, y));
127  
    return min;
128  
  }
129  
130  
  public float maximumBrightness() {
131  
    float max = 0;
132  
    for (int y = 0; y < height; y++)
133  
      for (int x = 0; x < width; x++)
134  
        max = Math.max(max, getPixel(x, y));
135  
    return max;
136  
  }
137  
138  
  float getPixel(int x, int y) {
139  
    return inRange(x, y) ? _toFloat(getByte(x,y )) : borderColor;
140  
  }
141  
  
142  
  public float getFloatPixel(int x, int y) { ret getPixel(x, y); }
143  
  
144  
  float getPixel(Pt p) { ret getPixel(p.x, p.y); }
145  
146  
  static byte _toByte(float pixel) {
147  
    return (byte) (pixel*255f);
148  
  }
149  
150  
  static float _toFloat(byte pixel) {
151  
    return (((int) pixel) & 255)/255f;
152  
  }
153  
154  
  private boolean inRange(int x, int y) {
155  
    return x >= 0 && x < width && y >= 0 && y < height;
156  
  }
157  
158  
  public int getWidth() { return width; }
159  
  public int getHeight() { return height; }
160  
161  
  public RGBImage toRGB() {
162  
    int[] rgbs = new int[width*height];
163  
    for (int y = 0; y < height; y++)
164  
      for (int x = 0; x < width; x++) {
165  
        int b = getByte(x, y) & 0xFF;
166  
        rgbs[y*width+x] = 0xFF000000 | b*0x010101;
167  
      }
168  
    return new RGBImage(width, height, rgbs);
169  
  }
170  
  
171  
  public RGBImage toRGB_slow() {
172  
    RGB[] rgbs = new RGB[width*height];
173  
    for (int y = 0; y < height; y++)
174  
      for (int x = 0; x < width; x++) {
175  
        float p = getPixel(x, y);
176  
        rgbs[y*width+x] = new RGB(p, p, p);
177  
      }
178  
    return new RGBImage(width, height, rgbs);
179  
  }
180  
181  
182  
  public BWImage clip(int x, int y, int w, int h) {
183  
    return clip(new Rectangle(x, y, w, h));
184  
  }
185  
186  
  private Rectangle fixClipRect(Rectangle r) {
187  
    return r.intersection(new Rectangle(0, 0, width, height));
188  
  }
189  
190  
  BWImage clip(Rect r) {
191  
    ret clip(r.getRectangle());
192  
  }
193  
  
194  
  /** this should be multithread-safe */
195  
  public BWImage clip(Rectangle r) {
196  
    r = fixClipRect(r);
197  
    byte[] newPixels = new byte[r.height*r.width];
198  
    for (int y = 0; y < r.height; y++)
199  
      for (int x = 0; x < r.width; x++)
200  
        newPixels[y*r.width+x] = getByte(r.x+x, r.y+y);
201  
    return new BWImage(r.width, r.height, newPixels);
202  
  }
203  
204  
  public void setPixel(int x, int y, float brightness) {
205  
    setByte(x, y, _toByte(fixPixel(brightness)));
206  
  }
207  
  
208  
  // i = 0 to 255
209  
  public void setInt(int x, int y, int i) {
210  
    setByte(x, y, (byte) limitToUByte(i));
211  
  }
212  
  
213  
  public void setInt(Pt p, int i) {
214  
    setInt(p.x, p.y, i);
215  
  }
216  
  
217  
  public void setByte(int x, int y, byte b) {
218  
    if (x >= 0 && x < width && y >= 0 && y < height)
219  
      pixels[y*width+x] = b;
220  
  }
221  
222  
  byte getByte_noRangeCheck(int x, int y) {
223  
    return pixels[y*width+x];
224  
  }
225  
226  
  public void setByte(int x, int y, int brightness) {
227  
    setByte(x, y, (byte) brightness);
228  
  }
229  
230  
  private float fixPixel(float pixel) {
231  
    return Math.max(0, Math.min(1, pixel));
232  
  }
233  
234  
  public float getBorderColor() {
235  
    return borderColor;
236  
  }
237  
238  
  public void setBorderColor(float borderColor) {
239  
    this.borderColor = borderColor;
240  
  }
241  
242  
  public boolean anyPixelBrighterThan(double threshold) {
243  
    for (int y = 0; y < height; y++)
244  
      for (int x = 0; x < width; x++)
245  
        if (getPixel(x, y) > threshold)
246  
          return true;
247  
    return false;
248  
  }
249  
  
250  
  int[] getRGBPixels() {
251  
    int n = width*height;
252  
    int[] out = new[n];
253  
    for i to n: {
254  
      var b = ubyteToInt(pixels[i]);
255  
      b |= (b << 8) | (b << 16);
256  
      out[i] = b | 0xFF000000;
257  
    }
258  
    ret out;
259  
  }
260  
  
261  
  public BufferedImage getBufferedImage() {
262  
    ret bufferedImage(getRGBPixels(), width, height);
263  
  }
264  
  
265  
  byte[] getBytes() {
266  
    ret pixels;
267  
  }
268  
}

download  show line numbers  debug dex  old transpilations   

Travelled to 20 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, ddnzoavkxhuk, gwrvuhgaqvyk, irmadwmeruwu, ishqpsrjomds, lpdgvwnxivlt, mowyntqkapby, mqqgnosmbjvj, ofpaelxlmzfo, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, sawdedvomwva, tslmcundralx, tvejysmllsmz, vouqrxazstgt, xrpafgyirdlv

No comments. add comment

Snippet ID: #1004247
Snippet name: BWImage (8 bit grayscale)
Eternal ID of this version: #1004247/40
Text MD5: bec097e59aadd3a79597341d9837dc8e
Transpilation MD5: 64916b5bedf5faa1a3393fbced4fb2a5
Author: stefan
Category: javax / imaging
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-07-21 19:02:58
Source code size: 7431 bytes / 268 lines
Pitched / IR pitched: No / No
Views / Downloads: 1034 / 5688
Version history: 39 change(s)
Referenced in: [show references]