mirror of
https://github.com/zDevelopers/ImageOnMap.git
synced 2024-09-29 06:57:29 +02:00
* NEW: Added stretch and cover image resizing modes
This commit is contained in:
parent
47fb9737cb
commit
4653008e5a
@ -21,6 +21,7 @@ package fr.moribus.imageonmap.commands.maptool;
|
|||||||
import fr.moribus.imageonmap.Permissions;
|
import fr.moribus.imageonmap.Permissions;
|
||||||
import fr.moribus.imageonmap.commands.IoMCommand;
|
import fr.moribus.imageonmap.commands.IoMCommand;
|
||||||
import fr.moribus.imageonmap.image.ImageRendererExecutor;
|
import fr.moribus.imageonmap.image.ImageRendererExecutor;
|
||||||
|
import fr.moribus.imageonmap.image.ImageUtils;
|
||||||
import fr.moribus.imageonmap.map.ImageMap;
|
import fr.moribus.imageonmap.map.ImageMap;
|
||||||
import fr.zcraft.zlib.components.commands.CommandException;
|
import fr.zcraft.zlib.components.commands.CommandException;
|
||||||
import fr.zcraft.zlib.components.commands.CommandInfo;
|
import fr.zcraft.zlib.components.commands.CommandInfo;
|
||||||
@ -40,7 +41,7 @@ public class NewCommand extends IoMCommand
|
|||||||
protected void run() throws CommandException
|
protected void run() throws CommandException
|
||||||
{
|
{
|
||||||
final Player player = playerSender();
|
final Player player = playerSender();
|
||||||
boolean scaling = false;
|
ImageUtils.ScalingType scaling = ImageUtils.ScalingType.NONE;
|
||||||
URL url;
|
URL url;
|
||||||
int width = 0, height = 0;
|
int width = 0, height = 0;
|
||||||
|
|
||||||
@ -58,17 +59,21 @@ public class NewCommand extends IoMCommand
|
|||||||
|
|
||||||
if(args.length >= 2)
|
if(args.length >= 2)
|
||||||
{
|
{
|
||||||
if(args[1].equals("resize")) {
|
|
||||||
scaling = true;
|
|
||||||
if(args.length >= 4) {
|
if(args.length >= 4) {
|
||||||
width = Integer.parseInt(args[2]);
|
width = Integer.parseInt(args[2]);
|
||||||
height = Integer.parseInt(args[3]);
|
height = Integer.parseInt(args[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch(args[1]) {
|
||||||
|
case "resize": scaling = ImageUtils.ScalingType.CONTAINED; break;
|
||||||
|
case "resize-stretched": scaling = ImageUtils.ScalingType.STRETCHED; break;
|
||||||
|
case "resize-covered": scaling = ImageUtils.ScalingType.COVERED; break;
|
||||||
|
default: throwInvalidArgument(I.t("Invalid Stretching mode.")); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
info(I.t("Rendering..."));
|
info(I.t("Rendering..."));
|
||||||
ImageRendererExecutor.Render(url, scaling, player.getUniqueId(), width, height, new WorkerCallback<ImageMap>()
|
ImageRendererExecutor.render(url, scaling, player.getUniqueId(), width, height, new WorkerCallback<ImageMap>()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void finished(ImageMap result)
|
public void finished(ImageMap result)
|
||||||
|
@ -27,7 +27,6 @@ import fr.zcraft.zlib.components.worker.WorkerCallback;
|
|||||||
import fr.zcraft.zlib.components.worker.WorkerRunnable;
|
import fr.zcraft.zlib.components.worker.WorkerRunnable;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@ -42,7 +41,7 @@ import java.util.concurrent.Future;
|
|||||||
@WorkerAttributes (name = "Image Renderer", queriesMainThread = true)
|
@WorkerAttributes (name = "Image Renderer", queriesMainThread = true)
|
||||||
public class ImageRendererExecutor extends Worker
|
public class ImageRendererExecutor extends Worker
|
||||||
{
|
{
|
||||||
static public void Render(final URL url, final boolean scaling, final UUID playerUUID, final int width, final int height, WorkerCallback<ImageMap> callback)
|
static public void render(final URL url, final ImageUtils.ScalingType scaling, final UUID playerUUID, final int width, final int height, WorkerCallback<ImageMap> callback)
|
||||||
{
|
{
|
||||||
submitQuery(new WorkerRunnable<ImageMap>()
|
submitQuery(new WorkerRunnable<ImageMap>()
|
||||||
{
|
{
|
||||||
@ -65,24 +64,20 @@ public class ImageRendererExecutor extends Worker
|
|||||||
|
|
||||||
if (image == null) throw new IOException(I.t("The given URL is not a valid image"));
|
if (image == null) throw new IOException(I.t("The given URL is not a valid image"));
|
||||||
|
|
||||||
if (scaling) return RenderScaled(image, playerUUID, width, height);
|
if(scaling != ImageUtils.ScalingType.NONE && height <= 1 && width <= 1) {
|
||||||
else return RenderPoster(image, playerUUID);
|
return renderSingle(scaling.resize(image, ImageMap.WIDTH, ImageMap.HEIGHT), playerUUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
final BufferedImage resizedImage = scaling.resize(image, ImageMap.WIDTH * width, ImageMap.HEIGHT * height);
|
||||||
|
return renderPoster(resizedImage, playerUUID);
|
||||||
}
|
}
|
||||||
}, callback);
|
}, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
static private ImageMap RenderScaled(final BufferedImage image, final UUID playerUUID, final int width, final int height) throws Throwable {
|
static private ImageMap renderSingle(final BufferedImage image, final UUID playerUUID) throws Throwable
|
||||||
if(height <= 1 && width <= 1) {
|
|
||||||
return RenderSingle(image, playerUUID);
|
|
||||||
}
|
|
||||||
final BufferedImage finalImage = ResizeImage(image, ImageMap.WIDTH * width, ImageMap.HEIGHT * height);
|
|
||||||
return RenderPoster(finalImage, playerUUID);
|
|
||||||
}
|
|
||||||
|
|
||||||
static private ImageMap RenderSingle(final BufferedImage image, final UUID playerUUID) throws Throwable
|
|
||||||
{
|
{
|
||||||
MapManager.checkMapLimit(1, playerUUID);
|
MapManager.checkMapLimit(1, playerUUID);
|
||||||
Future<Short> futureMapID = submitToMainThread(new Callable<Short>()
|
final Future<Short> futureMapID = submitToMainThread(new Callable<Short>()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public Short call() throws Exception
|
public Short call() throws Exception
|
||||||
@ -91,26 +86,23 @@ public class ImageRendererExecutor extends Worker
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
final BufferedImage finalImage = ResizeImage(image, ImageMap.WIDTH, ImageMap.HEIGHT);
|
|
||||||
|
|
||||||
final short mapID = futureMapID.get();
|
final short mapID = futureMapID.get();
|
||||||
ImageIOExecutor.saveImage(mapID, finalImage);
|
ImageIOExecutor.saveImage(mapID, image);
|
||||||
|
|
||||||
submitToMainThread(new Callable<Void>()
|
submitToMainThread(new Callable<Void>()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public Void call() throws Exception
|
public Void call() throws Exception
|
||||||
{
|
{
|
||||||
Renderer.installRenderer(finalImage, mapID);
|
Renderer.installRenderer(image, mapID);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return MapManager.createMap(playerUUID, mapID);
|
return MapManager.createMap(playerUUID, mapID);
|
||||||
}
|
}
|
||||||
|
|
||||||
static private ImageMap RenderPoster(final BufferedImage image, final UUID playerUUID) throws Throwable
|
static private ImageMap renderPoster(final BufferedImage image, final UUID playerUUID) throws Throwable
|
||||||
{
|
{
|
||||||
final PosterImage poster = new PosterImage(image);
|
final PosterImage poster = new PosterImage(image);
|
||||||
final int mapCount = poster.getImagesCount();
|
final int mapCount = poster.getImagesCount();
|
||||||
@ -144,33 +136,4 @@ public class ImageRendererExecutor extends Worker
|
|||||||
|
|
||||||
return MapManager.createMap(poster, playerUUID, mapsIDs);
|
return MapManager.createMap(poster, playerUUID, mapsIDs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static private BufferedImage ResizeImage(BufferedImage source, int destinationW, int destinationH)
|
|
||||||
{
|
|
||||||
float ratioW = (float)destinationW / (float)source.getWidth();
|
|
||||||
float ratioH = (float)destinationH / (float)source.getHeight();
|
|
||||||
int finalW, finalH;
|
|
||||||
|
|
||||||
if(ratioW < ratioH)
|
|
||||||
{
|
|
||||||
finalW = destinationW;
|
|
||||||
finalH = (int)(source.getHeight() * ratioW);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
finalW = (int)(source.getWidth() * ratioH);
|
|
||||||
finalH = destinationH;
|
|
||||||
}
|
|
||||||
|
|
||||||
int x, y;
|
|
||||||
x = (destinationW - finalW) / 2;
|
|
||||||
y = (destinationH - finalH) / 2;
|
|
||||||
|
|
||||||
BufferedImage newImage = new BufferedImage(destinationW, destinationH, BufferedImage.TYPE_INT_ARGB);
|
|
||||||
|
|
||||||
Graphics graphics = newImage.getGraphics();
|
|
||||||
graphics.drawImage(source, x, y, finalW, finalH, null);
|
|
||||||
graphics.dispose();
|
|
||||||
return newImage;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
97
src/main/java/fr/moribus/imageonmap/image/ImageUtils.java
Normal file
97
src/main/java/fr/moribus/imageonmap/image/ImageUtils.java
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
package fr.moribus.imageonmap.image;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Various image-related utilities
|
||||||
|
*/
|
||||||
|
public class ImageUtils {
|
||||||
|
|
||||||
|
public enum ScalingType {
|
||||||
|
NONE,
|
||||||
|
CONTAINED,
|
||||||
|
COVERED,
|
||||||
|
STRETCHED,
|
||||||
|
;
|
||||||
|
|
||||||
|
public BufferedImage resize(BufferedImage source, int destinationW, int destinationH) {
|
||||||
|
switch(this) {
|
||||||
|
case CONTAINED: return ImageUtils.resize(source, destinationW, destinationH, false);
|
||||||
|
case COVERED: return ImageUtils.resize(source, destinationW, destinationH, true);
|
||||||
|
case STRETCHED: return resizeStretched(source, destinationW, destinationH);
|
||||||
|
default: return source;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a resized buffer of the given source
|
||||||
|
* @param source
|
||||||
|
* @param destinationW
|
||||||
|
* @param destinationH
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static private BufferedImage resize(BufferedImage source, int destinationW, int destinationH, boolean covered)
|
||||||
|
{
|
||||||
|
float ratioW = (float)destinationW / (float)source.getWidth();
|
||||||
|
float ratioH = (float)destinationH / (float)source.getHeight();
|
||||||
|
int finalW, finalH;
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
if(covered ? ratioW > ratioH : ratioW < ratioH)
|
||||||
|
{
|
||||||
|
finalW = destinationW;
|
||||||
|
finalH = (int)(source.getHeight() * ratioW);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
finalW = (int)(source.getWidth() * ratioH);
|
||||||
|
finalH = destinationH;
|
||||||
|
}
|
||||||
|
|
||||||
|
x = (destinationW - finalW) / 2;
|
||||||
|
y = (destinationH - finalH) / 2;
|
||||||
|
|
||||||
|
return drawImage(source,
|
||||||
|
destinationW, destinationH,
|
||||||
|
x, y, finalW, finalH);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* @param destinationW
|
||||||
|
* @param destinationH
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static private BufferedImage resizeStretched(BufferedImage source, int destinationW, int destinationH) {
|
||||||
|
return drawImage(source,
|
||||||
|
destinationW, destinationH,
|
||||||
|
0, 0, destinationW, destinationH);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws the source image on a new buffer, and returns it.
|
||||||
|
* The source buffer can be drawn at any size and position in the new buffer.
|
||||||
|
* @param source The source buffer to draw
|
||||||
|
* @param bufferW The width of the new buffer
|
||||||
|
* @param bufferH The height of the new buffer
|
||||||
|
* @param posX The X position of the source buffer
|
||||||
|
* @param posY The Y position of the source buffer
|
||||||
|
* @param sourceW The width of the source buffer
|
||||||
|
* @param sourceH The height of the source buffer
|
||||||
|
* @return The new buffer, with the source buffer drawn on it
|
||||||
|
*/
|
||||||
|
static private BufferedImage drawImage(BufferedImage source,
|
||||||
|
int bufferW, int bufferH,
|
||||||
|
int posX, int posY,
|
||||||
|
int sourceW, int sourceH) {
|
||||||
|
BufferedImage newImage = new BufferedImage(bufferW, bufferH, BufferedImage.TYPE_INT_ARGB);
|
||||||
|
|
||||||
|
Graphics graphics = newImage.getGraphics();
|
||||||
|
graphics.drawImage(source, posX, posY, sourceW, sourceH, null);
|
||||||
|
graphics.dispose();
|
||||||
|
return newImage;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user