Antialiased hexagonal icons

For general discussion about Conway's Game of Life.
Post Reply
MarkJ
Posts: 31
Joined: October 22nd, 2010, 5:57 am

Antialiased hexagonal icons

Post by MarkJ » May 28th, 2020, 5:05 pm

I felt like redoing the slanted hexagonal icons with Antialiasing and gamma correction (works only on black background)

For reference, here is Tim Hutton's attempt from 10 years ago: https://timhutton.github.io/2010/05/21/31455.html
Z8lhZnA.png
Z8lhZnA.png (4.05 KiB) Viewed 96 times
These XPM icons are uncompromised true-color gray-scale renderings. Luck just has it that no more than 9 shades are actually used.

Code: Select all

/* colors */
". c #000000"
"A c #333333"
"B c #565656"
"C c #686868"
"D c #CDCDCD"
"E c #D8D8D8"
"F c #DBDBDB"
"G c #FDFDFD"
"H c #FFFFFF"
/* icon for state 0 */
"......AEDC....................."
".....AFHHGDC..................."
"....AFHHHHHGDC................."
"...AFHHHHHHHHGDC..............."
"..AFHHHHHHHHHHHGDC............."
".AFHHHHHHHHHHHHHHGDC..........."
"AFHHHHHHHHHHHHHHHHHGDC........."
"EHHHHHHHHHHHHHHHHHHHHGDB......."
"DHHHHHHHHHHHHHHHHHHHHHHD......."
"CGHHHHHHHHHHHHHHHHHHHHHGC......"
".DHHHHHHHHHHHHHHHHHHHHHHD......"
".CGHHHHHHHHHHHHHHHHHHHHHGC....."
"..DHHHHHHHHHHHHHHHHHHHHHHD....."
"..CGHHHHHHHHHHHHHHHHHHHHHGC...."
"...DHHHHHHHHHHHHHHHHHHHHHHD...."
"...CGHHHHHHHHHHHHHHHHHHHHHGC..."
"....DHHHHHHHHHHHHHHHHHHHHHHD..."
"....CGHHHHHHHHHHHHHHHHHHHHHGC.."
".....DHHHHHHHHHHHHHHHHHHHHHHD.."
".....CGHHHHHHHHHHHHHHHHHHHHHGC."
"......DHHHHHHHHHHHHHHHHHHHHHHD."
"......CGHHHHHHHHHHHHHHHHHHHHHGC"
".......DHHHHHHHHHHHHHHHHHHHHHHD"
".......BDGHHHHHHHHHHHHHHHHHHHHE"
".........CDGHHHHHHHHHHHHHHHHHFA"
"...........CDGHHHHHHHHHHHHHHFA."
".............CDGHHHHHHHHHHHFA.."
"...............CDGHHHHHHHHFA..."
".................CDGHHHHHFA...."
"...................CDGHHFA....."
".....................CDEA......"

Code: Select all

/* colors */
". c #000000"
"A c #343434"
"B c #575757"
"C c #686868"
"D c #CECECE"
"E c #D9D9D9"
"F c #DBDBDB"
"G c #FDFDFD"
"H c #FFFFFF"
/* icon for state 0 */
"..AEDC........."
".AFHHGDC......."
"AFHHHHHGDC....."
"EHHHHHHHHGDB..."
"DHHHHHHHHHHD..."
"CGHHHHHHHHHGC.."
".DHHHHHHHHHHD.."
".CGHHHHHHHHHGC."
"..DHHHHHHHHHHD."
"..CGHHHHHHHHHGC"
"...DHHHHHHHHHHD"
"...BDGHHHHHHHHE"
".....CDGHHHHHFA"
".......CDGHHFA."
".........CDEA.."

Code: Select all

/* colors */
". c #000000"
"A c #343434"
"B c #575757"
"C c #686868"
"D c #CECECE"
"E c #D9D9D9"
"F c #FDFDFD"
"G c #FFFFFF"
/* icon for state 0 */
"AEDC..."
"EGGFDB."
"DGGGGD."
"CFGGGFC"
".DGGGGD"
".BDFGGE"
"...CDEA"
The program that created them:

Code: Select all

import java.awt.Graphics2D;
import java.awt.geom.Path2D;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import javax.swing.JPanel;

public class CreateHexagonalIconsMain extends JPanel {
	private static final int BIG_SIZE = 7 * 15 * 31; // 3255

	public static void main(String[] args) {
		BufferedImage image = new BufferedImage(BIG_SIZE, BIG_SIZE, BufferedImage.TYPE_BYTE_GRAY);

		// A little Java hack
		image.setAccelerationPriority(0);
		byte[] pixels = ((DataBufferByte)image.getRaster().getDataBuffer()).getData();

		drawHexagon(image);

		// Create entire @ICONS section (copy-paste ready)
		iconize(pixels, 31, 3);
		iconize(pixels, 15, 3);
		iconize(pixels, 7, 3);
	}

	private static void drawHexagon(BufferedImage image) {
		double x = (BIG_SIZE - 1) / 4.0;

		Graphics2D g = image.createGraphics();
		try {
			Path2D path = new Path2D.Double();
			path.moveTo(0, x);
			path.lineTo(x, 0);
			path.lineTo(x * 3, x);
			path.lineTo(x * 4, x * 3);
			path.lineTo(x * 3, x * 4);
			path.lineTo(x, x * 3);
			path.closePath();
			g.fill(path);
		} finally {
			g.dispose();
		}
	}

	private static void iconize(byte[] pixels, int size, int numIcons) {
		int zoom = BIG_SIZE / size;

		if (zoom * size != BIG_SIZE)
			throw new IllegalArgumentException("size doesn't divide BIG_SIZE: " + size + ", " + BIG_SIZE);

		int[][] icon = new int[size][size];
		int     p    = 0;
		for (int y = 0; y < BIG_SIZE; y++)
			for (int x = 0; x < BIG_SIZE; x++)
				icon[y / zoom][x / zoom] += pixels[p++] & 0xFF;

		int[] hist = new int[256];
		for (int y = 0; y < size; y++) {
			for (int x = 0; x < size; x++) {
				icon[y][x] = (int)Math.round(Math.pow(icon[y][x] / 255.0 / zoom / zoom, 1 / 2.2) * 255);
				hist[icon[y][x]]++;
			}
		}

		char[] map = new char[256];
		map[0] = '.';
		int numColors = 1;
		for (int i = 1; i < 256; i++) {
			if (hist[i] != 0) {
				//noinspection CharUsedInArithmeticContext
				map[i] = (char)(numColors + 'A' - 1);
				numColors++;
			}
		}

		System.out.println();
		System.out.println("XPM");
		System.out.println("/* width height num_colors chars_per_pixel */");
		System.out.println("\"" + size + ' ' + (size * numIcons) + ' ' + numColors + " 1\"");
		System.out.println("/* colors */");
		for (int i = 0; i < 256; i++) {
			if (map[i] != 0) {
				String hex = hexOctet(i);
				System.out.println("\"" + map[i] + " c #" + hex + hex + hex + '"');
			}
		}

		for (int i = 0; i < numIcons; i++) {
			System.out.println("/* icon for state " + i + " */");
			for (int y = 0; y < size; y++) {
				System.out.print('"');
				for (int x = 0; x < size; x++)
					System.out.print(map[icon[y][x]]);

				System.out.println('"');
			}
		}
	}

	public static String hexOctet(int i) {
		String s = Integer.toHexString(i >>> 4) +
		           Integer.toHexString(i & 0xF);
		return s.toUpperCase();
	}
}

Post Reply