mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-24 05:03:34 -04:00
Refactor /img to be more modular
This commit is contained in:
parent
e3500790f1
commit
bddec7cca6
@ -41,44 +41,36 @@ namespace MCGalaxy.Commands.Building {
|
|||||||
public override void Use(Player p, string message) {
|
public override void Use(Player p, string message) {
|
||||||
if (!Directory.Exists("extra/images/"))
|
if (!Directory.Exists("extra/images/"))
|
||||||
Directory.CreateDirectory("extra/images/");
|
Directory.CreateDirectory("extra/images/");
|
||||||
bool layer = false;
|
|
||||||
byte popType = 1;
|
|
||||||
string bitmapLoc = null;
|
|
||||||
if (message == "") { Help(p); return; }
|
if (message == "") { Help(p); return; }
|
||||||
|
string[] parts = message.SplitSpaces(3);
|
||||||
if (message.IndexOf(' ') != -1) {
|
|
||||||
string[] args = message.Split(' ');
|
|
||||||
for (int i = 0; i < args.Length; i++)
|
|
||||||
{
|
|
||||||
if (args[i] == "layer" || args[i] == "l") layer = true;
|
|
||||||
else if (args[i] == "1" || args[i] == "2color") popType = 1;
|
|
||||||
else if (args[i] == "2" || args[i] == "1color") popType = 2;
|
|
||||||
else if (args[i] == "3" || args[i] == "2gray") popType = 3;
|
|
||||||
else if (args[i] == "4" || args[i] == "1gray") popType = 4;
|
|
||||||
else if (args[i] == "5" || args[i] == "bw") popType = 5;
|
|
||||||
else if (args[i] == "6" || args[i] == "gray") popType = 6;
|
|
||||||
}
|
|
||||||
message = args[args.Length - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.IndexOf('/') == -1 && message.IndexOf('.') != -1) {
|
|
||||||
if (!DownloadWebFile("http://www.imgur.com/" + message, p)) return;
|
|
||||||
bitmapLoc = "tempImage_" + p.name;
|
|
||||||
} else if (message.IndexOf('.') != -1) {
|
|
||||||
if (!DownloadWebFile(message, p)) return;
|
|
||||||
bitmapLoc = "tempImage_" + p.name;
|
|
||||||
} else {
|
|
||||||
bitmapLoc = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!File.Exists("extra/images/" + bitmapLoc + ".bmp")) {
|
|
||||||
Player.Message(p, "The URL entered was invalid!"); return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DrawArgs dArgs = default(DrawArgs);
|
DrawArgs dArgs = default(DrawArgs);
|
||||||
dArgs.layer = layer;
|
dArgs.palette = ImagePalette.Palettes[0];
|
||||||
dArgs.name = bitmapLoc;
|
dArgs.dualLayered = true;
|
||||||
dArgs.popType = popType;
|
|
||||||
|
if (parts.Length == 3) {
|
||||||
|
string mode = parts[2];
|
||||||
|
if (mode.CaselessEq("horizontal")) dArgs.layer = true;
|
||||||
|
if (mode.CaselessEq("vertical")) dArgs.dualLayered = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parts.Length >= 2) {
|
||||||
|
dArgs.palette = ImagePalette.Find(parts[1]);
|
||||||
|
if (dArgs.palette == null) {
|
||||||
|
Player.Message(p, "Palette {0} not found.", parts[1]); return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.IndexOf('.') != -1) {
|
||||||
|
if (!DownloadWebFile(message, p)) return;
|
||||||
|
dArgs.name = "tempImage_" + p.name;
|
||||||
|
} else {
|
||||||
|
dArgs.name = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!File.Exists("extra/images/" + dArgs.name + ".bmp")) {
|
||||||
|
Player.Message(p, "The URL entered was invalid!"); return;
|
||||||
|
}
|
||||||
Player.Message(p, "Place two blocks to determine direction.");
|
Player.Message(p, "Place two blocks to determine direction.");
|
||||||
p.MakeSelection(2, dArgs, DoImage);
|
p.MakeSelection(2, dArgs, DoImage);
|
||||||
}
|
}
|
||||||
@ -123,30 +115,20 @@ namespace MCGalaxy.Commands.Building {
|
|||||||
}
|
}
|
||||||
|
|
||||||
op.SetLevel(p.level);
|
op.SetLevel(p.level);
|
||||||
op.Player = p;
|
op.Player = p; op.Source = bmp;
|
||||||
op.Source = bmp;
|
op.LayerMode = dArgs.layer; op.DualLayer = dArgs.dualLayered;
|
||||||
op.Layer = dArgs.layer;
|
op.Palette = dArgs.palette; op.Filename = dArgs.name;
|
||||||
op.Mode = dArgs.popType;
|
|
||||||
op.Filename = dArgs.name;
|
|
||||||
|
|
||||||
if (op.Layer) {
|
|
||||||
if (op.Mode == 1) op.Mode = 2;
|
|
||||||
if (op.Mode == 3) op.Mode = 4;
|
|
||||||
}
|
|
||||||
DrawOpPerformer.Do(op, null, p, m, false);
|
DrawOpPerformer.Do(op, null, p, m, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Help(Player p) {
|
public override void Help(Player p) {
|
||||||
Player.Message(p, "/imageprint <switch> <localfile> - Print local file in extra/images/ folder. Must be type .bmp, type filename without extension.");
|
Player.Message(p, "%T/imageprint [file] [palette] <mode> %H- Prints image in extra/images/ folder. (File must have .bmp extension)");
|
||||||
Player.Message(p, "/imageprint <switch> <imgurfile.extension> - Print IMGUR stored file. Example: /i piCCm.gif will print www.imgur.com/piCCm.gif. Case-sensitive");
|
Player.Message(p, "%T/imageprint [url] [palette] <mode> %H- Downloads then prints the given image. (transparency supported)");
|
||||||
Player.Message(p, "/imageprint <switch> <webfile> - Print web file in format domain.com/folder/image.jpg. Does not need http:// or www.");
|
Player.Message(p, "%HPalettes: &f{0}", ImagePalette.Palettes.Join(pal => pal.Name));
|
||||||
Player.Message(p, "Available switches: (&f1%S) 2-Layer Color image, (&f2%S) 1-Layer Color Image, " +
|
Player.Message(p, "%HModes: &fVertical, Vertical2Layer, Horizontal");
|
||||||
"(&f3%S) 2-Layer Grayscale, (&f4%S) 1-Layer Grayscale, (%f5%S) Black and White, (&f6%S) Mathematical Grayscale");
|
|
||||||
Player.Message(p, "Local filetypes: .bmp. Remote Filetypes: .gif .png .jpg .bmp. PNG and GIF may use transparency");
|
|
||||||
Player.Message(p, "Use switch (&flayer%S) or (&fl%S) to print horizontally.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DrawArgs { public bool layer; public byte popType; public string name; }
|
struct DrawArgs { public bool layer, dualLayered; public ImagePalette palette; public string name; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,68 +20,70 @@ using System.Drawing;
|
|||||||
|
|
||||||
namespace MCGalaxy.Drawing {
|
namespace MCGalaxy.Drawing {
|
||||||
|
|
||||||
public interface IPalette {
|
public interface IPaletteMatcher {
|
||||||
|
|
||||||
/// <summary> Sets the blocks available for this palette to pick from. </summary>
|
/// <summary> Sets the palette of blocks used to match colours from. </summary>
|
||||||
void SetAvailableBlocks(PaletteEntry[] blocks);
|
void SetPalette(ImagePalette palette);
|
||||||
|
|
||||||
/// <summary> Returns the best matching block for the given color,
|
/// <summary> Returns the best matching block for the given color,
|
||||||
/// based on this palette's colourspace. </summary>
|
/// based on this palette's colourspace. </summary>
|
||||||
byte BestMatch(byte R, byte G, byte B, out int position);
|
byte BestMatch(byte R, byte G, byte B);
|
||||||
|
|
||||||
|
/// <summary> Returns the best matching block for the given color,
|
||||||
|
/// based on this palette's colourspace. </summary>
|
||||||
|
byte BestMatch(byte R, byte G, byte B, out bool backLayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class GrayscalePalette : IPalette {
|
public sealed class RgbPaletteMatcher : IPaletteMatcher {
|
||||||
|
|
||||||
public void SetAvailableBlocks(PaletteEntry[] blocks) { }
|
ImagePalette palette;
|
||||||
|
public void SetPalette(ImagePalette palette) {
|
||||||
public byte BestMatch(byte R, byte G, byte B, out int position) {
|
this.palette = palette;
|
||||||
int brightness = (R + G + B) / 3; position = -1;
|
|
||||||
if (brightness < (256 / 4))
|
|
||||||
return Block.obsidian;
|
|
||||||
else if (brightness >= (256 / 4) && brightness < (256 / 4) * 2)
|
|
||||||
return Block.darkgrey;
|
|
||||||
else if (brightness >= (256 / 4) * 2 && brightness < (256 / 4) * 3)
|
|
||||||
return Block.lightgrey;
|
|
||||||
else
|
|
||||||
return Block.white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class RgbPalette : IPalette {
|
|
||||||
|
|
||||||
PaletteEntry[] palette;
|
|
||||||
public void SetAvailableBlocks(PaletteEntry[] blocks) {
|
|
||||||
this.palette = blocks;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte BestMatch(byte R, byte G, byte B, out int position) {
|
public byte BestMatch(byte R, byte G, byte B) {
|
||||||
int minimum = int.MaxValue; position = 0;
|
int pos;
|
||||||
for (int i = 0; i < palette.Length; i++) {
|
MinDist(R, G, B, palette.FrontLayer, out pos);
|
||||||
PaletteEntry pixel = palette[i];
|
return palette.FrontLayer[pos].Block;
|
||||||
int dist = (R - pixel.R) * (R - pixel.R)
|
}
|
||||||
+ (G - pixel.G) * (G - pixel.G)
|
|
||||||
+ (B - pixel.B) * (B - pixel.B);
|
public byte BestMatch(byte R, byte G, byte B, out bool backLayer) {
|
||||||
|
int frontPos, backPos;
|
||||||
|
int frontDist = MinDist(R, G, B, palette.FrontLayer, out frontPos);
|
||||||
|
int backDist = MinDist(R, G, B, palette.BackLayer, out backPos);
|
||||||
|
|
||||||
|
backLayer = backDist <= frontDist;
|
||||||
|
return backLayer ? palette.BackLayer[backPos].Block : palette.FrontLayer[frontPos].Block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int MinDist(byte R, byte G, byte B, PaletteEntry[] entries, out int pos) {
|
||||||
|
int minDist = int.MaxValue; pos = 0;
|
||||||
|
for (int i = 0; i < entries.Length; i++) {
|
||||||
|
PaletteEntry entry = entries[i];
|
||||||
|
|
||||||
if (dist < minimum) {
|
int dist = (R - entry.R) * (R - entry.R)
|
||||||
minimum = dist; position = i;
|
+ (G - entry.G) * (G - entry.G)
|
||||||
}
|
+ (B - entry.B) * (B - entry.B);
|
||||||
|
|
||||||
|
if (dist < minDist) { minDist = dist; pos = i; }
|
||||||
}
|
}
|
||||||
return palette[position].Block;
|
return minDist;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class LabPalette : IPalette {
|
public sealed class LabPaletteMatcher : IPaletteMatcher {
|
||||||
|
|
||||||
LabColor[] palette;
|
LabColor[] palette;
|
||||||
public void SetAvailableBlocks(PaletteEntry[] blocks) {
|
public void SetPalette(ImagePalette palette) {
|
||||||
palette = new LabColor[blocks.Length];
|
this.palette = new LabColor[palette.FrontLayer.Length];
|
||||||
for (int i = 0; i < palette.Length; i++)
|
for (int i = 0; i < palette.FrontLayer.Length; i++)
|
||||||
palette[i] = RgbToLab(blocks[i]);
|
this.palette[i] = RgbToLab(palette.FrontLayer[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte BestMatch(byte r, byte g, byte b, out int position) {
|
public byte BestMatch(byte R, byte G, byte B) {
|
||||||
double minimum = int.MaxValue; position = 0;
|
double minDist = int.MaxValue; int pos = 0;
|
||||||
LabColor col = RgbToLab(r, g, b);
|
LabColor col = RgbToLab(R, G, B);
|
||||||
|
|
||||||
for (int i = 0; i < palette.Length; i++) {
|
for (int i = 0; i < palette.Length; i++) {
|
||||||
LabColor pixel = palette[i];
|
LabColor pixel = palette[i];
|
||||||
@ -90,13 +92,17 @@ namespace MCGalaxy.Drawing {
|
|||||||
+ (col.A - pixel.A) * (col.A - pixel.A)
|
+ (col.A - pixel.A) * (col.A - pixel.A)
|
||||||
+ (col.B - pixel.B) * (col.B - pixel.B);
|
+ (col.B - pixel.B) * (col.B - pixel.B);
|
||||||
|
|
||||||
if (dist < minimum) {
|
if (dist < minDist) { minDist = dist; pos = i; }
|
||||||
minimum = dist; position = i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return palette[position].Block;
|
return palette[pos].Block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte BestMatch(byte R, byte G, byte B, out bool backLayer) {
|
||||||
|
backLayer = false;
|
||||||
|
return BestMatch(R, G, B, out backLayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct LabColor {
|
struct LabColor {
|
||||||
public double L, A, B;
|
public double L, A, B;
|
||||||
public byte Block;
|
public byte Block;
|
@ -1,146 +1,146 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2011 MCForge
|
Copyright 2011 MCForge
|
||||||
|
|
||||||
Dual-licensed under the Educational Community License, Version 2.0 and
|
Dual-licensed under the Educational Community License, Version 2.0 and
|
||||||
the GNU General Public License, Version 3 (the "Licenses"); you may
|
the GNU General Public License, Version 3 (the "Licenses"); you may
|
||||||
not use this file except in compliance with the Licenses. You may
|
not use this file except in compliance with the Licenses. You may
|
||||||
obtain a copy of the Licenses at
|
obtain a copy of the Licenses at
|
||||||
|
|
||||||
http://www.opensource.org/licenses/ecl2.php
|
http://www.opensource.org/licenses/ecl2.php
|
||||||
http://www.gnu.org/licenses/gpl-3.0.html
|
http://www.gnu.org/licenses/gpl-3.0.html
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing,
|
Unless required by applicable law or agreed to in writing,
|
||||||
software distributed under the Licenses are distributed on an "AS IS"
|
software distributed under the Licenses are distributed on an "AS IS"
|
||||||
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||||
or implied. See the Licenses for the specific language governing
|
or implied. See the Licenses for the specific language governing
|
||||||
permissions and limitations under the Licenses.
|
permissions and limitations under the Licenses.
|
||||||
*/
|
*/
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace MCGalaxy.Drawing {
|
namespace MCGalaxy.Drawing {
|
||||||
|
|
||||||
internal static class ImagePalette {
|
/// <summary> Represents a mapping of block ids to RGB colours. </summary>
|
||||||
|
public sealed class ImagePalette {
|
||||||
internal static string[] Names = {
|
|
||||||
null, "2-layer color", "1-layer color", "2-layer grayscale",
|
/// <summary> The name of this palette. </summary>
|
||||||
"1-layer grayscale", "Black and White", "Mathematical grayscale"
|
public string Name;
|
||||||
};
|
|
||||||
public static PaletteEntry[] GetPalette(int type) {
|
/// <summary> Blocks in the front, used in vertical and layer mode. </summary>
|
||||||
if (type == 1) return Color_2;
|
public PaletteEntry[] FrontLayer;
|
||||||
if (type == 2) return Color_1;
|
|
||||||
if (type == 3) return Grayscale_2;
|
/// <summary> Blocks in the back, used only in two-layer vertical mode. </summary>
|
||||||
if (type == 4) return Grayscale_1;
|
public PaletteEntry[] BackLayer;
|
||||||
if (type == 5) return BlackWhite_1;
|
|
||||||
return null;
|
public ImagePalette(string name, PaletteEntry[] front, PaletteEntry[] back) {
|
||||||
}
|
Name = name; FrontLayer = front; BackLayer = back;
|
||||||
|
}
|
||||||
internal static PaletteEntry[] Color_2 = {
|
|
||||||
// front layer
|
|
||||||
new PaletteEntry(128, 86, 57, Block.dirt),
|
/// <summary> All supported palettes. </summary>
|
||||||
new PaletteEntry(162, 129, 75, Block.wood),
|
public static List<ImagePalette> Palettes = new List<ImagePalette>();
|
||||||
new PaletteEntry(244, 237, 174, Block.sand),
|
|
||||||
new PaletteEntry(226, 31, 38, Block.red),
|
public static ImagePalette Find(string name) {
|
||||||
new PaletteEntry(223, 135, 37, Block.orange),
|
foreach (ImagePalette entry in Palettes) {
|
||||||
new PaletteEntry(230, 241, 25, Block.yellow),
|
if (entry.Name.CaselessEq(name)) return entry;
|
||||||
new PaletteEntry(127, 234, 26, Block.lightgreen),
|
}
|
||||||
new PaletteEntry(25, 234, 20, Block.green),
|
return null;
|
||||||
new PaletteEntry(31, 234, 122, Block.aquagreen),
|
}
|
||||||
new PaletteEntry(27, 239, 225, Block.cyan),
|
|
||||||
new PaletteEntry(99, 166, 226, Block.lightblue),
|
public static void Load() {
|
||||||
new PaletteEntry(111, 124, 235, Block.blue),
|
Palettes.Clear();
|
||||||
new PaletteEntry(126, 34, 218, Block.purple),
|
Palettes.Add(new ImagePalette("Color", Color_Front, Color_Back));
|
||||||
new PaletteEntry(170, 71, 219, Block.lightpurple),
|
Palettes.Add(new ImagePalette("Grayscale", Grayscale_Front, Grayscale_Back));
|
||||||
new PaletteEntry(227, 39, 225, Block.pink),
|
Palettes.Add(new ImagePalette("BlackWhite", BlackWhite_Front, null));
|
||||||
new PaletteEntry(234, 39, 121, Block.darkpink),
|
Palettes.Add(new ImagePalette("SimpleGrayscale", Grayscale_Mathematical, null));
|
||||||
new PaletteEntry(46, 68, 47, Block.darkgrey),
|
}
|
||||||
new PaletteEntry(135, 145, 130, Block.lightgrey),
|
|
||||||
new PaletteEntry(230, 240, 225, Block.white),
|
|
||||||
new PaletteEntry(163, 163, 163, Block.staircasefull),
|
static PaletteEntry[] Color_Front = {
|
||||||
/*Turns out the back layer blocks are handled awfully.
|
new PaletteEntry(128, 86, 57, Block.dirt),
|
||||||
new PaletteEntry(217, 131, 155, 55),
|
new PaletteEntry(162, 129, 75, Block.wood),
|
||||||
new PaletteEntry(56, 77, 24, 56),
|
new PaletteEntry(244, 237, 174, Block.sand),
|
||||||
new PaletteEntry(86, 51, 28, 57),
|
new PaletteEntry(226, 31, 38, Block.red),
|
||||||
new PaletteEntry(39, 51, 154, 58),
|
new PaletteEntry(223, 135, 37, Block.orange),
|
||||||
new PaletteEntry(39, 117, 149, 59),*/
|
new PaletteEntry(230, 241, 25, Block.yellow),
|
||||||
|
new PaletteEntry(127, 234, 26, Block.lightgreen),
|
||||||
// back layer
|
new PaletteEntry(25, 234, 20, Block.green),
|
||||||
new PaletteEntry(57, 38, 25, Block.dirt),
|
new PaletteEntry(31, 234, 122, Block.aquagreen),
|
||||||
new PaletteEntry(72, 57, 33, Block.wood),
|
new PaletteEntry(27, 239, 225, Block.cyan),
|
||||||
new PaletteEntry(109, 105, 77, Block.sand),
|
new PaletteEntry(99, 166, 226, Block.lightblue),
|
||||||
new PaletteEntry(41, 31, 16, Block.trunk),
|
new PaletteEntry(111, 124, 235, Block.blue),
|
||||||
new PaletteEntry(101, 13, 16, Block.red),
|
new PaletteEntry(126, 34, 218, Block.purple),
|
||||||
new PaletteEntry(99, 60, 16, Block.orange),
|
new PaletteEntry(170, 71, 219, Block.lightpurple),
|
||||||
new PaletteEntry(102, 107, 11, Block.yellow),
|
new PaletteEntry(227, 39, 225, Block.pink),
|
||||||
new PaletteEntry(56, 104, 11, Block.lightgreen),
|
new PaletteEntry(234, 39, 121, Block.darkpink),
|
||||||
new PaletteEntry(11, 104, 8, Block.green),
|
new PaletteEntry(46, 68, 47, Block.darkgrey),
|
||||||
new PaletteEntry(13, 104, 54, Block.aquagreen),
|
new PaletteEntry(135, 145, 130, Block.lightgrey),
|
||||||
new PaletteEntry(12, 106, 100, Block.cyan),
|
new PaletteEntry(230, 240, 225, Block.white),
|
||||||
new PaletteEntry(44, 74, 101, Block.lightblue),
|
new PaletteEntry(163, 163, 163, Block.staircasefull),
|
||||||
new PaletteEntry(49, 55, 105, Block.blue),
|
new PaletteEntry(0, 0, 0, Block.obsidian),
|
||||||
new PaletteEntry(56, 15, 97, Block.purple),
|
};
|
||||||
new PaletteEntry(75, 31, 97, Block.lightpurple),
|
/*Turns out the back layer blocks are handled awfully.
|
||||||
new PaletteEntry(101, 17, 100, Block.pink),
|
new PaletteEntry(217, 131, 155, 55),
|
||||||
new PaletteEntry(104, 17, 54, Block.darkpink),
|
new PaletteEntry(56, 77, 24, 56),
|
||||||
new PaletteEntry(20, 30, 21, Block.darkgrey),
|
new PaletteEntry(86, 51, 28, 57),
|
||||||
new PaletteEntry(60, 64, 58, Block.lightgrey),
|
new PaletteEntry(39, 51, 154, 58),
|
||||||
new PaletteEntry(102, 107, 100, Block.white),
|
new PaletteEntry(39, 117, 149, 59),*/
|
||||||
new PaletteEntry(0, 0, 0, Block.obsidian),
|
|
||||||
};
|
static PaletteEntry[] Color_Back = {
|
||||||
|
new PaletteEntry(57, 38, 25, Block.dirt),
|
||||||
internal static PaletteEntry[] Color_1 = {
|
new PaletteEntry(72, 57, 33, Block.wood),
|
||||||
new PaletteEntry(128, 86, 57, Block.dirt),
|
new PaletteEntry(109, 105, 77, Block.sand),
|
||||||
new PaletteEntry(162, 129, 75, Block.wood),
|
new PaletteEntry(41, 31, 16, Block.trunk),
|
||||||
new PaletteEntry(244, 237, 174, Block.sand),
|
new PaletteEntry(101, 13, 16, Block.red),
|
||||||
new PaletteEntry(93, 70, 38, Block.trunk),
|
new PaletteEntry(99, 60, 16, Block.orange),
|
||||||
new PaletteEntry(226, 31, 38, Block.red),
|
new PaletteEntry(102, 107, 11, Block.yellow),
|
||||||
new PaletteEntry(223, 135, 37, Block.orange),
|
new PaletteEntry(56, 104, 11, Block.lightgreen),
|
||||||
new PaletteEntry(230, 241, 25, Block.yellow),
|
new PaletteEntry(11, 104, 8, Block.green),
|
||||||
new PaletteEntry(127, 234, 26, Block.lightgreen),
|
new PaletteEntry(13, 104, 54, Block.aquagreen),
|
||||||
new PaletteEntry(25, 234, 20, Block.green),
|
new PaletteEntry(12, 106, 100, Block.cyan),
|
||||||
new PaletteEntry(31, 234, 122, Block.aquagreen),
|
new PaletteEntry(44, 74, 101, Block.lightblue),
|
||||||
new PaletteEntry(27, 239, 225, Block.cyan),
|
new PaletteEntry(49, 55, 105, Block.blue),
|
||||||
new PaletteEntry(99, 166, 226, Block.lightblue),
|
new PaletteEntry(56, 15, 97, Block.purple),
|
||||||
new PaletteEntry(111, 124, 235, Block.blue),
|
new PaletteEntry(75, 31, 97, Block.lightpurple),
|
||||||
new PaletteEntry(126, 34, 218, Block.purple),
|
new PaletteEntry(101, 17, 100, Block.pink),
|
||||||
new PaletteEntry(170, 71, 219, Block.lightpurple),
|
new PaletteEntry(104, 17, 54, Block.darkpink),
|
||||||
new PaletteEntry(227, 39, 225, Block.pink),
|
new PaletteEntry(20, 30, 21, Block.darkgrey),
|
||||||
new PaletteEntry(234, 39, 121, Block.darkpink),
|
new PaletteEntry(60, 64, 58, Block.lightgrey),
|
||||||
new PaletteEntry(46, 68, 47, Block.darkgrey),
|
new PaletteEntry(102, 107, 100, Block.white),
|
||||||
new PaletteEntry(135, 145, 130, Block.lightgrey),
|
new PaletteEntry(0, 0, 0, Block.obsidian),
|
||||||
new PaletteEntry(230, 240, 225, Block.white),
|
};
|
||||||
new PaletteEntry(0, 0, 0, Block.obsidian),
|
|
||||||
};
|
static PaletteEntry[] Grayscale_Front = {
|
||||||
|
new PaletteEntry(0, 0, 0, Block.obsidian),
|
||||||
internal static PaletteEntry[] Grayscale_2 = {
|
new PaletteEntry(46, 68, 47, Block.darkgrey),
|
||||||
// front layer
|
new PaletteEntry(135, 145, 130, Block.lightgrey),
|
||||||
new PaletteEntry(46, 68, 47, Block.darkgrey),
|
new PaletteEntry(230, 240, 225, Block.white),
|
||||||
new PaletteEntry(135, 145, 130, Block.lightgrey),
|
};
|
||||||
new PaletteEntry(230, 240, 225, Block.white),
|
|
||||||
// back layer
|
static PaletteEntry[] Grayscale_Back = {
|
||||||
new PaletteEntry(20, 30, 21, Block.darkgrey),
|
new PaletteEntry(0, 0, 0, Block.obsidian),
|
||||||
new PaletteEntry(60, 64, 58, Block.lightgrey),
|
new PaletteEntry(20, 30, 21, Block.darkgrey),
|
||||||
new PaletteEntry(102, 107, 100, Block.white),
|
new PaletteEntry(60, 64, 58, Block.lightgrey),
|
||||||
new PaletteEntry(0, 0, 0, Block.obsidian),
|
new PaletteEntry(102, 107, 100, Block.white),
|
||||||
};
|
};
|
||||||
|
|
||||||
internal static PaletteEntry[] Grayscale_1 = {
|
static PaletteEntry[] Grayscale_Mathematical = {
|
||||||
new PaletteEntry(46, 68, 47, Block.darkgrey),
|
new PaletteEntry(32, 32, 32, Block.obsidian),
|
||||||
new PaletteEntry(135, 145, 130, Block.lightgrey),
|
new PaletteEntry(96, 96, 96, Block.darkgrey),
|
||||||
new PaletteEntry(230, 240, 225, Block.white),
|
new PaletteEntry(160, 160, 160, Block.lightgrey),
|
||||||
new PaletteEntry(0, 0, 0, Block.obsidian),
|
new PaletteEntry(224, 224, 224, Block.white),
|
||||||
};
|
};
|
||||||
|
|
||||||
internal static PaletteEntry[] BlackWhite_1 = {
|
static PaletteEntry[] BlackWhite_Front = {
|
||||||
new PaletteEntry(255, 255, 255, Block.white),
|
new PaletteEntry(255, 255, 255, Block.white),
|
||||||
new PaletteEntry(0, 0, 0, Block.obsidian),
|
new PaletteEntry(0, 0, 0, Block.obsidian),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct PaletteEntry {
|
public struct PaletteEntry {
|
||||||
public byte R, G, B, Block;
|
public byte R, G, B, Block;
|
||||||
|
|
||||||
public PaletteEntry(byte r, byte g, byte b, byte block) {
|
public PaletteEntry(byte r, byte g, byte b, byte block) {
|
||||||
R = r; G = g; B = b; Block = block;
|
R = r; G = g; B = b; Block = block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,23 +31,20 @@ namespace MCGalaxy.Drawing.Ops {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal Draw.Bitmap Source;
|
internal Draw.Bitmap Source;
|
||||||
internal int Mode, Direction;
|
internal int Direction;
|
||||||
internal bool Layer;
|
internal bool DualLayer, LayerMode;
|
||||||
internal string Filename;
|
internal string Filename;
|
||||||
|
public ImagePalette Palette;
|
||||||
|
|
||||||
Vec3S32 dx, dy, adj;
|
Vec3S32 dx, dy, adj;
|
||||||
IPalette selector;
|
IPaletteMatcher selector;
|
||||||
int threshold;
|
|
||||||
|
|
||||||
public override void Perform(Vec3S32[] marks, Brush brush, Action<DrawOpBlock> output) {
|
public override void Perform(Vec3S32[] marks, Brush brush, Action<DrawOpBlock> output) {
|
||||||
selector = null;
|
selector = null;
|
||||||
CalcThreshold();
|
CalcState(Direction);
|
||||||
CalcDirectionVectors(Direction);
|
|
||||||
|
|
||||||
PaletteEntry[] palette = ImagePalette.GetPalette(Mode);
|
selector = new RgbPaletteMatcher();
|
||||||
if (Mode == 6) selector = new GrayscalePalette();
|
selector.SetPalette(Palette);
|
||||||
else selector = new RgbPalette();
|
|
||||||
selector.SetAvailableBlocks(palette);
|
|
||||||
|
|
||||||
using (PixelGetter getter = new PixelGetter(Source)) {
|
using (PixelGetter getter = new PixelGetter(Source)) {
|
||||||
getter.Init();
|
getter.Init();
|
||||||
@ -58,7 +55,7 @@ namespace MCGalaxy.Drawing.Ops {
|
|||||||
Source = null;
|
Source = null;
|
||||||
if (Filename == "tempImage_" + Player.name)
|
if (Filename == "tempImage_" + Player.name)
|
||||||
File.Delete("extra/images/tempImage_" + Player.name + ".bmp");
|
File.Delete("extra/images/tempImage_" + Player.name + ".bmp");
|
||||||
Player.Message(Player, "Finished printing image using " + ImagePalette.Names[Mode]);
|
Player.Message(Player, "Finished printing image using {0} palette.", Palette.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutputPixel(Pixel P, Action<DrawOpBlock> output) {
|
void OutputPixel(Pixel P, Action<DrawOpBlock> output) {
|
||||||
@ -67,25 +64,23 @@ namespace MCGalaxy.Drawing.Ops {
|
|||||||
ushort z = (ushort)(Origin.Z + dx.Z * P.X + dy.Z * P.Y);
|
ushort z = (ushort)(Origin.Z + dx.Z * P.X + dy.Z * P.Y);
|
||||||
if (P.A < 20) { output(Place(x, y, z, Block.air, 0)); return; }
|
if (P.A < 20) { output(Place(x, y, z, Block.air, 0)); return; }
|
||||||
|
|
||||||
int position;
|
if (!DualLayer) {
|
||||||
byte block = selector.BestMatch(P.R, P.G, P.B, out position);
|
byte block = selector.BestMatch(P.R, P.G, P.B);
|
||||||
// Back layer block
|
output(Place(x, y, z, block, 0));
|
||||||
if (position <= threshold) {
|
} else {
|
||||||
x = (ushort)(x + adj.X);
|
bool backLayer;
|
||||||
z = (ushort)(z + adj.Z);
|
byte block = selector.BestMatch(P.R, P.G, P.B, out backLayer);
|
||||||
}
|
if (backLayer) {
|
||||||
output(Place(x, y, z, block, 0));
|
x = (ushort)(x + adj.X);
|
||||||
}
|
z = (ushort)(z + adj.Z);
|
||||||
|
}
|
||||||
void CalcThreshold() {
|
output(Place(x, y, z, block, 0));
|
||||||
threshold = -1;
|
|
||||||
if (Mode == 1 || Mode == 3) {
|
|
||||||
threshold = Mode == 1 ? 20 : 3;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CalcDirectionVectors(int dir) {
|
void CalcState(int dir) {
|
||||||
dx = default(Vec3S32); dy = default(Vec3S32); adj = default(Vec3S32);
|
dx = default(Vec3S32); dy = default(Vec3S32); adj = default(Vec3S32);
|
||||||
|
DualLayer = DualLayer && !LayerMode && Palette.BackLayer != null;
|
||||||
|
|
||||||
// Calculate back layer offset
|
// Calculate back layer offset
|
||||||
if (dir == 0) adj.Z = 1;
|
if (dir == 0) adj.Z = 1;
|
||||||
@ -93,7 +88,7 @@ namespace MCGalaxy.Drawing.Ops {
|
|||||||
if (dir == 2) adj.X = -1;
|
if (dir == 2) adj.X = -1;
|
||||||
if (dir == 3) adj.X = 1;
|
if (dir == 3) adj.X = 1;
|
||||||
|
|
||||||
if (Layer) {
|
if (LayerMode) {
|
||||||
if (dir == 0) { dx.X = 1; dy.Z = -1; }
|
if (dir == 0) { dx.X = 1; dy.Z = -1; }
|
||||||
if (dir == 1) { dx.X = -1; dy.Z = 1; }
|
if (dir == 1) { dx.X = -1; dy.Z = 1; }
|
||||||
if (dir == 2) { dx.Z = 1; dy.X = 1; }
|
if (dir == 2) { dx.Z = 1; dy.X = 1; }
|
||||||
|
@ -445,7 +445,7 @@
|
|||||||
<Compile Include="Drawing\Flip.cs" />
|
<Compile Include="Drawing\Flip.cs" />
|
||||||
<Compile Include="Drawing\Image\ImagePalette.cs" />
|
<Compile Include="Drawing\Image\ImagePalette.cs" />
|
||||||
<Compile Include="Drawing\Image\ImagePrintDrawOp.cs" />
|
<Compile Include="Drawing\Image\ImagePrintDrawOp.cs" />
|
||||||
<Compile Include="Drawing\Image\IPalette.cs" />
|
<Compile Include="Drawing\Image\IPaletteMatcher.cs" />
|
||||||
<Compile Include="Drawing\Image\PixelGetter.cs" />
|
<Compile Include="Drawing\Image\PixelGetter.cs" />
|
||||||
<Compile Include="Drawing\TransformFactories\RotateTransform.cs" />
|
<Compile Include="Drawing\TransformFactories\RotateTransform.cs" />
|
||||||
<Compile Include="Drawing\TransformFactories\SimpleTransforms.cs" />
|
<Compile Include="Drawing\TransformFactories\SimpleTransforms.cs" />
|
||||||
|
@ -21,6 +21,7 @@ using System.Net;
|
|||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using MCGalaxy.Blocks;
|
using MCGalaxy.Blocks;
|
||||||
using MCGalaxy.Commands.World;
|
using MCGalaxy.Commands.World;
|
||||||
|
using MCGalaxy.Drawing;
|
||||||
using MCGalaxy.Games;
|
using MCGalaxy.Games;
|
||||||
using MCGalaxy.Tasks;
|
using MCGalaxy.Tasks;
|
||||||
using MCGalaxy.Util;
|
using MCGalaxy.Util;
|
||||||
@ -171,6 +172,7 @@ namespace MCGalaxy {
|
|||||||
Alias.Load();
|
Alias.Load();
|
||||||
Bots.BotsFile.Load();
|
Bots.BotsFile.Load();
|
||||||
BlockDefinition.LoadGlobal();
|
BlockDefinition.LoadGlobal();
|
||||||
|
ImagePalette.Load();
|
||||||
|
|
||||||
SrvProperties.Load("properties/server.properties");
|
SrvProperties.Load("properties/server.properties");
|
||||||
Updater.Load("properties/update.properties");
|
Updater.Load("properties/update.properties");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user