mirror of
https://github.com/zDevelopers/ImageOnMap.git
synced 2024-11-13 05:44:04 +01: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.commands.IoMCommand;
|
||||
import fr.moribus.imageonmap.image.ImageRendererExecutor;
|
||||
import fr.moribus.imageonmap.image.ImageUtils;
|
||||
import fr.moribus.imageonmap.map.ImageMap;
|
||||
import fr.zcraft.zlib.components.commands.CommandException;
|
||||
import fr.zcraft.zlib.components.commands.CommandInfo;
|
||||
@ -40,7 +41,7 @@ public class NewCommand extends IoMCommand
|
||||
protected void run() throws CommandException
|
||||
{
|
||||
final Player player = playerSender();
|
||||
boolean scaling = false;
|
||||
ImageUtils.ScalingType scaling = ImageUtils.ScalingType.NONE;
|
||||
URL url;
|
||||
int width = 0, height = 0;
|
||||
|
||||
@ -58,17 +59,21 @@ public class NewCommand extends IoMCommand
|
||||
|
||||
if(args.length >= 2)
|
||||
{
|
||||
if(args[1].equals("resize")) {
|
||||
scaling = true;
|
||||
if(args.length >= 4) {
|
||||
width = Integer.parseInt(args[2]);
|
||||
height = Integer.parseInt(args[3]);
|
||||
}
|
||||
if(args.length >= 4) {
|
||||
width = Integer.parseInt(args[2]);
|
||||
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..."));
|
||||
ImageRendererExecutor.Render(url, scaling, player.getUniqueId(), width, height, new WorkerCallback<ImageMap>()
|
||||
ImageRendererExecutor.render(url, scaling, player.getUniqueId(), width, height, new WorkerCallback<ImageMap>()
|
||||
{
|
||||
@Override
|
||||
public void finished(ImageMap result)
|
||||
|
@ -27,7 +27,6 @@ import fr.zcraft.zlib.components.worker.WorkerCallback;
|
||||
import fr.zcraft.zlib.components.worker.WorkerRunnable;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -42,7 +41,7 @@ import java.util.concurrent.Future;
|
||||
@WorkerAttributes (name = "Image Renderer", queriesMainThread = true)
|
||||
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>()
|
||||
{
|
||||
@ -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 (scaling) return RenderScaled(image, playerUUID, width, height);
|
||||
else return RenderPoster(image, playerUUID);
|
||||
if(scaling != ImageUtils.ScalingType.NONE && height <= 1 && width <= 1) {
|
||||
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);
|
||||
}
|
||||
|
||||
static private ImageMap RenderScaled(final BufferedImage image, final UUID playerUUID, final int width, final int height) 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
|
||||
static private ImageMap renderSingle(final BufferedImage image, final UUID playerUUID) throws Throwable
|
||||
{
|
||||
MapManager.checkMapLimit(1, playerUUID);
|
||||
Future<Short> futureMapID = submitToMainThread(new Callable<Short>()
|
||||
final Future<Short> futureMapID = submitToMainThread(new Callable<Short>()
|
||||
{
|
||||
@Override
|
||||
public Short call() throws Exception
|
||||
@ -90,27 +85,24 @@ public class ImageRendererExecutor extends Worker
|
||||
return MapManager.getNewMapsIds(1)[0];
|
||||
}
|
||||
});
|
||||
|
||||
final BufferedImage finalImage = ResizeImage(image, ImageMap.WIDTH, ImageMap.HEIGHT);
|
||||
|
||||
|
||||
final short mapID = futureMapID.get();
|
||||
ImageIOExecutor.saveImage(mapID, finalImage);
|
||||
ImageIOExecutor.saveImage(mapID, image);
|
||||
|
||||
submitToMainThread(new Callable<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void call() throws Exception
|
||||
{
|
||||
Renderer.installRenderer(finalImage, mapID);
|
||||
Renderer.installRenderer(image, mapID);
|
||||
return null;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
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 int mapCount = poster.getImagesCount();
|
||||
@ -144,33 +136,4 @@ public class ImageRendererExecutor extends Worker
|
||||
|
||||
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