Add multiple quality levels for JPG encoding - adjust default to 0.85
This commit is contained in:
parent
e978745f79
commit
a3015f78d2
8 changed files with 69 additions and 41 deletions
|
|
@ -6,7 +6,6 @@ import java.util.List;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.dynmap.debug.Debug;
|
import org.dynmap.debug.Debug;
|
||||||
import org.dynmap.kzedmap.KzedMap;
|
|
||||||
import org.dynmap.utils.DynmapBufferedImage;
|
import org.dynmap.utils.DynmapBufferedImage;
|
||||||
import org.dynmap.utils.FileLockManager;
|
import org.dynmap.utils.FileLockManager;
|
||||||
import org.dynmap.utils.MapChunkCache;
|
import org.dynmap.utils.MapChunkCache;
|
||||||
|
|
@ -447,7 +446,7 @@ public class DynmapWorld {
|
||||||
try {
|
try {
|
||||||
if(!zf.getParentFile().exists())
|
if(!zf.getParentFile().exists())
|
||||||
zf.getParentFile().mkdirs();
|
zf.getParentFile().mkdirs();
|
||||||
FileLockManager.imageIOWrite(zIm, pd.fmt.getFileExt(), zf);
|
FileLockManager.imageIOWrite(zIm, pd.fmt, zf);
|
||||||
Debug.debug("Saved zoom-out tile at " + zf.getPath());
|
Debug.debug("Saved zoom-out tile at " + zf.getPath());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Debug.error("Failed to save zoom-out tile: " + zf.getName(), e);
|
Debug.error("Failed to save zoom-out tile: " + zf.getName(), e);
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,26 @@ import org.json.simple.JSONObject;
|
||||||
|
|
||||||
public abstract class MapType {
|
public abstract class MapType {
|
||||||
public enum ImageFormat {
|
public enum ImageFormat {
|
||||||
FORMAT_PNG("png"),
|
FORMAT_PNG("png", "png", 0.0f),
|
||||||
FORMAT_JPG("jpg");
|
FORMAT_JPG75("jpg-q75", "jpg", 0.75f),
|
||||||
|
FORMAT_JPG80("jpg-q80", "jpg", 0.80f),
|
||||||
|
FORMAT_JPG85("jpg-q85", "jpg", 0.85f),
|
||||||
|
FORMAT_JPG("jpg", "jpg", 0.85f),
|
||||||
|
FORMAT_JPG90("jpg-q90", "jpg", 0.90f),
|
||||||
|
FORMAT_JPG95("jpg-q95", "jpg", 0.95f),
|
||||||
|
FORMAT_JPG100("jpg-q100", "jpg", 1.00f);
|
||||||
|
String id;
|
||||||
String ext;
|
String ext;
|
||||||
ImageFormat(String ext) {
|
float qual;
|
||||||
|
|
||||||
|
ImageFormat(String id, String ext, float quality) {
|
||||||
|
this.id = id;
|
||||||
this.ext = ext;
|
this.ext = ext;
|
||||||
|
this.qual = quality;
|
||||||
}
|
}
|
||||||
|
public String getID() { return id; }
|
||||||
public String getFileExt() { return ext; }
|
public String getFileExt() { return ext; }
|
||||||
|
public float getQuality() { return qual; }
|
||||||
};
|
};
|
||||||
|
|
||||||
public abstract MapTile[] getTiles(Location l);
|
public abstract MapTile[] getTiles(Location l);
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,6 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.World.Environment;
|
import org.bukkit.World.Environment;
|
||||||
|
|
@ -23,9 +21,7 @@ import org.dynmap.MapManager;
|
||||||
import org.dynmap.TileHashManager;
|
import org.dynmap.TileHashManager;
|
||||||
import org.dynmap.MapTile;
|
import org.dynmap.MapTile;
|
||||||
import org.dynmap.MapType;
|
import org.dynmap.MapType;
|
||||||
import org.dynmap.MapType.MapStep;
|
|
||||||
import org.dynmap.debug.Debug;
|
import org.dynmap.debug.Debug;
|
||||||
import org.dynmap.kzedmap.KzedMap;
|
|
||||||
import org.dynmap.utils.DynmapBufferedImage;
|
import org.dynmap.utils.DynmapBufferedImage;
|
||||||
import org.dynmap.utils.FileLockManager;
|
import org.dynmap.utils.FileLockManager;
|
||||||
import org.dynmap.utils.MapChunkCache;
|
import org.dynmap.utils.MapChunkCache;
|
||||||
|
|
@ -312,7 +308,7 @@ public class FlatMap extends MapType {
|
||||||
if(!outputFile.getParentFile().exists())
|
if(!outputFile.getParentFile().exists())
|
||||||
outputFile.getParentFile().mkdirs();
|
outputFile.getParentFile().mkdirs();
|
||||||
try {
|
try {
|
||||||
FileLockManager.imageIOWrite(im.buf_img, "png", outputFile);
|
FileLockManager.imageIOWrite(im.buf_img, ImageFormat.FORMAT_PNG, outputFile);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Debug.error("Failed to save image: " + outputFile.getPath(), e);
|
Debug.error("Failed to save image: " + outputFile.getPath(), e);
|
||||||
} catch (java.lang.NullPointerException e) {
|
} catch (java.lang.NullPointerException e) {
|
||||||
|
|
@ -343,7 +339,7 @@ public class FlatMap extends MapType {
|
||||||
if(!dayfile.getParentFile().exists())
|
if(!dayfile.getParentFile().exists())
|
||||||
dayfile.getParentFile().mkdirs();
|
dayfile.getParentFile().mkdirs();
|
||||||
try {
|
try {
|
||||||
FileLockManager.imageIOWrite(im_day.buf_img, "png", dayfile);
|
FileLockManager.imageIOWrite(im_day.buf_img, ImageFormat.FORMAT_PNG, dayfile);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Debug.error("Failed to save image: " + dayfile.getPath(), e);
|
Debug.error("Failed to save image: " + dayfile.getPath(), e);
|
||||||
} catch (java.lang.NullPointerException e) {
|
} catch (java.lang.NullPointerException e) {
|
||||||
|
|
@ -585,6 +581,7 @@ public class FlatMap extends MapType {
|
||||||
s(o, "mapzoomin", c.getInteger("mapzoomin", 3));
|
s(o, "mapzoomin", c.getInteger("mapzoomin", 3));
|
||||||
s(o, "mapzoomout", world.getExtraZoomOutLevels());
|
s(o, "mapzoomout", world.getExtraZoomOutLevels());
|
||||||
s(o, "compassview", "S"); /* Always from south */
|
s(o, "compassview", "S"); /* Always from south */
|
||||||
|
s(o, "image-format", ImageFormat.FORMAT_PNG.getFileExt());
|
||||||
a(worldObject, "maps", o);
|
a(worldObject, "maps", o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -91,10 +91,16 @@ public class HDMap extends MapType {
|
||||||
}
|
}
|
||||||
String fmt = configuration.getString("image-format", "png");
|
String fmt = configuration.getString("image-format", "png");
|
||||||
/* Only allow png or jpg */
|
/* Only allow png or jpg */
|
||||||
if(fmt.equals(IMGFORMAT_PNG))
|
for(ImageFormat f : ImageFormat.values()) {
|
||||||
|
if(fmt.equals(f.getID())) {
|
||||||
|
imgformat = f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(imgformat == null) {
|
||||||
|
Log.severe("HDMap '"+name+"' set invalid image-format: " + fmt);
|
||||||
imgformat = ImageFormat.FORMAT_PNG;
|
imgformat = ImageFormat.FORMAT_PNG;
|
||||||
else
|
}
|
||||||
imgformat = ImageFormat.FORMAT_JPG;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public HDShader getShader() { return shader; }
|
public HDShader getShader() { return shader; }
|
||||||
|
|
|
||||||
|
|
@ -1041,7 +1041,7 @@ public class IsoHDPerspective implements HDPerspective {
|
||||||
if(!f.getParentFile().exists())
|
if(!f.getParentFile().exists())
|
||||||
f.getParentFile().mkdirs();
|
f.getParentFile().mkdirs();
|
||||||
try {
|
try {
|
||||||
FileLockManager.imageIOWrite(im[i].buf_img, fmt.getFileExt(), f);
|
FileLockManager.imageIOWrite(im[i].buf_img, fmt, f);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Debug.error("Failed to save image: " + f.getPath(), e);
|
Debug.error("Failed to save image: " + f.getPath(), e);
|
||||||
} catch (java.lang.NullPointerException e) {
|
} catch (java.lang.NullPointerException e) {
|
||||||
|
|
@ -1074,7 +1074,7 @@ public class IsoHDPerspective implements HDPerspective {
|
||||||
if(!f.getParentFile().exists())
|
if(!f.getParentFile().exists())
|
||||||
f.getParentFile().mkdirs();
|
f.getParentFile().mkdirs();
|
||||||
try {
|
try {
|
||||||
FileLockManager.imageIOWrite(dayim[i].buf_img, fmt.getFileExt(), f);
|
FileLockManager.imageIOWrite(dayim[i].buf_img, fmt, f);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Debug.error("Failed to save image: " + f.getPath(), e);
|
Debug.error("Failed to save image: " + f.getPath(), e);
|
||||||
} catch (java.lang.NullPointerException e) {
|
} catch (java.lang.NullPointerException e) {
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import org.dynmap.ColorScheme;
|
||||||
import org.dynmap.ConfigurationNode;
|
import org.dynmap.ConfigurationNode;
|
||||||
import org.dynmap.DynmapWorld;
|
import org.dynmap.DynmapWorld;
|
||||||
import org.dynmap.MapManager;
|
import org.dynmap.MapManager;
|
||||||
|
import org.dynmap.MapType.ImageFormat;
|
||||||
import org.dynmap.TileHashManager;
|
import org.dynmap.TileHashManager;
|
||||||
import org.dynmap.debug.Debug;
|
import org.dynmap.debug.Debug;
|
||||||
import org.dynmap.utils.DynmapBufferedImage;
|
import org.dynmap.utils.DynmapBufferedImage;
|
||||||
|
|
@ -276,7 +277,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
||||||
if(!fname.getParentFile().exists())
|
if(!fname.getParentFile().exists())
|
||||||
fname.getParentFile().mkdirs();
|
fname.getParentFile().mkdirs();
|
||||||
try {
|
try {
|
||||||
FileLockManager.imageIOWrite(img.buf_img, "png", fname);
|
FileLockManager.imageIOWrite(img.buf_img, ImageFormat.FORMAT_PNG, fname);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Debug.error("Failed to save image: " + fname.getPath(), e);
|
Debug.error("Failed to save image: " + fname.getPath(), e);
|
||||||
} catch (java.lang.NullPointerException e) {
|
} catch (java.lang.NullPointerException e) {
|
||||||
|
|
@ -306,7 +307,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
||||||
if(!dfname.getParentFile().exists())
|
if(!dfname.getParentFile().exists())
|
||||||
dfname.getParentFile().mkdirs();
|
dfname.getParentFile().mkdirs();
|
||||||
try {
|
try {
|
||||||
FileLockManager.imageIOWrite(img_day.buf_img, "png", dfname);
|
FileLockManager.imageIOWrite(img_day.buf_img, ImageFormat.FORMAT_PNG, dfname);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Debug.error("Failed to save image: " + dfname.getPath(), e);
|
Debug.error("Failed to save image: " + dfname.getPath(), e);
|
||||||
} catch (java.lang.NullPointerException e) {
|
} catch (java.lang.NullPointerException e) {
|
||||||
|
|
@ -390,7 +391,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
||||||
zoomFile.getParentFile().mkdirs();
|
zoomFile.getParentFile().mkdirs();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
FileLockManager.imageIOWrite(zIm, "png", zoomFile);
|
FileLockManager.imageIOWrite(zIm, ImageFormat.FORMAT_PNG, zoomFile);
|
||||||
Debug.debug("Saved zoom-out tile at " + zoomFile.getName());
|
Debug.debug("Saved zoom-out tile at " + zoomFile.getName());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Debug.error("Failed to save zoom-out tile: " + zoomFile.getName(), e);
|
Debug.error("Failed to save zoom-out tile: " + zoomFile.getName(), e);
|
||||||
|
|
@ -589,6 +590,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
||||||
s(o, "mapzoomin", c.getInteger("mapzoomin", 2));
|
s(o, "mapzoomin", c.getInteger("mapzoomin", 2));
|
||||||
s(o, "mapzoomout", world.getExtraZoomOutLevels()+1);
|
s(o, "mapzoomout", world.getExtraZoomOutLevels()+1);
|
||||||
s(o, "compassview", "SE"); /* Always from southeast */
|
s(o, "compassview", "SE"); /* Always from southeast */
|
||||||
|
s(o, "image-format", ImageFormat.FORMAT_PNG.getFileExt());
|
||||||
a(worldObject, "maps", o);
|
a(worldObject, "maps", o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,9 @@
|
||||||
package org.dynmap.kzedmap;
|
package org.dynmap.kzedmap;
|
||||||
|
|
||||||
import org.dynmap.DynmapWorld;
|
import org.dynmap.DynmapWorld;
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
|
@ -19,16 +14,8 @@ import org.dynmap.Log;
|
||||||
import org.dynmap.MapManager;
|
import org.dynmap.MapManager;
|
||||||
import org.dynmap.MapTile;
|
import org.dynmap.MapTile;
|
||||||
import org.dynmap.MapType;
|
import org.dynmap.MapType;
|
||||||
import org.dynmap.MapType.MapStep;
|
|
||||||
import org.dynmap.utils.DynmapBufferedImage;
|
|
||||||
import org.dynmap.utils.MapChunkCache;
|
import org.dynmap.utils.MapChunkCache;
|
||||||
import org.dynmap.utils.Vector3D;
|
|
||||||
import org.json.simple.JSONObject;
|
import org.json.simple.JSONObject;
|
||||||
import java.awt.image.DataBufferInt;
|
|
||||||
import java.awt.image.DataBuffer;
|
|
||||||
import java.awt.image.WritableRaster;
|
|
||||||
import java.awt.image.ColorModel;
|
|
||||||
import java.awt.image.Raster;
|
|
||||||
|
|
||||||
public class KzedMap extends MapType {
|
public class KzedMap extends MapType {
|
||||||
protected static final Logger log = Logger.getLogger("Minecraft");
|
protected static final Logger log = Logger.getLogger("Minecraft");
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,22 @@
|
||||||
package org.dynmap.utils;
|
package org.dynmap.utils;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.awt.image.DirectColorModel;
|
import java.awt.image.DirectColorModel;
|
||||||
import java.awt.image.WritableRaster;
|
import java.awt.image.WritableRaster;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.imageio.IIOImage;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.imageio.ImageWriteParam;
|
||||||
|
import javax.imageio.ImageWriter;
|
||||||
|
import javax.imageio.stream.ImageOutputStream;
|
||||||
|
|
||||||
import org.dynmap.Log;
|
import org.dynmap.Log;
|
||||||
|
import org.dynmap.MapType.ImageFormat;
|
||||||
import org.dynmap.debug.Debug;
|
import org.dynmap.debug.Debug;
|
||||||
/**
|
/**
|
||||||
* Implements soft-locks for prevent concurrency issues with file updates
|
* Implements soft-locks for prevent concurrency issues with file updates
|
||||||
|
|
@ -141,13 +146,13 @@ public class FileLockManager {
|
||||||
/**
|
/**
|
||||||
* Wrapper for IOImage.write - implements retries for busy files
|
* Wrapper for IOImage.write - implements retries for busy files
|
||||||
*/
|
*/
|
||||||
public static void imageIOWrite(BufferedImage img, String type, File fname) throws IOException {
|
public static void imageIOWrite(BufferedImage img, ImageFormat fmt, File fname) throws IOException {
|
||||||
int retrycnt = 0;
|
int retrycnt = 0;
|
||||||
boolean done = false;
|
boolean done = false;
|
||||||
byte[] rslt;
|
byte[] rslt;
|
||||||
synchronized(baos_lock) {
|
synchronized(baos_lock) {
|
||||||
baos.reset();
|
baos.reset();
|
||||||
if(type.equals("jpg")) {
|
if(fmt.getFileExt().equals("jpg")) {
|
||||||
WritableRaster raster = img.getRaster();
|
WritableRaster raster = img.getRaster();
|
||||||
WritableRaster newRaster = raster.createWritableChild(0, 0, img.getWidth(),
|
WritableRaster newRaster = raster.createWritableChild(0, 0, img.getWidth(),
|
||||||
img.getHeight(), 0, 0, new int[] {0, 1, 2});
|
img.getHeight(), 0, 0, new int[] {0, 1, 2});
|
||||||
|
|
@ -156,11 +161,31 @@ public class FileLockManager {
|
||||||
cm.getRedMask(), cm.getGreenMask(), cm.getBlueMask());
|
cm.getRedMask(), cm.getGreenMask(), cm.getBlueMask());
|
||||||
// now create the new buffer that is used ot write the image:
|
// now create the new buffer that is used ot write the image:
|
||||||
BufferedImage rgbBuffer = new BufferedImage(newCM, newRaster, false, null);
|
BufferedImage rgbBuffer = new BufferedImage(newCM, newRaster, false, null);
|
||||||
ImageIO.write(rgbBuffer, type, baos); /* Write to byte array stream - prevent bogus I/O errors */
|
|
||||||
|
// Find a jpeg writer
|
||||||
|
ImageWriter writer = null;
|
||||||
|
Iterator iter = ImageIO.getImageWritersByFormatName("jpg");
|
||||||
|
if (iter.hasNext()) {
|
||||||
|
writer = (ImageWriter)iter.next();
|
||||||
|
}
|
||||||
|
if(writer == null) {
|
||||||
|
Log.severe("No JPEG ENCODER - Java VM does not support JPEG encoding");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ImageWriteParam iwp = writer.getDefaultWriteParam();
|
||||||
|
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
|
||||||
|
iwp.setCompressionQuality(fmt.getQuality());
|
||||||
|
|
||||||
|
ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
|
||||||
|
writer.setOutput(ios);
|
||||||
|
|
||||||
|
writer.write(null, new IIOImage(rgbBuffer, null, null), iwp);
|
||||||
|
writer.dispose();
|
||||||
|
|
||||||
rgbBuffer.flush();
|
rgbBuffer.flush();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ImageIO.write(img, type, baos); /* Write to byte array stream - prevent bogus I/O errors */
|
ImageIO.write(img, fmt.getFileExt(), baos); /* Write to byte array stream - prevent bogus I/O errors */
|
||||||
}
|
}
|
||||||
rslt = baos.toByteArray();
|
rslt = baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue