在我的Java Spring MVC Web Application
中,我可以选择上传任意大小的图片。目前我有一个API,可以减少任何超过指定宽度的上传图像的大小。我使用以下代码:
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.image.renderable.ParameterBlock;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import javax.imageio.ImageIO;
import javax.media.jai.JAI;
import javax.media.jai.PlanarImage;
import javax.media.jai.RenderedOp;
public class ImageRescale
{
private static RenderingHints hints;
static
{
hints = new RenderingHints(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
hints.put(RenderingHints.KEY_COLOR_RENDERING,RenderingHints.VALUE_COLOR_RENDER_QUALITY);
hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
/*
* this block is to silence the warning that we're not using JAI
* native acceleration but are using the pure java implementation.
*/
Properties p = new Properties(System.getProperties());
p.put("com.sun.media.jai.disableMediaLib", "true");
System.setProperties(p);
}
public static byte[] getScaledInstance(byte[] image, int maxWidth)
{
InputStream in = new ByteArrayInputStream(image);
BufferedImage img = null;
try
{
img = ImageIO.read(in);
double scale = (double) maxWidth / img.getWidth();
if ( scale > 1.0d )
{
return image;
}
else if (scale > 0.5d && scale < 1.0d)
{
return getByteArray(getScaledDownByGraphics(img, scale));
}
else if (scale <= 0.5d)
{
return getByteArray(getScaledDownByJAI(img, scale));
}
}
catch (IOException e)
{
e.printStackTrace();
}
return image;
}
public static byte[] getByteArray(BufferedImage img)
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] imageInByte = null;
try
{
ImageIO.write( img, "jpg", baos );
baos.flush();
imageInByte = baos.toByteArray();
baos.close();
}
catch (IOException e)
{
e.printStackTrace();
}
return imageInByte;
}
/**
* See http://www.digitalsanctuary.com/tech-blog/java/how-to-resize-uploaded-images-using-java-better-way.html
* This instance seems to produce quality images ONLY when you are
* scaling down to something less than 50% of the original size.
* @param img
* @param scale
* @return the scaled image
*/
private static BufferedImage getScaledDownByJAI(BufferedImage img, double scale)
{
if(scale > 1.0d)
{
throw new RuntimeException("Can't scale according to " + scale + " : This method only scales down.");
}
PlanarImage originalImage = PlanarImage.wrapRenderedImage(img);
// now resize the image
ParameterBlock paramBlock = new ParameterBlock();
paramBlock.addSource(originalImage); // The source image
paramBlock.add(scale); // The xScale
paramBlock.add(scale); // The yScale
paramBlock.add(0.0); // The x translation
paramBlock.add(0.0); // The y translation
RenderedOp resizedImage = JAI.create("SubsampleAverage", paramBlock, hints);
return resizedImage.getAsBufferedImage();
}
/**
* This method produces high quality images when target scale is greater
* than 50% of the original.
* @param img
* @param scale
* @return the scaled image
*/
private static BufferedImage getScaledDownByGraphics(BufferedImage img, double scale)
{
final float scaleFactor = 0.8f;
BufferedImage ret = (BufferedImage)img;
int w = img.getWidth();
int h = img.getHeight();
int targetWidth = (int)(img.getWidth() * scale);
int targetHeight = (int)(img.getHeight() * scale);
int loopCount = 0;
int maxLoopCount = 20;
BufferedImage tmp;
do {
if (w > targetWidth) {
w *= scaleFactor;
if (w < targetWidth) {
w = targetWidth;
}
}
if (h > targetHeight) {
h *= scaleFactor;
if (h < targetHeight) {
h = targetHeight;
}
}
tmp = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = tmp.createGraphics();
g2.addRenderingHints(hints);
g2.drawImage(ret, 0, 0, w, h, null);
g2.dispose();
ret = tmp;
if(++loopCount > maxLoopCount) {
throw new RuntimeException("Hit maximum loop count " + maxLoopCount);
}
} while (w != targetWidth || h != targetHeight);
return ret;
}
}
但我现在想要的是一个API,压缩所有上传的图像并将其分辨率降低到大约72 dpi
,我认为这是图像的网络标准。有什么方法可以达到这个目的。
答案 0 :(得分:0)
你能检查这对你有帮助吗?
/**
*
* @param bi image
* @param mimeType type
* @param quality quality
* @return compressed image
* @throws IOException on error
*/
private static BufferedImage compressImage(BufferedImage bi, String mimeType
, float quality) throws IOException {
// converting buffered image to byte array
// do not compress GIFs
if (mimeType.equalsIgnoreCase("image/gif")) {
return bi;
}
ImageWriter writer = ImageIO.getImageWritersByMIMEType(mimeType).next();
ImageWriteParam iwp = writer.getDefaultWriteParam();
if (!mimeType.equalsIgnoreCase("image/png") && !mimeType.equalsIgnoreCase("image/bmp")) {
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
iwp.setCompressionQuality(quality);
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedOutputStream bos = new java.io.BufferedOutputStream(baos);
ImageOutputStream ios = ImageIO.createImageOutputStream(bos);
writer.setOutput(ios);
IIOImage optimizedImage = new IIOImage(bi, null, null);
writer.write(null, optimizedImage, iwp);
writer.dispose();
baos.flush();
ByteArrayInputStream in = new ByteArrayInputStream(baos.toByteArray());
return ImageIO.read(in);
}