diff --git a/core/src/main/java/com/boydti/fawe/util/MainUtil.java b/core/src/main/java/com/boydti/fawe/util/MainUtil.java index d955036f..8046c221 100644 --- a/core/src/main/java/com/boydti/fawe/util/MainUtil.java +++ b/core/src/main/java/com/boydti/fawe/util/MainUtil.java @@ -31,6 +31,7 @@ import java.util.Map.Entry; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Consumer; import java.util.regex.Pattern; import java.util.zip.*; import javax.imageio.ImageIO; @@ -885,7 +886,7 @@ public class MainUtil { return isInSubDirectory(dir, file.getParentFile()); } - public static void iterateFiles(File directory, RunnableVal task) { + public static void iterateFiles(File directory, Consumer task) { if (directory.exists()) { File[] files = directory.listFiles(); if (null != files) { @@ -893,7 +894,7 @@ public class MainUtil { if (files[i].isDirectory()) { iterateFiles(files[i], task); } else { - task.run(files[i]); + task.accept(files[i]); } } } diff --git a/core/src/main/java/com/boydti/fawe/util/image/ImageUtil.java b/core/src/main/java/com/boydti/fawe/util/image/ImageUtil.java index 98e77597..c903cc3a 100644 --- a/core/src/main/java/com/boydti/fawe/util/image/ImageUtil.java +++ b/core/src/main/java/com/boydti/fawe/util/image/ImageUtil.java @@ -37,14 +37,14 @@ public class ImageUtil { } int type = (img.getTransparency() == Transparency.OPAQUE) ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB; - BufferedImage ret = (BufferedImage)img; + BufferedImage ret = img; int w, h; if (higherQuality) { // Use multi-step technique: start with original size, then // scale down in multiple passes with drawImage() // until the target size is reached - w = img.getWidth(); - h = img.getHeight(); + w = ret.getWidth(); + h = ret.getHeight(); } else { // Use one-step technique: scale directly from original // size to target size with a single drawImage() call @@ -58,14 +58,14 @@ public class ImageUtil { if (w < targetWidth) { w = targetWidth; } - } + } else if (w < targetWidth) w = targetWidth; if (higherQuality && h > targetHeight) { h /= 2; if (h < targetHeight) { h = targetHeight; } - } + } else if (h < targetHeight) h = targetHeight; BufferedImage tmp = new BufferedImage(w, h, type); Graphics2D g2 = tmp.createGraphics(); diff --git a/core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java b/core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java index d8178037..7e919053 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java @@ -35,6 +35,7 @@ import com.boydti.fawe.util.StringMan; import com.boydti.fawe.util.chat.Message; import com.boydti.fawe.util.chat.UsageMessage; import com.boydti.fawe.util.gui.FormBuilder; +import com.boydti.fawe.util.image.ImageUtil; import com.sk89q.minecraft.util.commands.*; import com.sk89q.worldedit.*; import com.sk89q.worldedit.Vector; @@ -70,11 +71,18 @@ import com.sk89q.worldedit.util.command.binding.Text; import com.sk89q.worldedit.util.command.parametric.Optional; import com.sk89q.worldedit.util.command.parametric.ParameterData; import com.sk89q.worldedit.world.World; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; import java.io.File; import java.io.FileFilter; +import java.io.IOException; import java.lang.reflect.Type; import java.net.URI; +import java.nio.file.Files; import java.util.*; +import java.util.List; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; @@ -157,6 +165,70 @@ public class UtilityCommands extends MethodCommands { } } + @Command( + aliases = {"/heightmapinterface"}, + desc = "Generate the heightmap interface: https://github.com/boy0001/HeightMap", + max = 0 + ) + public void heightmapInterface(FawePlayer player) throws IOException { + player.sendMessage("Please wait while we generate the minified heightmaps."); + File srcFolder = MainUtil.getFile(Fawe.imp().getDirectory(), Settings.IMP.PATHS.HEIGHTMAP); + + int min = 100; + int max = 200; + + File webSrc = new File(Fawe.imp().getDirectory(), "web" + File.separator + "heightmap"); + File minImages = new File(webSrc, "images" + File.separator + "min"); + File maxImages = new File(webSrc, "images" + File.separator + "max"); + final int sub = srcFolder.getAbsolutePath().length(); + List images = new ArrayList<>(); + MainUtil.iterateFiles(srcFolder, new Consumer() { + @Override + public void accept(File file) { + switch (file.getName().substring(file.getName().lastIndexOf('.')).toLowerCase()) { + case ".png": + case ".jpeg": + break; + default: + return; + } + try { + String name = file.getAbsolutePath().substring(sub); + if (name.startsWith(File.separator)) name = name.replaceFirst(java.util.regex.Pattern.quote(File.separator), ""); + BufferedImage img = MainUtil.readImage(file); + BufferedImage minImg = ImageUtil.getScaledInstance(img, min, min, RenderingHints.VALUE_INTERPOLATION_BILINEAR, true); + BufferedImage maxImg = ImageUtil.getScaledInstance(img, max, max, RenderingHints.VALUE_INTERPOLATION_BILINEAR, true); + player.sendMessage("Writing " + name); + File minFile = new File(minImages, name); + File maxFile = new File(maxImages, name); + minFile.getParentFile().mkdirs(); + maxFile.getParentFile().mkdirs(); + ImageIO.write(minImg, "png", minFile); + ImageIO.write(maxImg, "png", maxFile); + images.add(name); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + }); + StringBuilder config = new StringBuilder(); + config.append("var images = [\n"); + for (String image : images) { + config.append('"' + image.replace(File.separator, "/") + "\",\n"); + } + config.append("];\n"); + config.append("// The low res images (they should all be the same size)\n"); + config.append("var src_min = \"images/min/\";\n"); + config.append("// The max resolution images (Use the same if there are no higher resolution ones available)\n"); + config.append("var src_max = \"images/max/\";\n"); + config.append("// The local source for the image (used in commands)\n"); + config.append("var src_local = \"file://\";\n"); + File configFile = new File(webSrc, "config.js"); + player.sendMessage("Writing " + configFile); + Files.write(configFile.toPath(), config.toString().getBytes()); + player.sendMessage("Done! See: `FastAsyncWorldEdit/web/heightmap`"); + } + @Command( aliases = {"/fill"}, usage = " [depth] [direction]",