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

515
LINES

< > BotCompany Repo | #666 // vsplit v6 (with structure size)

JavaX source code - run with: x30.jar

1  
!636
2  
!629 // standard functions
3  
!658 // image classes
4  
5  
import java.awt.*;
6  
import java.awt.image.*;
7  
import java.util.List;
8  
import javax.imageio.*;
9  
import java.lang.reflect.*;
10  
11  
public class main {
12  
  static RGBImage originalImage;
13  
  
14  
  static abstract class Params {
15  
    RGBImage originalImage;
16  
    abstract RGBImage render();
17  
    abstract Params copy();
18  
    
19  
    void baseClone(Params p) {
20  
      p.originalImage = originalImage;
21  
    }
22  
    
23  
    RGBImage rendered;
24  
    RGBImage getImage() {
25  
      if (rendered == null)
26  
        rendered = render();
27  
      return rendered;
28  
    }
29  
    
30  
    double score = 2.0;
31  
    double getScore() {
32  
      if (score == 2.0)
33  
        score = calcScore();
34  
      return score;
35  
    }
36  
    
37  
    double calcScore() {
38  
      return diff(originalImage, getImage());
39  
    }
40  
    
41  
    boolean isBetterThan(Params p) {
42  
      return getScore() < p.getScore();
43  
    }
44  
  }
45  
  
46  
  static class VSplit extends Params {
47  
    double splitPoint;
48  
    RGB col1, col2;
49  
    
50  
    VSplit copy() {
51  
      VSplit p = new VSplit();
52  
      baseClone(p);
53  
      p.splitPoint = splitPoint;
54  
      p.col1 = col1;
55  
      p.col2 = col2;
56  
      return p;
57  
    }
58  
    
59  
    public String toString() {
60  
      return "VSplit " + splitPoint + " " + col1 + " " + col2;
61  
    }
62  
63  
    RGBImage render() {
64  
      int w = originalImage.getWidth(), h = originalImage.getHeight();
65  
      RGBImage image = new RGBImage(w, h, Color.white);
66  
      vsplit(image, this);
67  
      return image;
68  
    }
69  
  }
70  
  
71  
  static class Solid extends Params {
72  
    RGB col;
73  
    
74  
    Solid copy() {
75  
      Solid p = new Solid();
76  
      baseClone(p);
77  
      p.col = col;
78  
      return p;
79  
    }
80  
    
81  
    public String toString() {
82  
      return "Solid " + col;
83  
    }
84  
85  
    RGBImage render() {
86  
      int w = originalImage.getWidth(), h = originalImage.getHeight();
87  
      return new RGBImage(w, h, col);
88  
    }
89  
  }
90  
  
91  
  interface Reproducer {
92  
    public Params reproduce(RGBImage original);
93  
  }
94  
  
95  
  static class RandomVSplit implements Reproducer {
96  
    int n = -1;
97  
    public Params reproduce(RGBImage original) {
98  
      ++n;
99  
      VSplit p = new VSplit();
100  
      p.originalImage = original;
101  
      p.splitPoint = random();
102  
      if (n % 2 == 0) {
103  
        p.col1 = randomColor();
104  
        p.col2 = randomColor();
105  
      } else {
106  
        p.col1 = probeRandomPixel(original);
107  
        p.col2 = probeRandomPixel(original);
108  
      }
109  
      return p;
110  
    }
111  
  }
112  
  
113  
  static class RandomSolid implements Reproducer {
114  
    int n = -1;
115  
    public Params reproduce(RGBImage original) {
116  
      ++n;
117  
      Solid p = new Solid();
118  
      p.originalImage = original;
119  
      if (n % 2 == 0) {
120  
        p.col = randomColor();
121  
      } else {
122  
        p.col = probeRandomPixel(original);
123  
      }
124  
      return p;
125  
    }
126  
  }
127  
  
128  
  static class VaryBest implements Reproducer {
129  
    Reproducer base;
130  
    Params best;
131  
    
132  
    VaryBest(Reproducer base) {
133  
      this.base = base;
134  
    }
135  
    
136  
    public Params reproduce(RGBImage original) {
137  
      Params p = base.reproduce(original);
138  
      if (best == null || p.isBetterThan(best))
139  
        best = p;
140  
      Params variation = vary(best);
141  
      //System.out.println("Best: " + best.getScore() + ", variation: " + variation.getScore());
142  
      if (variation.isBetterThan(best)) {
143  
        //System.out.println("Using variation, diff=" + (best.getScore()-variation.getScore()));
144  
        best = variation;
145  
      }
146  
      return best;
147  
    }
148  
    
149  
    Params vary(Params p) {
150  
      if (p instanceof VSplit) {
151  
        VSplit n = ((VSplit) p).copy();
152  
        int s = random(3);
153  
        if (s == 0)
154  
          varySplitPoint(n);
155  
        else if (s == 1)
156  
          n.col1 = varyColor(n.col1);
157  
        else
158  
          n.col2 = varyColor(n.col2);
159  
        return n;
160  
      } else if (p instanceof Solid) {
161  
        Solid n = ((Solid) p).copy();
162  
        n.col = varyColor(n.col);
163  
        return n;
164  
      }
165  
      return null;
166  
    }
167  
    
168  
    void varySplitPoint(VSplit p) {
169  
      p.splitPoint = Math.max(0, Math.min(1, p.splitPoint+random(-0.1, 0.1)));
170  
    }
171  
    
172  
    float varyChannel(float x) {
173  
      return Math.max(0f, Math.min(1f, (float) (x+random(-0.1, 0.1))));
174  
    }
175  
    
176  
    RGB varyColor(RGB rgb) {
177  
      int s = random(3);
178  
      if (s == 0)
179  
        return new RGB(varyChannel(rgb.r), rgb.g, rgb.b);
180  
      else if (s == 1)
181  
        return new RGB(rgb.r, varyChannel(rgb.g), rgb.b);
182  
      else
183  
        return new RGB(rgb.r, rgb.g, varyChannel(rgb.b));
184  
    }
185  
  }
186  
187  
  static class Alternate implements Reproducer {
188  
    int n = -1;
189  
    Reproducer[] list;
190  
    
191  
    Alternate(Reproducer... list) {
192  
      this.list = list;
193  
    }
194  
    
195  
    public Params reproduce(RGBImage original) {
196  
      ++n;
197  
      return list[n % list.length].reproduce(original);
198  
    }
199  
  }
200  
  
201  
  interface ReproducerMaker {
202  
    public Reproducer make();
203  
  }
204  
  
205  
  static class Gridded extends Params {
206  
    int w, h;
207  
    Params[] array;
208  
    
209  
    Gridded(int w, int h) {
210  
      this.w = w;
211  
      this.h = h;
212  
      array = new Params[w*h];
213  
    }
214  
    
215  
    Gridded copy() {
216  
      Gridded p = new Gridded(w, h);
217  
      baseClone(p);
218  
      for (int i = 0; i < w*h; i++)
219  
        p.array[i] = array[i].copy();
220  
      return p;
221  
    }
222  
    
223  
    public String toString() {
224  
      StringBuilder buf = new StringBuilder("grid{");
225  
      for (int i = 0; i < w*h; i++) {
226  
        if (i != 0)
227  
          buf.append(", ");
228  
        buf.append(array[i]);
229  
      }
230  
      return buf + "}";
231  
    }
232  
    
233  
    public RGBImage render() {
234  
      int ow = originalImage.getWidth(), oh = originalImage.getHeight();
235  
      RGBImage img = new RGBImage(ow, oh, Color.white);
236  
      for (int y = 0; y < h; y++)
237  
        for (int x = 0; x < w; x++) {
238  
          int x1 = x*ow/w, y1 = y*oh/h;
239  
          int x2 = (x+1)*ow/w, y2 = (y+1)*oh/h;
240  
          RGBImage part = array[y*w+x].render();
241  
          main.copy(part, 0, 0, img, x1, y1, part.getWidth(), part.getHeight());
242  
        }
243  
      return img;
244  
    }
245  
  }
246  
  
247  
  static class Grid implements Reproducer {
248  
    int w, h;
249  
    Reproducer[] bases;
250  
    
251  
    Grid(ReproducerMaker maker, int w, int h) {
252  
      this.w = w;
253  
      this.h = h;
254  
      bases = new Reproducer[w*h];
255  
      for (int i = 0; i < w*h; i++)
256  
        bases[i] = maker.make();
257  
    }
258  
    
259  
    RGBImage getGridElement(RGBImage originalImage, int i) {
260  
      int ow = originalImage.getWidth(), oh = originalImage.getHeight();
261  
      int y = i / w;
262  
      int x = i % w;
263  
      int x1 = x*ow/w, y1 = y*oh/h;
264  
      int x2 = (x+1)*ow/w, y2 = (y+1)*oh/h;
265  
      return originalImage.clip(x1, y1, x2-x1, y2-y1);
266  
    }
267  
      
268  
    public Params reproduce(RGBImage original) {
269  
      Gridded gridded = new Gridded(w, h);
270  
      gridded.originalImage = original;
271  
      for (int i = 0; i < w*h; i++) {
272  
        RGBImage img = getGridElement(original, i);
273  
        Params p = bases[i].reproduce(img);
274  
        if (p == null)
275  
          return null;
276  
        gridded.array[i] = p;
277  
      }
278  
      return gridded;
279  
    }
280  
  }
281  
  
282  
  static ReproducerMaker baseMaker = new ReproducerMaker() {
283  
    public Reproducer make() {
284  
      return new VaryBest(
285  
        new Alternate(
286  
          new RandomSolid(), new RandomVSplit()
287  
        ));
288  
    }
289  
  };
290  
    
291  
  // main reproduce function
292  
  static Reproducer reproducer =
293  
    new Alternate(
294  
      baseMaker.make(),
295  
      new Grid(baseMaker, 4, 4),
296  
      new Grid(baseMaker, 16, 8)
297  
    );
298  
  
299  
  static Params reproduce(RGBImage original, int ntry) {
300  
    int w = original.getWidth(), h = original.getHeight();
301  
    return reproducer.reproduce(original);
302  
  }
303  
  
304  
  public static void main(String[] args) {
305  
    String imageID = "#1000326"; // Bryan Cranston!
306  
    if (args.length != 0) imageID = args[0];
307  
    final String _imageID = imageID;
308  
    
309  
    JFrame frame = new JFrame("A JavaX Frame");
310  
    
311  
    final ImageSurface imageSurface = new ImageSurface();
312  
    Component panel = imageSurface;
313  
    
314  
    frame.add(panel);
315  
    frame.setBounds(100, 100, 300, 200);
316  
    frame.setVisible(true);
317  
    exitOnFrameClose(frame);
318  
    
319  
    new Thread() {
320  
      public void run() {
321  
        originalImage = loadImage(_imageID);
322  
        originalImage = resizeToWidth(originalImage, 100);
323  
        
324  
        reproduceOpenEnd(originalImage, imageSurface);
325  
      }
326  
    }.start();
327  
  }
328  
  
329  
  static void reproduceOpenEnd(RGBImage original, ImageSurface imageSurface) {
330  
    Params best = null;
331  
    long lastPrint = 0;
332  
    for (int ntry = 1; ; ntry++) {
333  
      if (System.currentTimeMillis() >= lastPrint+1000) {
334  
        lastPrint = System.currentTimeMillis();
335  
        if (best == null)
336  
          System.out.println("Try " + ntry);
337  
        else {
338  
          System.out.println("Best: " + best);
339  
          System.out.println("Try " + ntry + ", score: " + formatDouble(best.getScore()*100, 2) + "%, structure size: " + structureSize(best, Params.class));
340  
        }
341  
      }
342  
      Params p = reproduce(original, ntry);
343  
      if (best == null || p != null && p.getScore() < best.getScore()) {
344  
        //System.out.println("New best! " + p.getScore());
345  
        best = p;
346  
        imageSurface.setImage(p.getImage());
347  
      }
348  
      
349  
      if (p != null && p.getScore() == 0.0)
350  
        break;
351  
    }
352  
  }
353  
  
354  
  static RGB probeRandomPixel(RGBImage image) {
355  
    int x = (int) (random()*(image.getWidth()-1));
356  
    int y = (int) (random()*(image.getHeight()-1));
357  
    return image.getPixel(x, y);
358  
  }
359  
  
360  
  static RGB randomColor() {
361  
    return new RGB(random(), random(), random());
362  
  }
363  
  
364  
  static RGBImage resizeToWidth(RGBImage image, int w) {
365  
    return resize(image, w, (int) ((image.getHeight()*(double) w)/image.getWidth()));
366  
  }
367  
  
368  
  public static RGBImage resize(RGBImage image, int w, int h) {
369  
    if (w == image.getWidth() && h == image.getHeight()) return image;
370  
371  
    int[] pixels = new int[w*h];
372  
    for (int y = 0; y < h; y++)
373  
      for (int x = 0; x < w; x++)
374  
        pixels[y*w+x] = image.getInt(x*image.getWidth()/w, y*image.getHeight()/h);
375  
    return new RGBImage(w, h, pixels);
376  
  }
377  
378  
  static boolean useImageCache = true;
379  
  static RGBImage loadImage(String snippetID) {
380  
   try {
381  
    File dir = new File(System.getProperty("user.home"), ".tinybrain/image-cache");
382  
    if (useImageCache) {
383  
      dir.mkdirs();
384  
      File file = new File(dir, snippetID + ".png");
385  
      if (file.exists() && file.length() != 0)
386  
        try {
387  
          return new RGBImage(ImageIO.read(file));
388  
        } catch (Throwable e) {
389  
          e.printStackTrace();
390  
          // fall back to loading from sourceforge
391  
        }
392  
    }
393  
394  
    String imageURL = getImageURL(parseSnippetID(snippetID));
395  
    System.err.println("Loading image: " + imageURL);
396  
    BufferedImage image = ImageIO.read(new URL(imageURL));
397  
398  
    if (useImageCache) {
399  
      File tempFile = new File(dir, snippetID + ".tmp." + System.currentTimeMillis());
400  
      ImageIO.write(image, "png", tempFile);
401  
      tempFile.renameTo(new File(dir, snippetID + ".png"));
402  
      //Log.info("Cached image.");
403  
    }
404  
405  
    //Log.info("Loaded image.");
406  
    return new RGBImage(image);
407  
   } catch (IOException e) {
408  
    throw new RuntimeException(e);
409  
   }
410  
  }
411  
412  
  static String getImageURL(long snippetID) throws IOException {
413  
    String url;
414  
    if (snippetID == 1000010 || snippetID == 1000012)
415  
      url = "http://tinybrain.de:8080/tb/show-blobimage.php?id=" + snippetID;
416  
    else
417  
      url = "http://eyeocr.sourceforge.net/filestore/filestore.php?cmd=serve&file=blob_" + snippetID
418  
        + "&contentType=image/png";
419  
    return url;
420  
  }
421  
422  
  public static long parseSnippetID(String snippetID) {
423  
    return Long.parseLong(shortenSnippetID(snippetID));
424  
  }
425  
426  
  private static String shortenSnippetID(String snippetID) {
427  
    if (snippetID.startsWith("#"))
428  
      snippetID = snippetID.substring(1);
429  
    String httpBlaBla = "http://tinybrain.de/";
430  
    if (snippetID.startsWith(httpBlaBla))
431  
      snippetID = snippetID.substring(httpBlaBla.length());
432  
    return snippetID;
433  
  }
434  
  
435  
  static Random _random = new Random();
436  
  static double random() {
437  
    return _random.nextInt(100001)/100000.0;
438  
  }
439  
  
440  
  static int random(int max) {
441  
    return _random.nextInt(max);
442  
  }
443  
  
444  
  static double random(double min, double max) {
445  
    return min+random()*(max-min);
446  
  }
447  
  
448  
  static void vsplit(RGBImage img, VSplit p) {
449  
    int w = img.getWidth(), h = img.getHeight();
450  
    for (int yy = 0; yy < h; yy++)
451  
      for (int xx = 0; xx < w; xx++) {
452  
        //double x = ((double) xx)/(w-1);
453  
        double y = ((double) yy)/(h-1);
454  
        RGB col = y <= p.splitPoint ? p.col1 : p.col2;
455  
        img.setPixel(xx, yy, col);
456  
      }
457  
  }
458  
  
459  
  public static double pixelDiff(RGB a, RGB b) {
460  
    return (Math.abs(a.r-b.r) + Math.abs(a.g-b.g) + Math.abs(a.b-b.b))/3;
461  
  }
462  
463  
  public static double diff(RGBImage image, RGBImage image2) {
464  
    int w = image.getWidth(), h = image.getHeight();
465  
    double sum = 0;
466  
    for (int y = 0; y < h; y++)
467  
      for (int x = 0; x < w; x++)
468  
        sum += pixelDiff(image.getRGB(x, y), image2.getRGB(x, y));
469  
    return sum/(w*h);
470  
  }
471  
  
472  
  public static void copy(RGBImage src, int srcX, int srcY, RGBImage dst, int dstX, int dstY, int w, int h) {
473  
    for (int y = 0; y < h; y++)
474  
      for (int x = 0; x < w; x++)
475  
        dst.setPixel(dstX+x, dstY+y, src.getPixel(srcX+x, srcY+y));
476  
  }
477  
  
478  
  public static int structureSize(Object o, Class baseClass) {
479  
    if (o == null) return 0;
480  
    int size = 1;
481  
    Class c = o.getClass();
482  
    if (c.isArray()) {
483  
      int n = Array.getLength(o);
484  
      for (int i = 0; i < n; i++)
485  
        size += structureSize(Array.get(o, i), baseClass);
486  
    } else
487  
      while (c != Object.class && c != baseClass) {
488  
        Field[] fields = c.getDeclaredFields();
489  
        for (Field field : fields) {
490  
          if ((field.getModifiers() & Modifier.STATIC) != 0)
491  
            continue;
492  
          if (field.getType().isPrimitive())
493  
            ++size;
494  
          else {
495  
            Object value = null;
496  
            try {
497  
              value = field.get(o);
498  
            } catch (IllegalAccessException e) {
499  
              throw new RuntimeException(e);
500  
            }
501  
            size += structureSize(value, baseClass);
502  
          }
503  
        }
504  
        c = c.getSuperclass();
505  
      }
506  
    return size;
507  
  }
508  
  
509  
  public static String formatDouble(double d, int digits) {
510  
    String format = "0.";
511  
    for (int i = 0; i < digits; i++) format += "#";
512  
    return new java.text.DecimalFormat(format, new java.text.DecimalFormatSymbols(Locale.ENGLISH)).format(d);
513  
  }
514  
515  
}

Author comment

Began life as a copy of #665

download  show line numbers  debug dex  old transpilations   

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

No comments. add comment

Snippet ID: #666
Snippet name: vsplit v6 (with structure size)
Eternal ID of this version: #666/1
Text MD5: 1fc478187326fbb6b5e5052a5b1d6c6e
Author: stefan
Category:
Type: JavaX source code
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2015-07-13 08:17:54
Source code size: 14715 bytes / 515 lines
Pitched / IR pitched: No / Yes
Views / Downloads: 724 / 621
Referenced in: [show references]