很粗糙的地图画生成器

不是能直接导入的那种,只是颜色的替换。。。

我的世界Wiki有关地图画的介绍

因为太懒(技术也不够😅),所以只考虑平面地图画,平面的材料也只有各种地毯。效果肯定没那些大佬们的好,只是瞎编着玩的东东,实际作用有限。

我是把RGB转换为Hsl,并通过寻找相近的H(色相)来替代颜色。s(饱和度)过低与l(亮度)过高或过低时直接走黑白模式通过亮度确定颜色,不通过色相判断。

下面的文档里整理了一下羊毛毯在地图上的颜色的RGB值及其H值。
>>>羊毛毯地图画.docx<<<

再下面是具体的程序,水平有限,肯定会有一些瑕疵啦。
这里没缩进,想看的复制去IDE里看吧😉

//Main.java

package pixelpaint;

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import pixelpaint.Rgb2Hsl.Pixel;

public class Main {
static int A_width = 0;
static int A_height = 0;
static int max = 0;
static double h = 0;
static double l = 0;
static double s = 0;

static int hei = (25 << 16) | (25 << 8) | 25;
static int hui = (76 << 16) | (76 << 8) | 76;
static int danhui = (153 << 16) | (153 << 8) | 153;
static int bai = (255 << 16) | (255 << 8) | 255;

static int huang = (229 << 16) | (229 << 8) | 51;
static int cheng = (216 << 16) | (127 << 8) | 51;
static int huanglv = (127 << 16) | (204 << 8) | 25;
static int lv = (102 << 16) | (127 << 8) | 51;
static int lan = (51 << 16) | (76 << 8) | 178;
static int danlan = (102 << 16) | (153 << 8) | 216;
static int qing = (76 << 16) | (127 << 8) | 153;
static int zi = (127 << 16) | (63 << 8) | 178;
static int fenhong = (242 << 16) | (127 << 8) | 165;
static int pinhong = (178 << 16) | (76 << 8) | 216;
static int hong = (153 << 16) | (51 << 8) | 51;
static int zong = (102 << 16) | (76) | 51;

static java.awt.image.BufferedImage A_img;

public static void main(String[] args) {
new Window();
}

public Main(String path, int w_, int h_, boolean color) {
try {
File cc = new File(path);
java.awt.image.BufferedImage img = ImageIO.read(cc);
A_width = w_;
A_height = h_;
String formatName = path.substring(path.lastIndexOf(“.”) + 1);
String fileName = path.substring(0, path.lastIndexOf(“.”)) + “_结果”;
A_img = zoomOutImage(img);

if (color) {
for (int y = 0; y < A_height; y++) {
for (int x = 0; x < A_width; x++) {

int r = A_img.getRGB(x, y);

int red = (r >> 16) & 0x0ff;
int green = (r >> 8) & 0x0ff;
int blue = r & 0x0ff;

Pixel pixel = new Pixel(red, green, blue);
new Rgb2Hsl(pixel);
h = Pixel.geth();
l = Pixel.getl();
s = Pixel.gets();

if (l < 0.2 || l > 0.8 || s < 0.3) {
WAndB(x, y);
} else {

if (h > 0.60268083871435822) {
if (h > 0.8758169934640523) {
if (h > 0.9207664884135472) {
if (h > 0.9616161616161616) {
A_img.setRGB(x, y, hong);
} else {
A_img.setRGB(x, y, cheng);
}
} else {
A_img.setRGB(x, y, zong);
}
} else {
if (h > 0.77007375281779865) {
if (h > 0.805921052631579) {
A_img.setRGB(x, y, huang);
} else {
A_img.setRGB(x, y, lv);
}
} else {
A_img.setRGB(x, y, huanglv);
}
}
} else {
if (h > 0.30336072121419606) {
if (h > 0.387018234562784925) {
if (h > 0.425808840282524495) {
A_img.setRGB(x, y, qing);
} else {
A_img.setRGB(x, y, danlan);
}
} else {
A_img.setRGB(x, y, lan);
}
} else {
if (h > 0.1334886128364389275) {
if (h > 0.22624223602484471) {
A_img.setRGB(x, y, zi);
} else {
A_img.setRGB(x, y, pinhong);
}
} else {
if (h > 0.0275362318840579775) {
A_img.setRGB(x, y, fenhong);
} else {
A_img.setRGB(x, y, hong);
}
}
}
}

}

}
}

} else {
for (int y = 0; y < A_height; y++) {
for (int x = 0; x < A_width; x++) {
WAndB(x, y);
}
}

}

ImageIO.write(A_img, formatName, new File(fileName + “.” + formatName));

} catch (IOException e) {
e.printStackTrace();
}

}

public static void WAndB(int x, int y) {
int r = A_img.getRGB(x, y);

int red = (r >> 16) & 0x0ff;
int green = (r >> 8) & 0x0ff;
int blue = r & 0x0ff;

max = Math.max(red, Math.max(green, blue));

if (max < 50.5) {
A_img.setRGB(x, y, hei);
} else if (max < 114.5) {
A_img.setRGB(x, y, hui);
} else if (max < 204.5) {
A_img.setRGB(x, y, danhui);
} else if (max < 256) {
A_img.setRGB(x, y, bai);
}
}

public static BufferedImage zoomOutImage(BufferedImage originalImage) {
BufferedImage newImage = new BufferedImage(A_width, A_height, originalImage.getType());
Graphics g = newImage.getGraphics();
g.drawImage(originalImage, 0, 0, A_width, A_height, null);
g.dispose();
return newImage;
}

}


