プログラマメモ2 - programmer no memo2

jpegの圧縮後の画像 2008/08/10

Javaです。
画像のファイルサイズを小さくする方法は、実際の画像のサイズを小さくして保存するか、圧縮率を高くして保存するかだと思います。

圧縮率を調整してその結果画像を表示する簡単なアプリです。



左側のパネルに画像をドラッグアンドドロップします。スライダーで圧縮率を調整します。その結果が右パネルに表示されます。

swingxのライブラリを使っています。swingxのorg.jdesktop.swingx.JXImageViewは、ドラッグアンドドロップした画像を変換して表示してくれるコンポーネントです。便利です。


あと、
を使ってます。
swingworkerがjava6から含まれてますが、とりあえずjava5で。

画面はnetbeans6で作りました。あと、作った画面にあいたコンポーネントのフィールド変数をpublicにしてfinalにして外から直で触るという方法をとってます。

以下コード。

package img;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Iterator;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import javax.swing.JFrame;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.jdesktop.swingworker.SwingWorker;

public class Main {

public static void main(String[] args) {

final Frame frame = new Frame();


frame.panelControl.slider.addChangeListener(new ChangeListener() {

public void stateChanged(ChangeEvent e) {
// System.out.println(e);
JSlider source = (JSlider) e.getSource();
if (!source.getValueIsAdjusting()) {

final float f = (int) source.getValue() / 100f;
final BufferedImage bufferedImage = (BufferedImage) frame.panelControl.imageView
.getImage();
if (bufferedImage == null)
return;

source.setEnabled(false);
frame.panelControl.imageView.setEditable(false);

new SwingWorker<String, String>() {


byte[] bs;

@Override
protected String doInBackground() throws Exception {

bs = a(bufferedImage, f);

return null;
}

@Override
protected void done() {
System.out.println("*** done");
frame.panelControl.slider.setEnabled(true);
frame.panelControl.imageView.setEditable(true);

if (bs == null)
return;

try {

BufferedImage image = ImageIO
.read(new ByteArrayInputStream(bs));
frame.panelControl.imagePanel2.setImage(image);

} catch (IOException e) {
e.printStackTrace();
return;
}
String result;
result = (bs.length / 1024d) + "";
frame.panelControl.textInfo.setText("" + result
+ "Kbyte");

}

}.execute();

}

}
});

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(100, 100, 300, 500);
frame.setVisible(true);

}

static byte[] a(BufferedImage image, float compress) {
return image(image, compress);
}

static byte[] image(BufferedImage image, float compress) {
Iterator<ImageWriter> wfiles = ImageIO
.getImageWritersByFormatName("jpg");

byte[] bs = new byte[0];
if (wfiles.hasNext()) {
ImageWriter imageWriter = wfiles.next();

try {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageOutputStream sto = ImageIO
.createImageOutputStream(byteArrayOutputStream);
imageWriter.setOutput(sto);

ImageWriteParam param = imageWriter.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(compress);

imageWriter.write(null, new IIOImage(image, null, null), param);
imageWriter.dispose();

bs = (byteArrayOutputStream.toByteArray());
} catch (IOException e) {
e.printStackTrace();
}

}
return bs;
}
}

/*
* PanelControl.java
*
* Created on 2008/08/10, 18:16
*/

package img;

/**
*
* @author nakawakashigeto
*/
public class PanelControl extends javax.swing.JPanel {

/** Creates new form PanelControl */
public PanelControl() {
initComponents();
}

/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {

jScrollPane1 = new javax.swing.JScrollPane();

setName("Form"); // NOI18N

slider.setMajorTickSpacing(5);
slider.setPaintLabels(true);
slider.setPaintTicks(true);
slider.setValue(85);
slider.setName("slider"); // NOI18N

imageView.setName("imageView"); // NOI18N

org.jdesktop.layout.GroupLayout imageViewLayout = new org.jdesktop.layout.GroupLayout(imageView);
imageView.setLayout(imageViewLayout);
imageViewLayout.setHorizontalGroup(
imageViewLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(0, 211, Short.MAX_VALUE)
);
imageViewLayout.setVerticalGroup(
imageViewLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(0, 184, Short.MAX_VALUE)
);

jScrollPane1.setName("jScrollPane1"); // NOI18N

textInfo.setColumns(20);
textInfo.setRows(5);
textInfo.setName("textInfo"); // NOI18N
jScrollPane1.setViewportView(textInfo);

imagePanel2.setName("imagePanel2"); // NOI18N

org.jdesktop.layout.GroupLayout imagePanel2Layout = new org.jdesktop.layout.GroupLayout(imagePanel2);
imagePanel2.setLayout(imagePanel2Layout);
imagePanel2Layout.setHorizontalGroup(
imagePanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(0, 199, Short.MAX_VALUE)
);
imagePanel2Layout.setVerticalGroup(
imagePanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(0, 184, Short.MAX_VALUE)
);

org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(layout.createSequentialGroup()
.addContainerGap()
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 448, Short.MAX_VALUE)
.add(slider, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 448, Short.MAX_VALUE)
.add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
.add(imageView, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.add(18, 18, 18)
.add(imagePanel2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addContainerGap())))
);
layout.setVerticalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(layout.createSequentialGroup()
.addContainerGap()
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(imageView, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.add(imagePanel2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(slider, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(jScrollPane1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 54, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
}// </editor-fold>//GEN-END:initComponents


// Variables declaration - do not modify//GEN-BEGIN:variables
public final org.jdesktop.swingx.JXImageView imagePanel2 = new org.jdesktop.swingx.JXImageView();
public final org.jdesktop.swingx.JXImageView imageView = new org.jdesktop.swingx.JXImageView();
private javax.swing.JScrollPane jScrollPane1;
public final javax.swing.JSlider slider = new javax.swing.JSlider();
public final javax.swing.JTextArea textInfo = new javax.swing.JTextArea();
// End of variables declaration//GEN-END:variables

}


/*
* Frame.java
*
* Created on 2008/08/10, 19:42
*/

package img;

/**
*
* @author nakawakashigeto
*/
public class Frame extends javax.swing.JFrame {

/** Creates new form Frame */
public Frame() {
initComponents();
}

/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setName("Form"); // NOI18N

panelControl.setName("panelControl"); // NOI18N

org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(org.jdesktop.layout.GroupLayout.TRAILING, panelControl, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 420, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(panelControl, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 303, Short.MAX_VALUE)
);

pack();
}// </editor-fold>//GEN-END:initComponents

/**
* @param args the command line arguments
*/

public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Frame().setVisible(true);
}
});
}

// Variables declaration - do not modify//GEN-BEGIN:variables
public final img.PanelControl panelControl = new img.PanelControl();
// End of variables declaration//GEN-END:variables

}

: