Skip to content

Instantly share code, notes, and snippets.

@sk89q
Created November 20, 2011 01:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sk89q/1379639 to your computer and use it in GitHub Desktop.
Save sk89q/1379639 to your computer and use it in GitHub Desktop.
// $Id$
/*
* Copyright (C) 2010, 2011 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.minecraft.mapfun;
import java.awt.Color;
class ColorMatcher {
private static final Color[] colors = new Color[] {
null,
null,
null,
null,
new Color(89, 125, 39),
new Color(109, 153, 48),
new Color(127, 178, 56),
new Color(109, 153, 48),
new Color(174, 164, 115),
new Color(213, 201, 140),
new Color(247, 233, 163),
new Color(213, 201, 140),
new Color(117, 117, 117),
new Color(144, 144, 144),
new Color(167, 167, 167),
new Color(144, 144, 144),
new Color(180, 0, 0),
new Color(220, 0, 0),
new Color(255, 0, 0),
new Color(220, 0, 0),
new Color(112, 112, 180),
new Color(138, 138, 220),
new Color(160, 160, 255),
new Color(138, 138, 220),
new Color(117, 117, 117),
new Color(144, 144, 144),
new Color(167, 167, 167),
new Color(144, 144, 144),
new Color(0, 87, 0),
new Color(0, 106, 0),
new Color(0, 124, 0),
new Color(0, 106, 0),
new Color(180, 180, 180),
new Color(220, 220, 220),
new Color(255, 255, 255),
new Color(220, 220, 220),
new Color(115, 118, 129),
new Color(141, 144, 158),
new Color(164, 168, 184),
new Color(141,144,158),
new Color(129, 74, 33 ),
new Color(157, 91, 40),
new Color(183,106, 47),
new Color(157, 91, 40),
new Color(79, 79, 79),
new Color(96, 96, 96),
new Color(112,112,112),
new Color(96, 96, 96),
new Color(45, 45,180),
new Color(55, 55,220),
new Color(64, 64,255),
new Color(55, 55,220),
new Color(73, 58, 35),
new Color(89, 71, 43),
new Color(104, 83, 50),
new Color(89, 71, 43)
};
private ColorMatcher() {
}
private static double getDistance(Color c1, Color c2) {
double rmean = (c1.getRed() + c2.getRed()) / 2.0;
double r = c1.getRed() - c2.getRed();
double g = c1.getGreen() - c2.getGreen();
int b = c1.getBlue() - c2.getBlue();
double weightR = 2 + rmean / 256.0;
double weightG = 4.0;
double weightB = 2 + (255 - rmean) / 256.0;
return Math.sqrt(weightR*r*r + weightG*g*g + weightB*b*b);
}
public static byte match(Color color) {
/*if (r == 0 && g == 51 && b == 102) {
return 0;
}
if (r == 0 && g == 0 && b == 0) {
return 44;
}
if (r == 102 && g == 51 && b == 255) {
return 5*4;
}*/
double closestDistance = -1;
byte closestIndex = 0;
for (byte index = 0; index < colors.length; index++) {
Color testColor = colors[index];
if (testColor == null) {
continue;
}
double distance = getDistance(testColor, color);
if (closestDistance == -1 || distance < closestDistance) {
closestIndex = index;
closestDistance = distance;
}
}
return closestIndex;
}
}
// $Id$
/*
* Copyright (C) 2010, 2011 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.minecraft.mapfun;
public interface FrameSource {
public byte[] next();
public boolean hasData();
}
// $Id$
/*
* Copyright (C) 2010, 2011 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.minecraft.mapfun;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
public class ImageFrameSource implements FrameSource {
private List<byte[]> frames = new ArrayList<byte[]>();
private int frameIndex = 0;
public boolean hasData() {
return true;
}
/* (non-Javadoc)
* @see com.sk89q.minecraft.mapfun.FrameSource#read(java.io.File)
*/
public void read(File file) throws IOException {
BufferedImage img = null;
int i = 0;
img = ImageIO.read(file);
byte[] data = new byte[128 * 128];
for (int y = 0; y < img.getHeight(); y++) {
for (int x = 0; x < img.getWidth(); x++) {
int pixel = img.getRGB(x, y);
Color col = new Color(pixel);
data[i] = ColorMatcher.match(col);
i++;
}
}
frames.add(data);
}
/* (non-Javadoc)
* @see com.sk89q.minecraft.mapfun.FrameSource#next()
*/
public byte[] next() {
if (frameIndex >= frames.size()) {
frameIndex = 0;
}
return frames.get(frameIndex++);
}
}
// $Id$
/*
* Copyright (C) 2010, 2011 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.minecraft.mapfun;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
public class SKLogoSource implements FrameSource {
public static final Random random = new Random();
private int logoWidth = 7;
private int logoHeight = 5;
private byte[] logoData = new byte[] {
1, 1, 1, 0, 1, 0, 1,
1, 0, 0, 0, 1, 0, 1,
1, 1, 1, 0, 1, 1, 0,
0, 0, 1, 0, 1, 0, 1,
1, 1, 1, 0, 1, 0, 1,
};
private int logoX = random.nextInt(128 - logoWidth);
private int logoY = random.nextInt(128 - logoHeight);
private int velX = 1;
private int velY = 1;
public SKLogoSource(File file) throws IOException {
BufferedImage img = null;
int i = 0;
img = ImageIO.read(file);
byte[] data = new byte[img.getWidth() * img.getHeight()];
for (int y = 0; y < img.getHeight(); y++) {
for (int x = 0; x < img.getWidth(); x++) {
int pixel = img.getRGB(x, y);
Color col = new Color(pixel);
if (col.getRed() == 255 && col.getGreen() == 0 && col.getBlue() == 255) {
data[i] = 0;
} else {
data[i] = ColorMatcher.match(col);
}
i++;
}
}
logoWidth = img.getWidth();
logoHeight = img.getHeight();
logoData = data;
}
public byte[] next() {
logoX += velX;
logoY += velY;
if (logoX > 128 - 1 - logoWidth) {
velX = -1;
}
if (logoY > 128 - 1 - logoHeight) {
velY = -1;
}
if (logoX <= 0) {
velX = 1;
}
if (logoY <= 0) {
velY = 1;
}
byte[] data = new byte[128 * 128];
for (int x = 0; x < 128; x++) {
for (int y = 0; y < 128; y++) {
int index = y * 128 + x;
if (x >= logoX && x < logoX + logoWidth &&
y >= logoY && y < logoY + logoHeight &&
logoData[(y - logoY) * logoWidth + (x - logoX)] > 0) {
data[index] = logoData[(y - logoY) * logoWidth + (x - logoX)];
} else {
data[index] = 50;
}
}
}
return data;
}
public boolean hasData() {
return true;
}
}
// $Id$
/*
* Copyright (C) 2010, 2011 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.minecraft.mapfun;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Frame;
import com.sun.jna.NativeLibrary;
import uk.co.caprica.vlcj.player.MediaPlayerFactory;
import uk.co.caprica.vlcj.player.direct.DirectMediaPlayer;
import uk.co.caprica.vlcj.player.direct.RenderCallbackAdapter;
public class VLCFrameSource implements FrameSource {
private static final int WIDTH = 128;
private static final int HEIGHT = 128;
private byte[] lastData;
private DirectMediaPlayer mediaPlayer;
private long lastDraw;
public VLCFrameSource() {
NativeLibrary.addSearchPath("libvlc", "C:\\Program Files\\VideoLAN\\VLC");
MediaPlayerFactory factory = new MediaPlayerFactory("--no-video-title-show");
mediaPlayer = factory.newDirectMediaPlayer(WIDTH, HEIGHT, new RenderCallback(WIDTH, HEIGHT));
mediaPlayer.setPlaySubItems(true);
lastData = new byte[WIDTH * HEIGHT];
for (int i = 0; i < lastData.length; i++) {
lastData[i] = 40;
}
}
public void play(String url) {
mediaPlayer.playMedia(url);
}
public byte[] next() {
return lastData;
}
public boolean hasData() {
return System.currentTimeMillis() - lastDraw < 500;
}
private class RenderCallback extends RenderCallbackAdapter {
private int t = 0;
public RenderCallback(int width, int height) {
super(new int[width * height]);
}
@Override
public void onDisplay(int[] data) {
lastDraw = System.currentTimeMillis();
t++;
if (t % 2 != 0) {
return;
}
byte[] newData = new byte[WIDTH * HEIGHT];
for (int i = 0; i < data.length; i++) {
Color col = new Color(data[i]);
newData[i] = ColorMatcher.match(col);
}
/*for (int y = 0; y < 128; y++) {
for (int x = 0; x < 128; x++) {
int i = y * WIDTH + x;
Color col = new Color(data[i]);
newData[i] = MapCol.getColor(col.getRed(), col.getGreen(), col.getBlue());
}
}*/
lastData = newData;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment