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

828
LINES

< > BotCompany Repo | #2000447 // Image classes

New Tinybrain snippet

1  
class RGB {
2  
  public final float r, g, b;
3  
4  
  public RGB(float r, float g, float b) {
5  
    this.r = r;
6  
    this.g = g;
7  
    this.b = b;
8  
  }
9  
10  
  public RGB(double r, double g, double b) {
11  
    this.r = (float) r;
12  
    this.g = (float) g;
13  
    this.b = (float) b;
14  
  }
15  
16  
  public RGB(double brightness) {
17  
    this.r = this.g = this.b = (float) brightness;
18  
  }
19  
20  
  public RGB(Color color) {
21  
    this.r = color.getRed()/255f;
22  
    this.g = color.getGreen()/255f;
23  
    this.b = color.getBlue()/255f;
24  
  }
25  
26  
  public RGB(String hex) {
27  
    r = Integer.parseInt(hex.substring(0, 2), 16)/255f;
28  
    g = Integer.parseInt(hex.substring(2, 4), 16)/255f;
29  
    b = Integer.parseInt(hex.substring(4, 6), 16)/255f;
30  
  }
31  
32  
  public float getComponent(int i) {
33  
    return i == 0 ? r : i == 1 ? g : b;
34  
  }
35  
36  
  public Color getColor() {
37  
    return new Color(r, g, b);
38  
  }
39  
40  
  public static RGB newSafe(float r, float g, float b) {
41  
    return new RGB(Math.max(0, Math.min(1, r)), Math.max(0, Math.min(1, g)), Math.max(0, Math.min(1, b)));
42  
  }
43  
44  
  public int asInt() {
45  
    return getColor().getRGB() & 0xFFFFFF;
46  
  }
47  
48  
  public float getBrightness() {
49  
    return (r+g+b)/3.0f;
50  
  }
51  
52  
  public String getHexString() {
53  
    return Integer.toHexString(asInt() | 0xFF000000).substring(2).toUpperCase();
54  
  }
55  
56  
  @Override
57  
  public boolean equals(Object o) {
58  
    if (this == o) return true;
59  
    if (!(o instanceof RGB)) return false;
60  
61  
    RGB rgb = (RGB) o;
62  
63  
    if (Float.compare(rgb.b, b) != 0) return false;
64  
    if (Float.compare(rgb.g, g) != 0) return false;
65  
    if (Float.compare(rgb.r, r) != 0) return false;
66  
67  
    return true;
68  
  }
69  
70  
  @Override
71  
  public int hashCode() {
72  
    int result = (r != +0.0f ? Float.floatToIntBits(r) : 0);
73  
    result = 31 * result + (g != +0.0f ? Float.floatToIntBits(g) : 0);
74  
    result = 31 * result + (b != +0.0f ? Float.floatToIntBits(b) : 0);
75  
    return result;
76  
  }
77  
78  
  public boolean isBlack() {
79  
    return r == 0f && g == 0f && b == 0f;
80  
  }
81  
82  
  public boolean isWhite() {
83  
    return r == 1f && g == 1f && b == 1f;
84  
  }
85  
86  
  public String toString() {
87  
    return getHexString();
88  
  }
89  
}
90  
91  
class RGBImage {
92  
  private BufferedImage bufferedImage;
93  
  private File file;
94  
  private int width, height;
95  
  private int[] pixels;
96  
97  
  // color returned when getPixel is called with out-of-bounds position
98  
  private int background = 0xFFFFFF;
99  
100  
  public RGBImage(BufferedImage image) {
101  
    this(image, null);
102  
  }
103  
104  
  public RGBImage(BufferedImage image, File file) {
105  
    this.file = file;
106  
    bufferedImage = image;
107  
    width = image.getWidth();
108  
    height = image.getHeight();
109  
    pixels = new int[width*height];
110  
    PixelGrabber pixelGrabber = new PixelGrabber(image, 0, 0, width, height, pixels, 0, width);
111  
    try {
112  
      if (!pixelGrabber.grabPixels())
113  
        throw new RuntimeException("Could not grab pixels");
114  
      cleanPixels(); // set upper byte to 0
115  
    } catch (InterruptedException e) {
116  
      throw new RuntimeException(e);
117  
    }
118  
  }
119  
120  
  /** We assume it's a file name to load from */
121  
  public RGBImage(String file) throws IOException {
122  
    this(new File(file));
123  
  }
124  
125  
  public RGBImage(Dimension size, Color color) {
126  
    this(size.width, size.height, color);
127  
  }
128  
129  
  public RGBImage(Dimension size, RGB color) {
130  
    this(size.width, size.height, color);
131  
  }
132  
133  
  private void cleanPixels() {
134  
    for (int i = 0; i < pixels.length; i++)
135  
      pixels[i] &= 0xFFFFFF;
136  
  }
137  
138  
  public RGBImage(int width, int height, int[] pixels) {
139  
    this.width = width;
140  
    this.height = height;
141  
    this.pixels = pixels;
142  
  }
143  
144  
  public RGBImage(int w, int h, RGB[] pixels) {
145  
    this.width = w;
146  
    this.height = h;
147  
    this.pixels = asInts(pixels);
148  
  }
149  
150  
  public static int[] asInts(RGB[] pixels) {
151  
    int[] ints = new int[pixels.length];
152  
    for (int i = 0; i < pixels.length; i++)
153  
      ints[i] = pixels[i] == null ? 0 : pixels[i].getColor().getRGB();
154  
    return ints;
155  
  }
156  
157  
  public RGBImage(int w, int h, RGB rgb) {
158  
    this.width = w;
159  
    this.height = h;
160  
    this.pixels = new int[w*h];
161  
    int col = rgb.asInt();
162  
    if (col != 0)
163  
      for (int i = 0; i < pixels.length; i++)
164  
        pixels[i] = col;
165  
  }
166  
167  
  public RGBImage(RGBImage image) {
168  
    this(image.width, image.height, copyPixels(image.pixels));
169  
  }
170  
171  
  public RGBImage(int width, int height, Color color) {
172  
    this(width, height, new RGB(color));
173  
  }
174  
175  
  public RGBImage(File file) throws IOException {
176  
    this(javax.imageio.ImageIO.read(file));
177  
  }
178  
179  
  private static int[] copyPixels(int[] pixels) {
180  
    int[] copy = new int[pixels.length];
181  
    System.arraycopy(pixels, 0, copy, 0, pixels.length);
182  
    return copy;
183  
  }
184  
185  
  public int getIntPixel(int x, int y) {
186  
    if (inRange(x, y))
187  
      return pixels[y * width + x];
188  
    else
189  
      return background;
190  
  }
191  
192  
  public static RGB asRGB(int packed) {
193  
    int r = (packed >> 16) & 0xFF;
194  
    int g = (packed >> 8) & 0xFF;
195  
    int b = packed & 0xFF;
196  
    return new RGB(r / 255f, g / 255f, b / 255f);
197  
  }
198  
199  
  public RGB getRGB(int x, int y) {
200  
    if (inRange(x, y))
201  
      return asRGB(pixels[y * width + x]);
202  
    else
203  
      return new RGB(background);
204  
  }
205  
206  
  /** alias of getRGB - I kept typing getPixel instead of getRGB all the time, so I finally created it */
207  
  public RGB getPixel(int x, int y) {
208  
    return getRGB(x, y);
209  
  }
210  
211  
  public int getWidth() {
212  
    return width;
213  
  }
214  
215  
  public int getHeight() {
216  
    return height;
217  
  }
218  
219  
  /** Attention: cached, i.e. does not change when image itself changes */
220  
  /** @NotNull */
221  
  public BufferedImage getBufferedImage() {
222  
    if (bufferedImage == null) {
223  
      bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
224  
      //bufferedImage.setData(Raster.createRaster(new SampleModel()));
225  
      for (int y = 0; y < height; y++)
226  
        for (int x = 0; x < width; x++)
227  
          bufferedImage.setRGB(x, y, pixels[y*width+x]);
228  
    }
229  
    return bufferedImage;
230  
  }
231  
232  
  public RGBImage clip(Rectangle r) {
233  
    r = fixClipRect(r);
234  
    int[] newPixels;
235  
    try {
236  
      newPixels = new int[r.width*r.height];
237  
    } catch (RuntimeException e) {
238  
      System.out.println(r);
239  
      throw e;
240  
    }
241  
    for (int y = 0; y < r.height; y++) {
242  
      System.arraycopy(pixels, (y+r.y)*width+r.x, newPixels, y*r.width, r.width);
243  
    }
244  
    return new RGBImage(r.width, r.height, newPixels);
245  
  }
246  
247  
  private Rectangle fixClipRect(Rectangle r) {
248  
    r = r.intersection(new Rectangle(0, 0, width, height));
249  
    if (r.isEmpty())
250  
      r = new Rectangle(r.x, r.y, 0, 0);
251  
    return r;
252  
  }
253  
254  
  public File getFile() {
255  
    return file;
256  
  }
257  
258  
  /** can now also do GIF (not just JPEG) */
259  
  public static RGBImage load(String fileName) {
260  
    return load(new File(fileName));
261  
  }
262  
263  
  /** can now also do GIF (not just JPEG) */
264  
  public static RGBImage load(File file) {
265  
    try {
266  
      BufferedImage bufferedImage = javax.imageio.ImageIO.read(file);
267  
      return new RGBImage(bufferedImage);
268  
    } catch (IOException e) {
269  
      throw new RuntimeException(e);
270  
    }
271  
  }
272  
273  
  public int getInt(int x, int y) {
274  
    return pixels[y * width + x];
275  
  }
276  
277  
  public void save(File file) throws IOException {
278  
    String name = file.getName().toLowerCase();
279  
    String type;
280  
    if (name.endsWith(".png")) type = "png";
281  
    else if (name.endsWith(".jpg") || name.endsWith(".jpeg")) type = "jpeg";
282  
    else throw new IOException("Unknown image extension: " + name);
283  
    javax.imageio.ImageIO.write(getBufferedImage(), type, file);
284  
  }
285  
286  
  public static RGBImage dummyImage() {
287  
    return new RGBImage(1, 1, new int[] {0xFFFFFF});
288  
  }
289  
290  
  public int[] getPixels() {
291  
    return pixels;
292  
  }
293  
294  
  public void setPixel(int x, int y, RGB rgb) {
295  
    if (x >= 0 && y >= 0 && x < width && y < height)
296  
      pixels[y*width+x] = rgb.asInt();
297  
  }
298  
299  
  public void setPixel(int x, int y, Color color) {
300  
    setPixel(x, y, new RGB(color));
301  
  }
302  
303  
  public void setPixel(int x, int y, int rgb) {
304  
    if (x >= 0 && y >= 0 && x < width && y < height)
305  
      pixels[y*width+x] = rgb;
306  
  }
307  
308  
  public RGBImage copy() {
309  
    return new RGBImage(this);
310  
  }
311  
312  
  public boolean inRange(int x, int y) {
313  
    return x >= 0 && y >= 0 && x < width && y < height;
314  
  }
315  
316  
  public int getBackground() {
317  
    return background;
318  
  }
319  
320  
  public void setBackground(int background) {
321  
    this.background = background;
322  
  }
323  
324  
  public Dimension getSize() {
325  
    return new Dimension(width, height);
326  
  }
327  
328  
  @Override
329  
  public boolean equals(Object o) {
330  
    if (this == o) return true;
331  
    if (o == null || getClass() != o.getClass()) return false;
332  
333  
    RGBImage rgbImage = (RGBImage) o;
334  
335  
    if (height != rgbImage.height) return false;
336  
    if (width != rgbImage.width) return false;
337  
    if (!Arrays.equals(pixels, rgbImage.pixels)) return false;
338  
339  
    return true;
340  
  }
341  
342  
  @Override
343  
  public int hashCode() {
344  
    int result = width;
345  
    result = 31 * result + height;
346  
    result = 31 * result + Arrays.hashCode(pixels);
347  
    return result;
348  
  }
349  
350  
  public String getHex(int x, int y) {
351  
    return getPixel(x, y).getHexString();
352  
  }
353  
354  
  public RGBImage clip(int x, int y, int width, int height) {
355  
    return clip(new Rectangle(x, y, width, height));
356  
  }
357  
358  
  public RGBImage clipLine(int y) {
359  
    return clip(0, y, width, 1);
360  
  }
361  
362  
  public int numPixels() {
363  
    return width*height;
364  
  }
365  
}
366  
367  
abstract class Surface extends JPanel {
368  
369  
370  
  public Object AntiAlias = RenderingHints.VALUE_ANTIALIAS_ON;
371  
  public Object Rendering = RenderingHints.VALUE_RENDER_SPEED;
372  
  public AlphaComposite composite;
373  
  public Paint texture;
374  
  public BufferedImage bimg;
375  
  public int imageType;
376  
  public String name;
377  
  public boolean clearSurface = true;
378  
  // Demos using animated gif's that implement ImageObserver set dontThread.
379  
  public boolean dontThread;
380  
381  
  protected long sleepAmount = 50; // max20 fps
382  
383  
  private long orig, start, frame;
384  
  private Toolkit toolkit;
385  
  private boolean perfMonitor, outputPerf;
386  
  private int biw, bih;
387  
  private boolean clearOnce;
388  
  private boolean toBeInitialized = true;
389  
390  
391  
  public Surface() {
392  
    setDoubleBuffered(false);
393  
    toolkit = getToolkit();
394  
    name = this.getClass().getName();
395  
    name = name.substring(name.indexOf(".", 7)+1);
396  
    setImageType(0);
397  
398  
    // To launch an individual demo with the performance str output  :
399  
    //    java -Djava2demo.perf= -cp Java2Demo.jar demos.Clipping.ClipAnim
400  
    try {
401  
      if (System.getProperty("java2demo.perf") != null) {
402  
        perfMonitor = outputPerf = true;
403  
      }
404  
    } catch (Exception ex) { }
405  
  }
406  
407  
408  
    /*protected Image getImage(String name) {
409  
        return DemoImages.getImage(name, this);
410  
    }
411  
412  
413  
    protected Font getFont(String name) {
414  
        return DemoFonts.getFont(name);
415  
    }*/
416  
417  
418  
  public int getImageType() {
419  
    return imageType;
420  
  }
421  
422  
423  
  public void setImageType(int imgType) {
424  
    if (imgType == 0) {
425  
      imageType = 1;
426  
    } else {
427  
      imageType = imgType;
428  
    }
429  
    bimg = null;
430  
  }
431  
432  
433  
  public void setAntiAlias(boolean aa) {
434  
    AntiAlias = aa
435  
      ? RenderingHints.VALUE_ANTIALIAS_ON
436  
      : RenderingHints.VALUE_ANTIALIAS_OFF;
437  
  }
438  
439  
440  
  public void setRendering(boolean rd) {
441  
    Rendering = rd
442  
      ? RenderingHints.VALUE_RENDER_QUALITY
443  
      : RenderingHints.VALUE_RENDER_SPEED;
444  
  }
445  
446  
447  
  public void setTexture(Object obj) {
448  
    if (obj instanceof GradientPaint) {
449  
      texture = new GradientPaint(0, 0, Color.white,
450  
        getSize().width*2, 0, Color.green);
451  
    } else {
452  
      texture = (Paint) obj;
453  
    }
454  
  }
455  
456  
457  
  public void setComposite(boolean cp) {
458  
    composite = cp
459  
      ? AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f)
460  
      : null;
461  
  }
462  
463  
464  
  public void setMonitor(boolean pm) {
465  
    perfMonitor = pm;
466  
  }
467  
468  
469  
  public void setSleepAmount(long amount) {
470  
    sleepAmount = amount;
471  
  }
472  
473  
474  
  public long getSleepAmount() {
475  
    return sleepAmount;
476  
  }
477  
478  
479  
  public BufferedImage createBufferedImage(Graphics2D g2,
480  
                                           int w,
481  
                                           int h,
482  
                                           int imgType) {
483  
    BufferedImage bi = null;
484  
    if (imgType == 0) {
485  
      bi = (BufferedImage) g2.getDeviceConfiguration().
486  
        createCompatibleImage(w, h);
487  
    } else if (imgType > 0 && imgType < 14) {
488  
      bi = new BufferedImage(w, h, imgType);
489  
    } else if (imgType == 14) {
490  
      bi = createBinaryImage(w, h, 2);
491  
    } else if (imgType == 15) {
492  
      bi = createBinaryImage(w, h, 4);
493  
    } else if (imgType == 16) {
494  
      bi = createSGISurface(w, h, 32);
495  
    } else if (imgType == 17) {
496  
      bi = createSGISurface(w, h, 16);
497  
    }
498  
    biw = w;
499  
    bih = h;
500  
    return bi;
501  
  }
502  
503  
504  
  // Lookup tables for BYTE_BINARY 1, 2 and 4 bits.
505  
  static byte[] lut1Arr = new byte[] {0, (byte)255 };
506  
  static byte[] lut2Arr = new byte[] {0, (byte)85, (byte)170, (byte)255};
507  
  static byte[] lut4Arr = new byte[] {0, (byte)17, (byte)34, (byte)51,
508  
    (byte)68, (byte)85,(byte) 102, (byte)119,
509  
    (byte)136, (byte)153, (byte)170, (byte)187,
510  
    (byte)204, (byte)221, (byte)238, (byte)255};
511  
512  
513  
  private BufferedImage createBinaryImage(int w, int h, int pixelBits) {
514  
    int bytesPerRow = w * pixelBits / 8;
515  
    if (w * pixelBits % 8 != 0) {
516  
      bytesPerRow++;
517  
    }
518  
    byte[] imageData = new byte[h * bytesPerRow];
519  
    IndexColorModel cm = null;
520  
    switch (pixelBits) {
521  
      case 1:
522  
        cm = new IndexColorModel(pixelBits, lut1Arr.length,
523  
          lut1Arr, lut1Arr, lut1Arr);
524  
        break;
525  
      case 2:
526  
        cm = new IndexColorModel(pixelBits, lut2Arr.length,
527  
          lut2Arr, lut2Arr, lut2Arr);
528  
        break;
529  
      case 4:
530  
        cm = new IndexColorModel(pixelBits, lut4Arr.length,
531  
          lut4Arr, lut4Arr, lut4Arr);
532  
        break;
533  
      default:
534  
      {new Exception("Invalid # of bit per pixel").printStackTrace();}
535  
    }
536  
537  
    DataBuffer db = new DataBufferByte(imageData, imageData.length);
538  
    WritableRaster r = Raster.createPackedRaster(db, w, h, pixelBits, null);
539  
    return new BufferedImage(cm, r, false, null);
540  
  }
541  
542  
  private BufferedImage createSGISurface(int w, int h, int pixelBits) {
543  
    int rMask32 = 0xFF000000;
544  
    int rMask16 = 0xF800;
545  
    int gMask32 = 0x00FF0000;
546  
    int gMask16 = 0x07C0;
547  
    int bMask32 = 0x0000FF00;
548  
    int bMask16 = 0x003E;
549  
550  
    DirectColorModel dcm = null;
551  
    DataBuffer db = null;
552  
    WritableRaster wr = null;
553  
    switch (pixelBits) {
554  
      case 16:
555  
        short[] imageDataUShort = new short[w * h];
556  
        dcm = new DirectColorModel(16, rMask16, gMask16, bMask16);
557  
        db = new DataBufferUShort(imageDataUShort, imageDataUShort.length);
558  
        wr = Raster.createPackedRaster(db, w, h, w,
559  
          new int[] {rMask16, gMask16, bMask16},
560  
          null);
561  
        break;
562  
      case 32:
563  
        int[] imageDataInt = new int[w * h];
564  
        dcm = new DirectColorModel(32, rMask32, gMask32, bMask32);
565  
        db = new DataBufferInt(imageDataInt, imageDataInt.length);
566  
        wr = Raster.createPackedRaster(db, w, h, w,
567  
          new int[] {rMask32, gMask32, bMask32},
568  
          null);
569  
        break;
570  
      default:
571  
      {new Exception("Invalid # of bit per pixel").printStackTrace();}
572  
    }
573  
574  
    return new BufferedImage(dcm, wr, false, null);
575  
  }
