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

472
LINES

< > BotCompany Repo | #665 // vsplit v5 (with grid)

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

Author comment

Began life as a copy of #664

download  show line numbers  debug dex  old transpilations   

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

No comments. add comment

Snippet ID: #665
Snippet name: vsplit v5 (with grid)
Eternal ID of this version: #665/1
Text MD5: abcecf0141823313b348cd49512b2f4b
Author: stefan
Category:
Type: JavaX source code
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2015-07-13 07:15:51
Source code size: 13286 bytes / 472 lines
Pitched / IR pitched: No / Yes
Views / Downloads: 636 / 534
Referenced in: [show references]