
prng.image.Letters Maven / Gradle / Ivy
The newest version!
package prng.image;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Random;
import java.util.function.DoubleConsumer;
/**
* Creates a display of at least 87 letters selected from a set of 59 characters. 59^87 exceeds 2^512.
*
* Each character has a color selected from 1536 possibles,
*/
public class Letters extends BasePainter {
/** Selected visually distinct characters */
private static final String CHARS = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabdefghijnpqrt$%&*+@#?{";
private static Color col(float r) {
r *= 6;
int s = (int) r;
r -= s;
switch (s) {
case 0:
return new Color(1, r, 0);
case 1:
return new Color(1 - r, 1f, 0);
case 2:
return new Color(0, 1, r);
case 3:
return new Color(0, 1 - r, 1);
case 4:
return new Color(r, 0, 1);
case 5:
return new Color(1, 0, 1 - r);
}
return Color.WHITE;
}
public Letters(Random rand) {
super(rand);
}
@Override
public void create(DoubleConsumer progress) {
// Select a font
GraphicsEnvironment e = GraphicsEnvironment.getLocalGraphicsEnvironment();
String[] families = e.getAvailableFontFamilyNames();
ArrayList fonts = new ArrayList<>();
for(String f:families) {
Font font = new Font(f, Font.PLAIN, 12);
if( font.canDisplayUpTo(CHARS) != -1 ) continue;
fonts.add(font);
}
ArrayList drawn = new ArrayList<>();
ArrayList bounds = new ArrayList<>();
BufferedImage image = new BufferedImage(512, 512,
BufferedImage.TYPE_INT_RGB);
myImage = image;
Graphics2D graphics = (Graphics2D) image.getGraphics();
graphics.setStroke(new BasicStroke(1));
Stroke fatStroke = new BasicStroke(3);
FontRenderContext frc = graphics.getFontRenderContext();
int placed;
do {
placed = 0;
graphics.clearRect(0, 0, 512, 512);
Font font = fonts.get(rand.nextInt(fonts.size()));
int count = 0;
double scale = 512;
while( scale >= 16 ) {
double xo = 0;
while( xo < 512 ) {
double yo = 0;
while( yo < 512 ) {
int chr = rand.nextInt(CHARS.length());
GlyphVector vec = font.createGlyphVector(frc,
CHARS.substring(chr, chr + 1));
Shape outline = vec.getGlyphOutline(0);
outline = AffineTransform.getRotateInstance(Math.PI * 2
* rand.nextDouble()).createTransformedShape(
outline);
Rectangle2D box = outline.getBounds2D();
double xs = scale / box.getWidth();
double ys = scale / box.getHeight();
double as = (Math.min(xs, ys) * 7) / 8;
outline = AffineTransform.getScaleInstance(as,
as).createTransformedShape(outline);
box = outline.getBounds2D();
outline = AffineTransform.getTranslateInstance(
(xo + (0.5 * (scale - box.getWidth())))
- box.getX(),
(yo + (0.5 * (scale - box.getHeight())))
- box.getY()).createTransformedShape(
outline);
Area letter = new Area(
fatStroke.createStrokedShape(outline));
letter.add(new Area(outline));
box = letter.getBounds2D();
boolean noHit = true;
for(int i=0;i
© 2015 - 2025 Weber Informatics LLC | Privacy Policy