576  
577  
  public Graphics2D createGraphics2D(int width,
578  
                                     int height,
579  
                                     BufferedImage bi,
580  
                                     Graphics g) {
581  
582  
    Graphics2D g2 = null;
583  
584  
    if (bi != null) {
585  
      g2 = bi.createGraphics();
586  
    } else {
587  
      g2 = (Graphics2D) g;
588  
    }
589  
590  
    g2.setBackground(getBackground());
591  
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, AntiAlias);
592  
    g2.setRenderingHint(RenderingHints.KEY_RENDERING, Rendering);
593  
594  
    if (clearSurface || clearOnce) {
595  
      g2.clearRect(0, 0, width, height);
596  
      clearOnce = false;
597  
    }
598  
599  
    if (texture != null) {
600  
      // set composite to opaque for texture fills
601  
      g2.setComposite(AlphaComposite.SrcOver);
602  
      g2.setPaint(texture);
603  
      g2.fillRect(0, 0, width, height);
604  
    }
605  
606  
    if (composite != null) {
607  
      g2.setComposite(composite);
608  
    }
609  
610  
    return g2;
611  
  }
612  
613  
  public abstract void render(int w, int h, Graphics2D g);
614  
615  
616  
  /**
617  
   * It's possible to turn off double-buffering for just the repaint
618  
   * calls invoked directly on the non double buffered component.
619  
   * This can be done by overriding paintImmediately() (which is called
620  
   * as a result of repaint) and getting the current RepaintManager and
621  
   * turning off double buffering in the RepaintManager before calling
622  
   * super.paintImmediately(g).
623  
   */