//Rgb2Hsl.java

package pixelpaint;
//来源: https://www.jianshu.com/p/366ed43c67f6
public class Rgb2Hsl {
public static final double MaxRGB = 255.0;

public Rgb2Hsl(Pixel pixel) {
int red = pixel.red;
int blue = pixel.blue;
int green = pixel.green;
double b, delta, g, max, min, r;
double hue, saturation, luminosity;

r = (double) red / MaxRGB;
g = (double) green / MaxRGB;
b = (double) blue / MaxRGB;
max = Math.max(r, Math.max(g, b));
min = Math.min(r, Math.min(g, b));

hue = 0.0;
saturation = 0.0;
luminosity = (min + max) / 2.0;
delta = max - min;
if (delta == 0.0) {
Pixel.hue = hue;
Pixel.saturation = saturation;
Pixel.luminosity = luminosity;
return;
}
saturation = delta / ((luminosity <= 0.5) ? (min + max) : (2.0 - max - min));
if (r == max)
hue = (g == min ? 5.0 + (max - b) / delta : 1.0 - (max - g) / delta);
else if (g == max)
hue = (b == min ? 1.0 + (max - r) / delta : 3.0 - (max - b) / delta);
else
hue = (r == min ? 3.0 + (max - g) / delta : 5.0 - (max - r) / delta);
hue /= 6.0;

Pixel.hue = hue;
Pixel.saturation = saturation;
Pixel.luminosity = luminosity;
}

public static class Pixel {
int red;
int blue;
int green;
static double hue;
static double luminosity;
static double saturation;

public Pixel(int red, int blue, int green) {
this.red = red;
this.blue = blue;
this.green = green;
}

public static double geth() {
return hue;
}

public static double getl() {
return luminosity;
}

public static double gets() {
return saturation;
}

}

}


//Window.java

package pixelpaint;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.File;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

import javax.imageio.ImageIO;
import javax.swing.ButtonGroup;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;

