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

269
LINES

< > BotCompany Repo | #1002470 // RGBImage

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

Libraryless. Click here for Pure Java version (10400L/59K).

sclass RGBImage implements MakesBufferedImage, IRGBImage {
  transient BufferedImage bufferedImage;
  int width, height;
  int[] pixels;

  *() {}

  *(BufferedImage image) {
    bufferedImage = image;
    width = image.getWidth();
    height = image.getHeight();
    pixels = new int[width*height];
    var gp = grabbableIntPixels_fastOrSlow(image);
    
    if (gp.scanlineStride == width && gp.offset == 0)
      pixels = gp.data;
    else {
      pixels = new int[width*height];
      int iIn = 0, iOut = 0;
      for y to height: {
        arrayCopy(gp.data, iIn, pixels, iOut, width);
        iIn += gp.scanlineStride;
        iOut += width;
      }
    }
    
    cleanPixels(); // set upper byte to 0
  }

  *(Dimension size, Color color) {
    this(size.width, size.height, color);
  }

  *(Dimension size, RGB color) {
    this(size.width, size.height, color);
  }

  private void cleanPixels() {
    var pixels = this.pixels;
    for (int i = 0; i < pixels.length; i++)
      pixels[i] &= 0xFFFFFF;
  }

  *(int width, int height, int[] pixels) {
    this.width = width;
    this.height = height;
    this.pixels = pixels;
  }

  *(int w, int h, RGB[] pixels) {
    this.width = w;
    this.height = h;
    this.pixels = asInts(pixels);
  }

  public static int[] asInts(RGB[] pixels) {
    int[] ints = new int[pixels.length];
    for (int i = 0; i < pixels.length; i++)
      ints[i] = pixels[i] == null ? 0 : pixels[i].getColor().getRGB();
    return ints;
  }

  public RGBImage(int w, int h) {
    this(w, h, Color.black);
  }
  
  *(int w, int h, RGB rgb) {
    this.width = w;
    this.height = h;
    this.pixels = new int[w*h];
    int col = rgb.asInt();
    if (col != 0)
      for (int i = 0; i < pixels.length; i++)
        pixels[i] = col;
  }

  *(RGBImage image) {
    this(image.width, image.height, copyPixels(image.pixels));
  }

  *(int width, int height, Color color) {
    this(width, height, new RGB(color));
  }

  *(MakesBufferedImage img) {
    this(toBufferedImage(img));
  }

  private static int[] copyPixels(int[] pixels) {
    int[] copy = new int[pixels.length];
    System.arraycopy(pixels, 0, copy, 0, pixels.length);
    return copy;
  }

  public int getIntPixel(int x, int y) {
    if (inRange(x, y))
      return pixels[y * width + x];
    else
      return 0xFFFFFF;
  }
  
  // idx = index in pixel array
  public int getIntPixel_noRangeCheck(int idx) {
    ret pixels[idx];
  }

  public static RGB asRGB(int packed) {
    int r = (packed >> 16) & 0xFF;
    int g = (packed >> 8) & 0xFF;
    int b = packed & 0xFF;
    return new RGB(r / 255f, g / 255f, b / 255f);
  }

  public RGB getRGB(int x, int y) {
    if (inRange(x, y))
      return asRGB(pixels[y * width + x]);
    else
      return new RGB(0xFFFFFF);
  }

  /** alias of getRGB - I kept typing getPixel instead of getRGB all the time, so I finally created it */
  RGB getPixel(int x, int y) {
    return getRGB(x, y);
  }
  
  RGB getPixel(Pt p) { ret getPixel(p.x, p.y); }

  public int getWidth() { return width; }
  public int getHeight() { return height; }
  public int w() { ret width; }
  public int h() { ret height; }

  /** Attention: cached, i.e. does not change when image itself changes */
  /** @NotNull */
  public BufferedImage getBufferedImage() {
    if (bufferedImage == null) {
      bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
      //bufferedImage.setData(Raster.createRaster(new SampleModel()));
      for (int y = 0; y < height; y++)
        for (int x = 0; x < width; x++)
          bufferedImage.setRGB(x, y, pixels[y*width+x]);
    }
    return bufferedImage;
  }

  RGBImage clip(Rect r) {
    ret r == null ? null : clip(r.getRectangle());
  }
  
  RGBImage clip(Rectangle r) {
    r = fixClipRect(r);
    if (r.x == 0 && r.y == 0 && r.width == width && r.height == height) this;
    int[] newPixels;
    try {
      newPixels = new int[r.width*r.height];
    } catch (RuntimeException e) {
      System.out.println(r);
      throw e;
    }
    for (int y = 0; y < r.height; y++) {
      System.arraycopy(pixels, (y+r.y)*width+r.x, newPixels, y*r.width, r.width);
    }
    return new RGBImage(r.width, r.height, newPixels);
  }

  private Rectangle fixClipRect(Rectangle r) {
    r = r.intersection(new Rectangle(0, 0, width, height));
    if (r.isEmpty())
      r = new Rectangle(r.x, r.y, 0, 0);
    return r;
  }

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

  public void save(File file) {
    saveImage(file, getBufferedImage());
  }

  public static RGBImage dummyImage() {
    return new RGBImage(1, 1, new int[] {0xFFFFFF});
  }

  public int[] getPixels() {
    return pixels;
  }
  
  void setPixel(int x, int y, int r, int g, int b) {
    if (x >= 0 && y >= 0 && x < width && y < height)
      pixels[y*width+x] = (limitToUByte(r) << 16) | (limitToUByte(g) << 8) | limitToUByte(b);
  }

  public void setPixel(int x, int y, RGB rgb) {
    if (x >= 0 && y >= 0 && x < width && y < height)
      pixels[y*width+x] = rgb.asInt();
  }

  public void setPixel aka set(int x, int y, Color color) {
    setPixel(x, y, new RGB(color));
  }
  
  void setInt(int x, int y, int rgb) {
    setPixel(x, y, rgb);
  }

  public void setPixel(int x, int y, int rgb) {
    if (x >= 0 && y >= 0 && x < width && y < height)
      pixels[y*width+x] = rgb;
  }
  
  void setPixel(Pt p, RGB rgb) { setPixel(p.x, p.y, rgb); }
  void setPixel(Pt p, Color color) { setPixel(p.x, p.y, color); }

  public RGBImage copy() {
    return new RGBImage(this);
  }

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

  public Dimension getSize() {
    return new Dimension(width, height);
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    RGBImage rgbImage = (RGBImage) o;

    if (height != rgbImage.height) return false;
    if (width != rgbImage.width) return false;
    if (!Arrays.equals(pixels, rgbImage.pixels)) return false;

    return true;
  }

  @Override
  public int hashCode() {
    int result = width;
    result = 31 * result + height;
    result = 31 * result + Arrays.hashCode(pixels);
    return result;
  }

  public String getHex(int x, int y) {
    return getPixel(x, y).getHexString();
  }

  public RGBImage clip(int x, int y, int width, int height) {
    return clip(new Rectangle(x, y, width, height));
  }

  public RGBImage clipLine(int y) {
    return clip(0, y, width, 1);
  }

  public int numPixels() {
    return width*height;
  }
  
  selfType uncacheBufferedImage() {
    bufferedImage = null;
    this;
  }
}

Author comment

Began life as a copy of #1001447

download  show line numbers  debug dex  old transpilations   

Travelled to 23 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, ddnzoavkxhuk, gwrvuhgaqvyk, irmadwmeruwu, ishqpsrjomds, jtubtzbbkimh, lpdgvwnxivlt, lulzaavyztxj, mqqgnosmbjvj, ofpaelxlmzfo, onxytkatvevr, ppjhyzlbdabe, pyentgdyhuwx, pzhvpgtvlbxg, sawdedvomwva, tslmcundralx, tvejysmllsmz, vouqrxazstgt, whxojlpjdney, wtqryiryparv

No comments. add comment

Snippet ID: #1002470
Snippet name: RGBImage
Eternal ID of this version: #1002470/28
Text MD5: f9d5409f82b479c4c7725f0b9911da1c
Transpilation MD5: f21bdfdc94304242d8194ebc4e486a58
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-08-27 01:26:58
Source code size: 6953 bytes / 269 lines
Pitched / IR pitched: No / No
Views / Downloads: 845 / 9093
Version history: 27 change(s)
Referenced in: [show references]