624  
  public void paintImmediately(int x,int y,int w, int h) {
625  
    RepaintManager repaintManager = null;
626  
    boolean save = true;
627  
    if (!isDoubleBuffered()) {
628  
      repaintManager = RepaintManager.currentManager(this);
629  
      save = repaintManager.isDoubleBufferingEnabled();
630  
      repaintManager.setDoubleBufferingEnabled(false);
631  
    }
632  
    super.paintImmediately(x, y, w, h);
633  
634  
    if (repaintManager != null) {
635  
      repaintManager.setDoubleBufferingEnabled(save);
636  
    }
637  
  }
638  
639  
640  
  public void paint(Graphics g) {
641  
642  
    Dimension d = getSize();
643  
644  
    if (imageType == 1)
645  
      bimg = null;
646  
    else if (bimg == null || biw != d.width || bih != d.height) {
647  
      bimg = createBufferedImage((Graphics2D)g,
648  
        d.width, d.height, imageType-2);
649  
      clearOnce = true;
650  
      toBeInitialized = true;
651  
    }
652  
653  
    if (toBeInitialized) {
654  
      toBeInitialized = false;
655  
      startClock();
656  
    }
657  
658  
    Graphics2D g2 = createGraphics2D(d.width, d.height, bimg, g);
659  
    render(d.width, d.height, g2);
660  
    g2.dispose();
661  
662  
    if (bimg != null)  {
663  
      g.drawImage(bimg, 0, 0, null);
664  
      toolkit.sync();
665  
    }
666  
667  
  }
668  
669  
670  
  public void startClock() {
671  
    orig = System.currentTimeMillis();
672  
    start = orig;
673  
    frame = 0;
674  
  }
675  
676  
  private static final int REPORTFRAMES = 30;
677  
678  
679  
  public static void setAlpha(Graphics2D g, float alpha) {
680  
    g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
681  
  }
682  
}
683  
684  
class ImageSurface extends Surface {
685  
  private BufferedImage image;
686  
  private double zoomX = 1, zoomY = 1;
687  
  private Rectangle selection;
688  
689  
  public ImageSurface() {
690  
    this(new RGBImage(1, 1, new int[] { 0xFFFFFF }));
691  
  }
692  
693  
  public ImageSurface(RGBImage image) {
694  
    this(image.getBufferedImage());
695  
  }
696  
697  
  public ImageSurface(BufferedImage image) {
698  
    clearSurface = false;
699  
    this.image = image;
700  
701  
    /*addMouseMotionListener(new MouseAdapter() {
702  
      public void mouseMoved(MouseEvent e) {
703  
        getMousePosition()
704  
705  
      }
706  
    });*/
707  
  }
708  
709  
  public ImageSurface(RGBImage image, double zoom) {
710  
    this(image);
711  
    setZoom(zoom);
712  
  }
713  
714  
  public void render(int w, int h, Graphics2D g) {
715  
    g.setColor(Color.white);
716  
    g.fillRect(0, 0, w, h);
717  
    if (image != null)
718  
      g.drawImage(image, 0, 0, getZoomedWidth(), getZoomedHeight(), null);
719  
720  
    if (selection != null) {
721  
      // drawRect is inclusive, selection is exclusive, so... whatever, tests show it's cool.
722  
      drawSelectionRect(g, selection, Color.green, Color.white);
723  
    }
724  
  }
725  
726  
  public void drawSelectionRect(Graphics2D g, Rectangle selection, Color green, Color white) {
727  
    g.setColor(green);
728  
    int top = (int) (selection.y * zoomY);
729  
    int bottom = (int) ((selection.y+selection.height) * zoomY);
730  
    int left = (int) (selection.x * zoomX);
731  
    int right = (int) ((selection.x+selection.width) * zoomX);
732  
    g.drawRect(left-1, top-1, right-left+1, bottom-top+1);
733  
    g.setColor(white);
734  
    g.drawRect(left - 2, top - 2, right - left + 3, bottom - top + 3);
735  
  }
736  
737  
  public void setZoom(double zoom) {
738  
    setZoom(zoom, zoom);
739  
  }
740  
741  
  public void setZoom(double zoomX, double zoomY) {
742  
    this.zoomX = zoomX;
743  
    this.zoomY = zoomY;
744  
    revalidate();
745  
    repaint();
746  
  }
747  
748  
  public Dimension getMinimumSize() {
749  
    int w = getZoomedWidth();
750  
    int h = getZoomedHeight();
751  
    Dimension min = super.getMinimumSize();
752  
    return new Dimension(Math.max(w, min.width), Math.max(h, min.height));
753  
  }
754  
755  
  private int getZoomedHeight() {
756  
    return (int) (image.getHeight() * zoomY);
757  
  }
758  
759  
  private int getZoomedWidth() {
760  
    return (int) (image.getWidth() * zoomX);
761  
  }
762  
763  
  public void setImage(RGBImage image) {
764  
    setImage(image.getBufferedImage());
765  
  }
766  
767  
  public void setImage(BufferedImage image) {
768  
    this.image = image;
769  
    revalidate();
770  
    repaint();
771  
  }
772  
773  
  public BufferedImage getImage() {
774  
    return image;
775  
  }
776  
777  
  public double getZoomX() {
778  
    return zoomX;
779  
  }
780  
781  
  public double getZoomY() {
782  
    return zoomY;
783  
  }
784  
785  
  public Dimension getPreferredSize() {
786  
    return new Dimension(getZoomedWidth(), getZoomedHeight());
787  
  }
788  
789  
  /** returns a scrollpane with the scroll-mode prevent-garbage-drawing fix applied */
790  
  public JScrollPane makeScrollPane() {
791  
    JScrollPane scrollPane = new JScrollPane(this);
792  
    scrollPane.getViewport().setScrollMode(JViewport.BACKINGSTORE_SCROLL_MODE);
793  
    return scrollPane;
794  
  }
795  
796  
  public void zoomToDisplaySize() {
797  
    if (image == null) return;
798  
    Dimension display = getDisplaySize();
799  
    double xRatio = display.width/(double) image.getWidth();
800  
    double yRatio = display.height/(double) image.getHeight();
801  
    setZoom(Math.min(xRatio, yRatio));
802  
    revalidate();
803  
  }
804  
805  
  /** tricky magic to get parent scroll pane */
806  
  private Dimension getDisplaySize() {
807  
    Container c = getParent();
808  
    while (c != null) {
809  
      if (c instanceof JScrollPane)
810  
        return c.getSize();
811  
      c = c.getParent();
812  
    }
813  
    return getSize();
814  
  }
815  
816  
  public void setSelection(Rectangle r) {
817  
    selection = r;
818  
    repaint();
819  
  }
820  
821  
  public Rectangle getSelection() {
822  
    return selection;
823  
  }
824  
825  
  public RGBImage getRGBImage() {
826  
    return new RGBImage(getImage());
827  
  }
828  
}

download  show line numbers   

Snippet is not live.

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

Comments [hide]

ID Author/Program Comment Date
1181 stefan Please use #1001447 instead 2015-11-29 20:39:51
428 #1000604 (pitcher) 2015-08-18 00:07:22

add comment

Snippet ID: #2000447
Snippet name: Image classes
Eternal ID of this version: #2000447/1
Text MD5: 285b6d96b08cde6976bcfdbf5edef24a
Author: stefan
Category: javax
Type: New Tinybrain snippet
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2015-07-13 04:14:56
Source code size: 22159 bytes / 828 lines
Pitched / IR pitched: No / Yes
Views / Downloads: 844 / 1339
Referenced in: [show references]