public class Window extends JFrame {

private static final long serialVersionUID = 1L;
private JPanel contentPane;
private JTextField textField;
private Timer timer = new Timer();
int choice = 0;
int width = 0;
int height = 0;
boolean isimg = false;
boolean color = false;
String path = null;

public Window() {
setResizable(false);
setTitle(“MC羊毛像素画转换器 BY:CC2001”);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(200, 250, 450, 190);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);

JButton btnNewButton = new JButton(“选择文件”);
btnNewButton.setBounds(321, 24, 103, 23);
contentPane.add(btnNewButton);

btnNewButton.setBackground(Color.WHITE);

textField = new JTextField();
textField.setBackground(Color.WHITE);
textField.setEditable(false);
textField.setBounds(10, 25, 301, 23);
contentPane.add(textField);
textField.setColumns(10);

JLabel lblNewLabel = new JLabel(“选择要转换的图片文件 : ( .jpg格式 )”);
lblNewLabel.setBounds(10, 10, 255, 15);
contentPane.add(lblNewLabel);

JLabel lblNewLabel_1 = new JLabel(“目标大小 :”);
lblNewLabel_1.setBounds(10, 78, 60, 15);

contentPane.add(lblNewLabel_1);

JSpinner spinner_w = new JSpinner();
spinner_w.setBounds(80, 75, 60, 22);
contentPane.add(spinner_w);

JSpinner spinner_h = new JSpinner();
spinner_h.setBounds(150, 75, 60, 22);
contentPane.add(spinner_h);

JLabel lblNewLabel_2 = new JLabel(“等比例缩放 :”);
lblNewLabel_2.setBounds(242, 78, 75, 15);
contentPane.add(lblNewLabel_2);

JComboBox comboBox = new JComboBox();
comboBox.addPopupMenuListener(new PopupMenuListener() {
public void popupMenuCanceled(PopupMenuEvent e) {
}

public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
choice = comboBox.getSelectedIndex();
}

public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
}
});
comboBox.setModel(new DefaultComboBoxModel(new String[] { “关闭”, “改变宽”, “改变高” }));
comboBox.setBackground(Color.WHITE);
comboBox.setBounds(321, 74, 75, 23);
contentPane.add(comboBox);

JLabel lblNewLabel_3 = new JLabel(“颜色模式 :”);
lblNewLabel_3.setBounds(10, 123, 60, 15);
contentPane.add(lblNewLabel_3);

JRadioButton rdbtnNewRadioButton = new JRadioButton(“灰度羊毛”);
rdbtnNewRadioButton.setSelected(true);
rdbtnNewRadioButton.setBounds(80, 119, 80, 23);
contentPane.add(rdbtnNewRadioButton);

JRadioButton rdbtnNewRadioButton_1 = new JRadioButton(“全彩羊毛”);
rdbtnNewRadioButton_1.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
color = rdbtnNewRadioButton_1.isSelected();
}
});

rdbtnNewRadioButton_1.setBounds(162, 119, 80, 23);
contentPane.add(rdbtnNewRadioButton_1);

ButtonGroup btnGroup = new ButtonGroup();
btnGroup.add(rdbtnNewRadioButton);
btnGroup.add(rdbtnNewRadioButton_1);

JButton btnNewButton_1 = new JButton(“取消”);
btnNewButton_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});

btnNewButton_1.setBackground(Color.WHITE);
btnNewButton_1.setBounds(364, 119, 60, 23);
contentPane.add(btnNewButton_1);

JButton btnNewButton_2 = new JButton(“确定”);
btnNewButton_2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (isimg) {

int w = (int) spinner_w.getValue();
int h = (int) spinner_h.getValue();
new Main(path, w, h, color);
setTitle(“======生成完毕======”);
timer.schedule(new TimerTask() {
public void run() {
setTitle(“MC羊毛像素画转换器 BY:CC2001”);
}
}, 3000);

} else
JOptionPane.showMessageDialog(getComponent(0), “不是可读取的图片文件”);
}
});
btnNewButton_2.setBackground(Color.WHITE);
btnNewButton_2.setBounds(275, 119, 60, 23);
contentPane.add(btnNewButton_2);

spinner_w.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
if (choice == 1)
spinner_h.setValue((int) spinner_w.getValue() * height / width);
}
});

spinner_h.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
if (choice == 2)
spinner_w.setValue((int) spinner_h.getValue() * width / height);
}
});

btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFileChooser cc = new JFileChooser();
cc.showOpenDialog(getParent());

if (cc.getSelectedFile() != null) {
isimg = true;
File file = cc.getSelectedFile();
path = file.getPath();
textField.setText(path);
try {
java.awt.image.BufferedImage img = ImageIO.read(new File(path));

if (img != null) {
width = img.getWidth();
height = img.getHeight();
spinner_w.setModel(new SpinnerNumberModel(width, null, null, 1));
spinner_h.setModel(new SpinnerNumberModel(height, null, null, 1));

} else {
JOptionPane.showMessageDialog(getComponent(0), “不是可读取的图片文件”);
isimg = false;
}
} catch (IOException e1) {
e1.printStackTrace();
}
}

}

});

this.setVisible(true);
}
}


应该是能跑的,只支持*.jpg格式,生成的图片与原图片在同一文件夹。




性感CC - 在线找打
------ 我是分割线 ------