SSISO Community

시소당

이미지 파일 크기 동적으로 줄이기..

How to change image "file" size by changing resolution?
Author: shveta_vasisht

Nov 29, 2002 10:14 PM
 
Hi,
I am trying to reduce the image file size "without" changing the image dimensions.
The functionality which i am trying to implement is to allow a user to upload any image and then reduce the image file size to a some level.I am aware that we can get a scaled version of the image by using JAI and getScaledInstance(...) function of the image class , but i want the dimensions of the image to remain the same as the image which is uploaded.

What actually required is not the resize of image in
terms of width & height. but we need image which is
consuming less space (we somehow compromize on
resolution with some loss of accuracy eg.color level
etc.)
Is there some algorithm to make image take less
number of bytes without perceptible difference in
image.
The type of images that can be uploaded will be gif's and jpg's.
Are there certain methods in JAI or some other java API to reduce resolution ?
Has some one tried this before using a java code?

Regards,
Shveta
 
i've the same problem! any suggestion?
 
import java.awt.*;
import java.awt.image.*;
import java.io.*;
import java.util.*;
import javax.imageio.*;
import javax.imageio.stream.*;
 
public class ImageKit {
static {
ImageIO.setUseCache(false);
}
 
//Tested buffering. Reads 1000bytes/call for jpeg (200 for png, 100 for gif)
public static BufferedImage read(InputStream in) throws IOException {
BufferedImage image = ImageIO.read(in);
if (image == null)
throw new IOException("Read fails");
return image;
}
 
public static BufferedImage read(byte[] bytes) {
try {
return read(new ByteArrayInputStream(bytes));
} catch(IOException e) {
throw new RuntimeException(e);
}
}
 
//quality means jpeg output, if quality is < 0 ==> use default quality
public static void write(BufferedImage image, float quality, OutputStream out) throws IOException {
Iterator writers = ImageIO.getImageWritersBySuffix("jpeg");
if (!writers.hasNext())
throw new IllegalStateException("No writers found");
ImageWriter writer = (ImageWriter) writers.next();
ImageOutputStream ios = ImageIO.createImageOutputStream(out);
writer.setOutput(ios);
ImageWriteParam param = writer.getDefaultWriteParam();
if (quality >= 0) {
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(quality);
}
writer.write(null, new IIOImage(image, null, null), param);
ios.close();
writer.dispose();
}
 
public static byte[] toByteArray(BufferedImage image, float quality) {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream(50000);
write(image, quality, out);
return out.toByteArray();
} catch(IOException e) {
throw new RuntimeException(e);
}
}
 
public static BufferedImage compress(BufferedImage image, float quality) {
return read(toByteArray(image, quality));
}
 
public static void flush(BufferedImage image) {
try {
if (image != null)
image.flush();
} catch (NullPointerException e) {
//bug in sun's code
}
 
}
}

DEMO:
import java.awt.*;
import java.awt.image.*;
import java.io.*;
import java.net.*;
import java.text.*;
import javax.imageio.*;
import javax.swing.*;
import javax.swing.event.*;
 
public class CompressedView extends JComponent {
private BufferedImage originalImage, compressedImage;
private float quality=0.1f;
private int compressedSize;
 
public float getQuality() {
return quality;
}
 
public int getCompressedSize() {
return compressedSize;
}
 
public void setQuality(float quality) {
this.quality = quality;
calculateCompressedImage();
}
 
private void calculateCompressedImage() {
compressedImage = null;
if (originalImage == null) {
compressedSize = 0;
} else {
byte[] buff = ImageKit.toByteArray(originalImage, quality);
compressedImage = ImageKit.read(buff);
compressedSize = buff.length;
}
repaint();
}
 
public void setImage(BufferedImage image) {
originalImage = image;
calculateCompressedImage();
}
 
public int getImageWidth() {
return (originalImage == null) ? 0 : originalImage.getWidth();
}
 
public int getImageHeight() {
return (originalImage == null) ? 0 : originalImage.getHeight();
}
 
public Dimension getPreferredSize() {
return new Dimension(getImageWidth()*2, getImageHeight());
}
 
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (originalImage == null)
return;
g.drawImage(originalImage, 0, 0, null);
g.drawImage(compressedImage, originalImage.getWidth(), 0, null);
}
 
public static void main(String[] args) throws IOException {
URL url = new URL("http://today.java.net/jag/bio/JagHeadshot-small.jpg");
BufferedImage image = ImageIO.read(url);
final CompressedView view = new CompressedView();
view.setImage(image);
final JLabel percent = new JLabel();
final JLabel size = new JLabel();
JSlider slider = new JSlider();
slider.addChangeListener(new ChangeListener(){
NumberFormat format = NumberFormat.getIntegerInstance();
 
public void stateChanged(ChangeEvent e) {
JSlider sl = (JSlider) e.getSource();
percent.setText(sl.getValue() + "%");
if (!sl.getValueIsAdjusting()) {
view.setQuality(sl.getValue()/100f);
size.setText(format.format(view.getCompressedSize()) + " bytes");
}
}
});
slider.setValue((int)(100* view.getQuality()));
JToolBar tb = new JToolBar();
tb.add(percent);
tb.add(slider);
tb.add(size);
JFrame f = new JFrame("CompressedView");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container cp = f.getContentPane();
cp.add(tb, BorderLayout.NORTH);
cp.add(view);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
 
Hi, i tried the code and it worked very well.Thanks

rc
 
출처: http://forum.java.sun.com

1445 view

4.0 stars