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

272
LINES

< > BotCompany Repo | #1016912 // class BWImage with BWImageSimpleStorage (old)

JavaX fragment (include)

static class BWImage implements MakesBufferedImage {
  private int width, height;
  private BWImageSimpleStorage storage;

  // color returned when getPixel is called with a position outside the actual image
  private float borderColor = 0.0f;
  
  // for unstructure()
  BWImage() {}

  // BLACK! [Inefficient...]
  public BWImage(int width, int height) {
    this.width = width;
    this.height = height;
    byte[] bytePixels = new byte[width*height];
    storage = makeStorage(width, height, bytePixels);
  }

  public BWImage(int width, int height, float[] pixels) {
    this.width = width;
    this.height = height;
    byte[] bytePixels = new byte[pixels.length];
    for (int i = 0; i < pixels.length; i++)
      bytePixels[i] = toByte(pixels[i]);
    storage = makeStorage(width, height, bytePixels);
  }

  private BWImageSimpleStorage makeStorage(int width, int height, byte[] bytePixels) {
    return new BWImageSimpleStorage(width, height, bytePixels);
  }

  public BWImage(int width, int height, byte[] pixels) {
    this.height = height;
    this.width = width;
    storage = makeStorage(width, height, pixels);
  }

  public BWImage(BWImage image) {
    width = image.getWidth();
    height = image.getHeight();
    byte[] bytePixels = new byte[width*height];
    for (int y = 0; y < height; y++)
      for (int x = 0; x < width; x++)
        bytePixels[y*width+x] = image.getByte(x, y);
    storage = makeStorage(width, height, bytePixels);
  }

  public BWImage(RGBImage image) {
    width = image.getWidth();
    height = image.getHeight();
    byte[] result = new byte[height*width];
    for (int y = 0; y < height; y++)
      for (int x = 0; x < width; x++) {
        RGB rgb = image.getRGB(x, y);
        result[y*width+x] = BWImage.toByte(rgb.getBrightness());
      }
    storage = makeStorage(width, height, result);
  }

  /*public BWImage(BufferedImage image) {
    this(new RGBImage(image));
  }*/

  *(BufferedImage image) ctex {
 width = image.getWidth();
    height = image.getHeight();
    int[] pixels = new int[width*height];
    byte[] bytePixels = new byte[width*height];
    PixelGrabber pixelGrabber = new PixelGrabber(image, 0, 0, width, height, pixels, 0, width);
    if (!pixelGrabber.grabPixels())
      fail("Could not grab pixels");
    int n = width*height;
    
    for (int i = 0; i < n; i++) {
      //bytePixels[i] = pixelToByte(pixels[i]);
      int packed = pixels[i];
      /*float r = ((packed >> 16) & 0xFF)/255f;
      float g = ((packed >> 8) & 0xFF)/255f;
      float b = (packed & 0xFF)/255f;
      bytePixels[i] = (byte) iround((r+g+b)/3.0f*255f);*/
      int r = ((packed >> 16) & 0xFF);
      int g = ((packed >> 8) & 0xFF);
      int b = (packed & 0xFF);
      bytePixels[i] = (byte) ((r+g+b+1)/3);
    }
    storage = makeStorage(width, height, bytePixels);
  }
  
  // TODO: does it exactly match the other method? (asRGB+getBrightness+toByte)
  static byte pixelToByte(int packed) {
    /*int r = (packed >> 16) & 0xFF;
    int g = (packed >> 8) & 0xFF;
    int b = packed & 0xFF;
    ret (byte) ((r+g+b)/3.0f);*/
    float r = ((packed >> 16) & 0xFF)/255f;
    float g = ((packed >> 8) & 0xFF)/255f;
    float b = (packed & 0xFF)/255f;
    ret (byte) ((r+g+b)/3.0f*255f);
  }

  public byte getByte(int x, int y) {
    return inRange(x, y) ? storage.getByte(x, y) : toByte(borderColor);
  }

  public BWImage(int width, int height, float brightness) {
    this.width = width;
    this.height = height;
    byte b = toByte(brightness);
    byte[] pixels = new byte[width*height];
    for (int i = 0; i < pixels.length; i++)
      pixels[i] = b;
    storage = makeStorage(width, height, pixels);
  }

  public double averageBrightness() {
    double sum = 0;
    for (int y = 0; y < height; y++)
      for (int x = 0; x < width; x++)
        sum += getPixel(x, y);
    return (sum/(double) (height*width));
  }

  public float minimumBrightness() {
    float min = 1;
    for (int y = 0; y < height; y++)
      for (int x = 0; x < width; x++)
        min = Math.min(min, getPixel(x, y));
    return min;
  }

  public float maximumBrightness() {
    float max = 0;
    for (int y = 0; y < height; y++)
      for (int x = 0; x < width; x++)
        max = Math.max(max, getPixel(x, y));
    return max;
  }

  float getPixel(int x, int y) {
    return inRange(x, y) ? toFloat(storage.getByte(x,y )) : borderColor;
  }
  
  float getPixel(Pt p) { ret getPixel(p.x, p.y); }

  public static byte toByte(float pixel) {
    return (byte) (pixel*255f);
  }

  public static float toFloat(byte pixel) {
    return (((int) pixel) & 255)/255f;
  }

  private boolean inRange(int x, int y) {
    return x >= 0 && x < width && y >= 0 && y < height;
  }

  public int getWidth() { return width; }
  int w() { return width; }

  public int getHeight() { return height; }
  int h() { return height; }

  public RGBImage toRGB() {
    int[] rgbs = new int[width*height];
    for (int y = 0; y < height; y++)
      for (int x = 0; x < width; x++) {
        int b = getByte(x, y) & 0xFF;
        rgbs[y*width+x] = 0xFF000000 | b*0x010101;
      }
    return new RGBImage(width, height, rgbs);
  }
  
  public RGBImage toRGB_slow() {
    RGB[] rgbs = new RGB[width*height];
    for (int y = 0; y < height; y++)
      for (int x = 0; x < width; x++) {
        float p = getPixel(x, y);
        rgbs[y*width+x] = new RGB(p, p, p);
      }
    return new RGBImage(width, height, rgbs);
  }


  public BWImage clip(int x, int y, int w, int h) {
    return clip(new Rectangle(x, y, w, h));
  }

  private Rectangle fixClipRect(Rectangle r) {
    return r.intersection(new Rectangle(0, 0, width, height));
  }

  BWImage clip(Rect r) {
    ret clip(r.getRectangle());
  }
  
  /** this should be multithread-safe */
  public BWImage clip(Rectangle r) {
    r = fixClipRect(r);
    byte[] newPixels = new byte[r.height*r.width];
    for (int y = 0; y < r.height; y++)
      for (int x = 0; x < r.width; x++)
        newPixels[y*r.width+x] = getByte(r.x+x, r.y+y);
    return new BWImage(r.width, r.height, newPixels);
  }

  public void setPixel(int x, int y, float brightness) {
    storage.setByte(x, y, toByte(fixPixel(brightness)));
  }

  public void setByte(int x, int y, int brightness) {
    storage.setByte(x, y, (byte) brightness);
  }

  private float fixPixel(float pixel) {
    return Math.max(0, Math.min(1, pixel));
  }

  public float getBorderColor() {
    return borderColor;
  }

  public void setBorderColor(float borderColor) {
    this.borderColor = borderColor;
  }

  public boolean anyPixelBrighterThan(double threshold) {
    for (int y = 0; y < height; y++)
      for (int x = 0; x < width; x++)
        if (getPixel(x, y) > threshold)
          return true;
    return false;
  }
  
  public BufferedImage getBufferedImage() {
    //ret toRGB().getBufferedImage();
    
    // TYPE_BYTE_GRAY is buggy - see #1015235
    BufferedImage bufferedImage = new BufferedImage(width, height, /*BufferedImage.TYPE_BYTE_GRAY*/BufferedImage.TYPE_INT_RGB);
    for (int y = 0; y < height; y++)
      for (int x = 0; x < width; x++) {
        int b = ((int) getByte(x, y) & 0xFF);
        bufferedImage.setRGB(x, y, b*0x010101);
      }
    return bufferedImage; 
  }
  
  byte[] getBytes() {
    ret storage.pixels;
  }
}

static final class BWImageSimpleStorage {
  int width, height;
  byte[] pixels;
  
  // for unstructure()
  BWImageSimpleStorage() {}

  public BWImageSimpleStorage(int width, int height, byte[] pixels) {
    this.width = width;
    this.height = height;
    this.pixels = pixels;
  }

  public void setByte(int x, int y, byte b) {
    pixels[y*width+x] = b;
  }

  public byte getByte(int x, int y) {
    return pixels[y*width+x];
  }
}

Author comment

Began life as a copy of #1004247

download  show line numbers  debug dex  old transpilations   

Travelled to 14 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, irmadwmeruwu, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1016912
Snippet name: class BWImage with BWImageSimpleStorage (old)
Eternal ID of this version: #1016912/1
Text MD5: 21be331476307553690aa01aa509b7d4
Author: stefan
Category: javax / imaging
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2018-07-07 16:42:53
Source code size: 7985 bytes / 272 lines
Pitched / IR pitched: No / No
Views / Downloads: 270 / 293
Referenced in: [show references]