Libraryless. Click here for Pure Java version (1443L/10K/31K).
!747 import java.awt.*; import java.awt.image.*; import javax.imageio.*; import static java.lang.Math.*; !image classes !FrameWithImages class P { double x, y; *(double *x, double *y) {} } interface Reproducer { public main.Params reproduce(RGBImage original); } interface ReproducerMaker { public Reproducer make(); } main { static Object androidContext; static int imageWidth = 200; !include #1000522 // helper functions for image reproduction !include #1000898 // exitOnFrameClose static double pi = PI; static double rotate_x(P p, double angle) { angle = angle*pi/180; return p.x*cos(angle)-p.y*sin(angle); } static double sideshiftlimit = sqrt(2)/2; static class Magnet extends Params { double angle, sideshift; RGB col1 = new RGB(Color.black), col2 = new RGB(Color.white); RGB def(double x, double y) { P p = new P(x-0.5, y-0.5); x = rotate_x(p, -angle); return x < sideshift ? col1 : col2; } Magnet copy() { new Magnet p; baseClone(p); p.sideshift = sideshift; p.angle = angle; p.col1 = col1; p.col2 = col2; return p; } public String toString() { return "M " + formatDouble(sideshift, 2) + " " + (int) angle + " " + col1 + " " + col2; } RGBImage render() { int w = originalImage.getWidth(), h = originalImage.getHeight(); RGBImage image = new RGBImage(w, h, Color.white); paint(image, this); return image; } } static abstract class Params { RGBImage originalImage; abstract RGBImage render(); abstract Params copy(); void baseClone(Params p) { p.originalImage = originalImage; } RGBImage rendered; RGBImage getImage() { if (rendered == null) rendered = render(); return rendered; } double score = 2.0; double getScore() { if (score == 2.0) score = calcScore(); return score; } double calcScore() { return diff(originalImage, getImage()); } boolean isBetterThan(Params p) { return getScore() < p.getScore(); } } static class RandomMagnet implements Reproducer { int n = -1; public Params reproduce(RGBImage original) { ++n; new Magnet p; p.originalImage = original; p.sideshift = random(-sideshiftlimit, sideshiftlimit); p.angle = random()*360; if (n % 2 == 0) { p.col1 = randomColor(); p.col2 = randomColor(); } else { p.col1 = probeRandomPixel(original); p.col2 = probeRandomPixel(original); } return p; } } static class VaryBest implements Reproducer { Reproducer base; Params best; VaryBest(Reproducer base) { this.base = base; } public Params reproduce(RGBImage original) { Params p = base.reproduce(original); if (best == null || p.isBetterThan(best)) best = p; Params variation = vary(best); //System.out.println("Best: " + best.getScore() + ", variation: " + variation.getScore()); if (variation.isBetterThan(best)) { //System.out.println("Using variation, diff=" + (best.getScore()-variation.getScore())); best = variation; } return best; } Params vary(Params p) { if (p instanceof Magnet) { Magnet n = ((Magnet) p).copy(); int s = random(3); if (s == 0) { s = random(2); if (s == 0) n.sideshift = varySideshift(n.sideshift); else { //double old = n.angle; n.angle = (n.angle+360+random(-5, 5)) % 360; //System.out.println("angle: " + formatDouble(old, 1) + " -> " + formatDouble(n.angle, 1)); } } else if (s == 1) n.col1 = varyColor(n.col1); else n.col2 = varyColor(n.col2); return n; } return null; } double varySideshift(double sideshift) { return max(-sideshiftlimit, min(sideshiftlimit, sideshift+random(-0.1, 0.1))); } double varyN(double x) { return Math.max(0, Math.min(1, x+random(-0.1, 0.1))); } float varyChannel(float x) { return Math.max(0f, Math.min(1f, (float) (x+random(-0.1, 0.1)))); } RGB varyColor(RGB rgb) { int s = random(3); if (s == 0) return new RGB(varyChannel(rgb.r), rgb.g, rgb.b); else if (s == 1) return new RGB(rgb.r, varyChannel(rgb.g), rgb.b); else return new RGB(rgb.r, rgb.g, varyChannel(rgb.b)); } } static class Gridded extends Params { int w, h; Params[] array; Gridded(int w, int h) { this.w = w; this.h = h; array = new Params[w*h]; } Gridded copy() { Gridded p = new Gridded(w, h); baseClone(p); for (int i = 0; i < w*h; i++) p.array[i] = array[i].copy(); return p; } public String toString() { StringBuilder buf = new StringBuilder("grid{"); for (int i = 0; i < w*h; i++) { if (i != 0) buf.append(", "); buf.append(array[i]); } return buf + "}"; } public RGBImage render() { int ow = originalImage.getWidth(), oh = originalImage.getHeight(); RGBImage img = new RGBImage(ow, oh, Color.white); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { int x1 = x*ow/w, y1 = y*oh/h; int x2 = (x+1)*ow/w, y2 = (y+1)*oh/h; RGBImage part = array[y*w+x].render(); main.copy(part, 0, 0, img, x1, y1, part.getWidth(), part.getHeight()); } return img; } } static class Grid implements Reproducer { int w, h; Reproducer[] bases; Grid(ReproducerMaker maker, int w, int h) { this.w = w; this.h = h; bases = new Reproducer[w*h]; for (int i = 0; i < w*h; i++) bases[i] = maker.make(); } RGBImage getGridElement(RGBImage originalImage, int i) { int ow = originalImage.getWidth(), oh = originalImage.getHeight(); int y = i / w; int x = i % w; int x1 = x*ow/w, y1 = y*oh/h; int x2 = (x+1)*ow/w, y2 = (y+1)*oh/h; return originalImage.clip(x1, y1, x2-x1, y2-y1); } public Params reproduce(RGBImage original) { Gridded gridded = new Gridded(w, h); gridded.originalImage = original; for (int i = 0; i < w*h; i++) { RGBImage img = getGridElement(original, i); Params p = bases[i].reproduce(img); if (p == null) return null; gridded.array[i] = p; } return gridded; } } static ReproducerMaker baseMaker = new ReproducerMaker() { public Reproducer make() { return new VaryBest(new RandomMagnet()); } }; // main reproduce function static Reproducer reproducer; static String imageID = "#1000326"; // Bryan Cranston! static RGBImage originalImage; static FrameWithImages fwi; static double zoom = 1; psvm { for (int i = 0; i < args.length; i++) { String arg = args[i]; if (isSnippetID(arg)) imageID = arg; else if (arg.equals("zoom")) zoom = Double.parseDouble(args[++i]); else if (arg.equals("w") || arg.equals("width")) { String w = args[++i]; imageWidth = w.equals("original") ? -1 : Integer.parseInt(w); } else System.out.println("Unknown argument: " + arg); } fwi = new FrameWithImages(1); fwi.hop(); thread { originalImage = loadImage(imageID); if (imageWidth < 0) imageWidth = originalImage.getWidth(); else originalImage = resizeToWidth(originalImage, imageWidth); fwi.setZoom(zoom); fwi.setInnerSize(originalImage); int gx = originalImage.getWidth()/8, gy = originalImage.getHeight()/8; reproducer = new Grid(baseMaker, gx, gy); reproduceOpenEnd(originalImage); } /* new Magnet m; m.sideshift = -0.2; m.angle = 30; while (true) { m.angle = (m.angle+1) % 360; //System.out.println("Angle: " + m.angle); RGBImage img = new RGBImage(100, 100, Color.gray); paint(img, m); fwi.setImage(0, img); } */ } static void reproduceOpenEnd(RGBImage original) { Params best = null; long lastPrint = 0, lastN = 0; for (long ntry = 1; ; ntry++) { long now = System.currentTimeMillis(); if (now >= lastPrint+1000) { long tps = (ntry-lastN)*1000/(now-lastPrint); lastPrint = now; lastN = ntry; String s = "Try " + ntry + "(" + tps + "/s)"; if (best == null) System.out.println(s); else { //System.out.println("Best: " + best); System.out.println(s + ", score: " + formatDouble(best.getScore()*100, 3) + "%"); //, structure size: " + structureSize(best, Params.class)); } } Params p = reproducer.reproduce(original); if (best == null || p != null && p.getScore() < best.getScore()) { //System.out.println("New best! " + p.getScore()); best = p; fwi.setImage(0, p.getImage()); } if (p != null && p.getScore() == 0.0) break; } } static void paint(RGBImage img, Magnet m) { int w = img.getWidth(), h = img.getHeight(); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { double nx = x/(double)(w-1); double ny = y/(double)(h-1); img.setPixel(x, y, m.def(nx, ny)); } } }
Began life as a copy of #1000541
download show line numbers debug dex old transpilations
Travelled to 15 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, teubizvjbppd, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1000550 |
Snippet name: | Magnetize image (current) |
Eternal ID of this version: | #1000550/1 |
Text MD5: | b547d264a0550449b25f102aaac558ae |
Transpilation MD5: | 29ca80eb49bc360e234d561d4182b960 |
Author: | stefan |
Category: | |
Type: | JavaX source code |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2015-09-13 15:10:58 |
Source code size: | 10027 bytes / 366 lines |
Pitched / IR pitched: | No / Yes |
Views / Downloads: | 630 / 627 |
Referenced in: | [show references] |