package uk.co.mmscomputing.application.imageviewer;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.awt.print.*;
import java.io.*;
import java.util.*; // as of 1.5.0 java.util has class Scanner
import javax.imageio.*;
import javax.imageio.stream.*;
import java.beans.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.imageio.metadata.*;
import uk.co.mmscomputing.util.JarImageIcon;
//import uk.co.mmscomputing.imageio.*;
import uk.co.mmscomputing.image.operators.*;
public class ImageTab extends JPanel implements PropertyChangeListener{
static public final String fileOpenID="uk.co.mmscomputing.file.open.dir";
static public final String fileSaveID="uk.co.mmscomputing.file.save.dir";
protected Properties properties;
protected JTabbedPane images;
protected JFileChooser openfc;
protected JFileChooser savefc;
public ImageTab(Properties properties){
this.properties=properties;
setLayout(new BorderLayout());
JPanel p=new JPanel();
p.setLayout(new BorderLayout());
JPanel q=new JPanel();
q.setLayout(new BoxLayout(q,BoxLayout.PAGE_AXIS));
setButtonPanel(q);
p.add(q,BorderLayout.NORTH);
add(p,BorderLayout.EAST);
images=new JTabbedPane();
add(images,BorderLayout.CENTER);
String userdir=System.getProperty("user.home");
setOpenDir(properties.getProperty(fileOpenID,userdir));
setSaveDir(properties.getProperty(fileSaveID,userdir));
}
public void setOpenDir(String path){
new File(path).mkdirs();
openfc=new JFileChooser(path);
}
public void setSaveDir(String path){
new File(path).mkdirs();
savefc=new JFileChooser(path);
}
protected void setButtonPanel(JPanel gui){
JPanel buttonPanel=new JPanel();
buttonPanel.setLayout(new GridLayout(0,1));
buttonPanel.add(new JButton(getNewAction()));
buttonPanel.add(new JButton(getOpenAction()));
buttonPanel.add(new JButton(getSaveAction()));
buttonPanel.add(new JButton(getPrintAction()));
buttonPanel.add(new JButton(getConvertAction()));
buttonPanel.add(new JButton(getRotateAction()));
gui.add(buttonPanel);
}
public Action getNewAction(){
return new AbstractAction("new",new JarImageIcon(getClass(),"32x32/new.png")){
public void actionPerformed(ActionEvent ev){
images.removeAll();
}
};
}
public Action getOpenAction(){
return new AbstractAction("open",new JarImageIcon(getClass(),"32x32/open.png")){
public void actionPerformed(ActionEvent ev){
int res=openfc.showOpenDialog(null);
properties.setProperty(fileOpenID,openfc.getCurrentDirectory().toString());
if(res==JFileChooser.APPROVE_OPTION){
try{
open(openfc.getSelectedFile().getPath());
}catch(Exception e){
JOptionPane.showMessageDialog(null, "Image Open Error : "+e.getMessage(), "Exception", JOptionPane.ERROR_MESSAGE);
}
}
}
};
}
public Action getSaveAction(){
return new AbstractAction("save",new JarImageIcon(getClass(),"32x32/save.png")){
public void actionPerformed(ActionEvent ev){
int res=savefc.showSaveDialog(null);
properties.setProperty(fileSaveID,savefc.getCurrentDirectory().toString());
if(res==JFileChooser.APPROVE_OPTION){
new Thread(){
public void run(){
try{
save(savefc.getSelectedFile().getPath());
}catch(Exception e){
JOptionPane.showMessageDialog(null, "Image Save Error : "+e.getMessage(), "Exception", JOptionPane.ERROR_MESSAGE);
}
}
}.start();
}
}
};
}
public Action getPrintAction(){
return new AbstractAction("",new JarImageIcon(getClass(),"32x32/print.png")){
public void actionPerformed(ActionEvent ev){
new Thread(){
public void run(){
Printer p=new Printer();
for(int i=0; i<images.getTabCount(); i++){
JScrollPane sp=(JScrollPane)images.getComponentAt(i);
ImagePanel ip=(ImagePanel)sp.getViewport().getView();
p.append(ip);
}
p.print();
}
}.start();
}
};
}
public Action getConvertAction(){
return new AbstractAction("<html><center><b>Colour</b><br><b>Reduction</b></center></html>"/*,new JarImageIcon(getClass(),"32x32/blackWhite.png")*/){
public void actionPerformed(ActionEvent ev){
convertImage();
}
};
}
public Action getRotateAction(){
return new AbstractAction("",new JarImageIcon(getClass(),"32x32/rotate.png")){
public void actionPerformed(ActionEvent ev){
JScrollPane sp=(JScrollPane)images.getSelectedComponent();
if(sp!=null){
ImagePanel ip=(ImagePanel)sp.getViewport().getView();
ip.rotate();
}
}
};
}
protected void addImage(String fn, BufferedImage img){
Object md=img.getProperty("iiometadata");
if((md!=Image.UndefinedProperty)&&(md!=null)&&(md instanceof IIOMetadata)){
// new MetadataReader().read((IIOMetadata)md);
}
System.out.println("Image.Width ="+img.getWidth());
System.out.println("Image.Height ="+img.getHeight());
ImagePanel ip=new ImagePanel();
ip.addPropertyChangeListener(this);
JScrollPane sp=new JScrollPane(ip);
sp.getVerticalScrollBar().setUnitIncrement(100);
sp.getHorizontalScrollBar().setUnitIncrement(100);
ip.setImage(img);
// images.addTab("image",sp);
images.addTab(fn,new TabCloseIcon(), sp);
images.setSelectedIndex(images.getTabCount()-1);
}
public void open(String filename)throws IOException{
long time=System.currentTimeMillis();
String ext=filename.substring(filename.lastIndexOf('.')+1);
Iterator readers=ImageIO.getImageReadersByFormatName(ext);
if(!readers.hasNext()){throw new IOException(getClass().getName()+".open:\n\tNo reader for format '"+ext+"' available.");}
ImageReader reader=(ImageReader)readers.next();
while(!reader.getClass().getName().startsWith("uk.co.mmscomputing")&&readers.hasNext()){// prefer our own reader
reader=(ImageReader)readers.next();
}
File f=new File(filename);
ImageInputStream iis=ImageIO.createImageInputStream(f);
try{
reader.setInput(iis,true);
try{
for(int i=0; true; i++){
IIOMetadata md=reader.getImageMetadata(i);
// if(md!=null){new MetadataReader().read(md);}
addImage(f.getName()+" "+i,reader.read(i));
}
}catch(IndexOutOfBoundsException ioobe){}
}catch(Error e){
System.out.println("9\b"+getClass().getName()+".open:\n\t"+e);
e.printStackTrace();
throw e;
}finally{
iis.close();
}
time=System.currentTimeMillis()-time;
System.out.println("Opened : "+filename);
System.out.println("Time used to load images : "+time);
}
private IIOImage getIIOImage(ImageWriter writer,ImageWriteParam iwp,BufferedImage image){
ImageTypeSpecifier it = ImageTypeSpecifier.createFromRenderedImage(image);
/*
try{
uk.co.mmscomputing.imageio.bmp.BMPMetadata md=(uk.co.mmscomputing.imageio.bmp.BMPMetadata)image.getProperty("iiometadata");
if(md!=null){
md.setXPixelsPerMeter(11812); // force 300 dpi for bmp images
md.setYPixelsPerMeter(11812); // works only with mmsc.bmp package
}
}catch(Exception e){}
*/
IIOMetadata md;
Object obj=image.getProperty("iiometadata"); // if image is a TwainBufferedImage get metadata
if((obj!=null)&&(obj instanceof IIOMetadata)){
md = (IIOMetadata)obj;
}else{
md = writer.getDefaultImageMetadata(it,iwp);
}
return new IIOImage(image,null,md);
}
public void save(String filename)throws IOException{
if(images.getTabCount()<=0){throw new IOException(getClass().getName()+".save:\n\tNo images available!");}
String ext=filename.substring(filename.lastIndexOf('.')+1);
Iterator writers=ImageIO.getImageWritersByFormatName(ext);
if(!writers.hasNext()){throw new IOException(getClass().getName()+".save:\n\tNo writer for format '"+ext+"' available.");}
ImageWriter writer=(ImageWriter)writers.next();
while(!writer.getClass().getName().startsWith("uk.co.mmscomputing")&&writers.hasNext()){// prefer our own writer
writer=(ImageWriter)writers.next();
}
ImageWriteParam iwp = writer.getDefaultWriteParam();
IIOParamController controller = iwp.getController();
if(controller!=null){controller.activate(iwp);}
long time=System.currentTimeMillis();
File file=new File(filename);
if(file.exists()){file.delete();}
ImageOutputStream ios=null;
try{
ios=ImageIO.createImageOutputStream(file);
writer.setOutput(ios);
if(writer.canWriteSequence()){ //i.e tiff,sff(fax)
writer.prepareWriteSequence(null);
for(int i=0;i<images.getTabCount();i++){
JScrollPane sp=(JScrollPane)images.getComponentAt(i);
ImagePanel ip=(ImagePanel)sp.getViewport().getView();
writer.writeToSequence(getIIOImage(writer,iwp,ip.getImage()),iwp);
}
writer.endWriteSequence();
}else{
JScrollPane sp=(JScrollPane)images.getComponentAt(0);
ImagePanel ip=(ImagePanel)sp.getViewport().getView();
writer.write(null,getIIOImage(writer,iwp,ip.getImage()),iwp);
for(int i=1; i<images.getTabCount(); i++){
if(writer.canInsertImage(i)){
sp=(JScrollPane)images.getComponentAt(i);
ip=(ImagePanel)sp.getViewport().getView();
writer.write(null,getIIOImage(writer,iwp,ip.getImage()),iwp);
}else{
throw new IOException("Image Writer cannot append image ["+i+"] ("+filename+")");
}
}
}
time=System.currentTimeMillis()-time;
System.out.println("Saved : "+filename);
System.out.println("3\bTime used to save images : "+time);
}finally{
if(ios!=null){ios.close();}
}
}
public void convertImage(){
new Thread(){
public void run(){
try{
ImageTypeConvertOpPanel itcop=new ImageTypeConvertOpPanel();
ImageTypeConvertOp itco=itcop.activate();
if(itco!=null){
for(int i=0; i<images.getTabCount(); i++){
JScrollPane sp=(JScrollPane)images.getComponentAt(i);
ImagePanel ip=(ImagePanel)sp.getViewport().getView();
BufferedImage image=itco.filter(ip.getImage());
ip.setImage(image);
ip.revalidate();ip.repaint();
String type="Unknown Type";
switch(image.getType()){
case BufferedImage.TYPE_BYTE_BINARY: type="Byte Binary"; break;
case BufferedImage.TYPE_BYTE_INDEXED: type="Byte Indexed";break;
}
ColorModel cm=image.getColorModel();
System.out.println("9\bConverted Images to:\n\ntype: "+type+"\nbpp: "+cm.getPixelSize());
}
}
}catch(Exception e){
System.out.println("9\b"+getClass().getName()+".convertImage:\n\t"+e);
e.printStackTrace();
}
}
}.start();
}
/*
public void convertToBWImage(){
for(int i=0; i<images.getTabCount(); i++){
JScrollPane sp=(JScrollPane)images.getComponentAt(i);
ImagePanel ip=(ImagePanel)sp.getViewport().getView();
BufferedImage original=ip.getImage();
BufferedImage image=new BufferedImage(original.getWidth(),original.getHeight(),BufferedImage.TYPE_BYTE_BINARY);
Graphics2D g=image.createGraphics();
AffineTransform t=new AffineTransform();
g.drawRenderedImage(original,t);
ip.setImage(image);
ip.revalidate();ip.repaint();
}
}
*/
public void propertyChange(final PropertyChangeEvent evt){
/*
String prop=evt.getPropertyName();
if(prop.equals("open")){
JTabbedPane tp=(JTabbedPane)getParent();
tp.setSelectedIndex(1);
new Thread(){
public void run(){
try{
open((String)evt.getNewValue());
}catch(Exception e){
JOptionPane.showMessageDialog(null, "Image Open Error : "+e.getMessage(), "Exception", JOptionPane.ERROR_MESSAGE);
}
}
}.start();
}else if(prop.equals("save")){
new Thread(){
public void run(){
try{
open((String)evt.getNewValue());
int res=savefc.showSaveDialog(null);
if(res==JFileChooser.APPROVE_OPTION){
save(savefc.getSelectedFile().getPath());
}
}catch(IOException ioe){
System.out.println("9\b"+ioe.getMessage());
}
}
}.start();
}
*/
}
static private class Printer extends Thread{
PrinterJob pj;
PageFormat pf;
Book bk;
public Printer(){
pj=PrinterJob.getPrinterJob();
pf = pj.defaultPage();
Paper p=pf.getPaper();
p.setImageableArea(0.0,0.0,p.getWidth(),p.getHeight());
pf.setPaper(p);
pf = pj.validatePage(pf);
bk=new Book();
}
public void append(ImagePanel image){
bk.append(image, pf);
}
public void print(){
pj.setPageable(bk);
if(pj.printDialog()){
try{
pj.print();
}catch (Exception e){
e.printStackTrace();
System.out.println("9\b"+getClass().getName()+".print:\n\t"+e.getMessage());
}
}
}
}
}