[Date Prev][Date Next][Thread Prev][Thread Next] - [Date Index][Thread Index][Author Index]

TMSat Java Image Viewer



Hi,

I have attached an updated version of the Java Image Viewer for TMSat to include 
support for the new TM50xxxx.IMI images.

These are a sequence of 141x141 8 bit gray scale images that I believe are taken 
using the wide angle camera.

The current image on the satellite (message b00 - TM504200.IMI) is a sequence of 
16 images (actually 15 as it looks like the last is just noise) taken over the 
southern part of the USA with New Orleans in the center.  The Gulf of Mexico and 
Florida can be easilty recognised. The images are rotating counter clockwise due 
to the rotation of the satellite.

Chris Jackson tells me that they can store upto 87 images,  so it will be 
interesting to see a sequence that is taken at intervals during half an orbit 
(the half in sunlight).

-- John Melton

Note:  I compiled and tested this with JDK1.2,  but it should work OK with JDK 
1.1.  Not sure how it will work with the Microsoft version of Java!


import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;

class ImageCanvas extends Canvas {

	Image[] images;
	int imageIndex=0;
	Movie movie;

	ImageCanvas(Image[] images) {
		this.images=images;
		imageIndex=0;
		if(images.length>1) {
			movie=new Movie(200);
			movie.start();
		}
	}

	public Dimension getMinimumSize() {
		return getPreferredSize();
	}

	public Dimension getPreferredSize() {
		int width=0;
		int height=0;
		if(images!=null) {
			width=images[0].getWidth(null);
			height=images[0].getHeight(null);
		}
		return new Dimension(width,height);
	}

	public void paint(Graphics g) {
		if(g==null) {
			return;
		}
		if(images!=null) {
			g.drawImage(images[imageIndex],0,0,null);
		}
	}

	void nextFrame() {
		imageIndex++;
		if(imageIndex>=images.length) {
			imageIndex=0;
		}
		paint(getGraphics());
	}

	class Movie extends Thread {
		
		int rate;

		Movie(int rate) {
			this.rate=rate;
		}

		public void run() {
			while(true) {
				try {
					sleep(rate);
					if(images.length>1) {
						nextFrame();
					} else {
						movie=null;
						break;
					}
				} catch (InterruptedException e) {
				}
			}
		}

	}

}

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;

//
// Load and display TMSat images
//

class TMImage extends Frame implements ActionListener {

	private Panel panel;
	private ScrollPane imagePane;
	private Image[] images=null;

	//
	// TMImage constructor
	//
	TMImage() {
		super("TMImage");
		setLayout(new GridBagLayout());
                MenuBar menuBar=new MenuBar();
                Menu menu=new Menu("File");
                MenuItem menuItem=new MenuItem("Open");
                menuItem.addActionListener(this);
                menu.add(menuItem);
                menuItem=new MenuItem("-");
                menu.add(menuItem);
                menuItem=new MenuItem("Exit");
                menuItem.addActionListener(this);
                menu.add(menuItem);
		menuBar.add(menu);
		setMenuBar(menuBar);
		panel=new Panel();
		panel.setLayout(new GridBagLayout());
                imagePane=new ScrollPane(ScrollPane.SCROLLBARS_AS_NEEDED);
                imagePane.setSize(new Dimension(510,510));
		constrain(panel,imagePane,
                                0,0,1,1,
                                GridBagConstraints.BOTH,GridBagConstraints.WEST,
				1.0,1.0,
                                0,0,0,0);
		constrain(this,panel,
                                0,0,1,1,
                                GridBagConstraints.BOTH,GridBagConstraints.WEST,
				1.0,1.0,
                                0,0,0,0);
	}

	//
	// handle ActionListener events (someone selects a menu choice)
	//
	public void actionPerformed(ActionEvent event) {
		String command=event.getActionCommand();
		if(command.equals("Open")) {
			try {
				FileDialog fd=new FileDialog(this,"Open TMSat Image", FileDialog.LOAD);
				fd.show();
				String filename=fd.getFile();
				if(filename!=null) {
					load(fd.getDirectory()+fd.getFile());
				}
			} catch (IOException e) {
				System.err.println("Error loading image file: "+e.getMessage());
			}
		} else if(command.equals("Exit")) {
			System.exit(0);
		}
	}

	//
	// load an image - the type and dimensions are based on the file name
	//
	private void load(String fileName) throws IOException {
		File file=new File(fileName);
		if(file.exists()) {
			BufferedInputStream s=new BufferedInputStream(new FileInputStream(file));
			String uFileName=file.getName().toUpperCase();
			if(uFileName.startsWith("TM00")) {
				s.skip(400);
				images=new Image[1];
				images[0]=loadNonInterlacedImage(s,611,576);
			} else if(uFileName.startsWith("TM01")) {
				images=new Image[1];
				images[0]=loadInterlacedImage(s,141,156);
			} else if(uFileName.startsWith("TM10")) {
				images=new Image[1];
				images[0]=loadInterlacedImage(s,1020,1020);
			} else if(uFileName.startsWith("TM20")) {
				images=new Image[1];
				images[0]=loadInterlacedImage(s,1020,1020);
			} else if(uFileName.startsWith("TM30")) {
				images=new Image[1];
				images[0]=loadInterlacedImage(s,1020,1020);
			} else if(uFileName.startsWith("TM40")) {
				loadVideo(s,382,274);
			} else if(uFileName.startsWith("TM50")) {
				loadVideo(s,file.length(),141,141);
			} else {
				System.err.println("Cannot determine format of: "+fileName);
			}
			s.close();
			if(images!=null) {
				Dimension d=imagePane.getSize();
				panel.remove(imagePane);
                		imagePane=new ScrollPane(ScrollPane.SCROLLBARS_AS_NEEDED);
             			imagePane.setSize(d);
				ImageCanvas imageCanvas=new ImageCanvas(images);
				imagePane.add(imageCanvas);
				constrain(panel,imagePane,
                              		0,0,1,1,
                                	GridBagConstraints.BOTH,GridBagConstraints.WEST,
					1.0,1.0,
                                	0,0,0,0);
				imagePane.validate();
				imagePane.getVAdjustable().setUnitIncrement(50);
				imagePane.getHAdjustable().setUnitIncrement(50);
				setTitle(file.getName()+" ("+images[0].getWidth(null)+"x"+images[0].getHeight(null)+") "+images.length+" images");
			}
		} else {
			System.err.println("Cannot find file: "+fileName);
		}
	}

	//
	// Wide Angle Image is stored as a non-interlaced image;
	//
	private Image loadNonInterlacedImage(BufferedInputStream s,int width,int height) throws IOException {
		int size=width*height;
		byte[] buffer=new byte[size];
		int bytes=0;
		bytes+=s.read(buffer,bytes,size-bytes);
		int[] pixels=new int[size];
		int i=0;
		int rowOffset=0;
		for(int r=0;r<height;r++) {
			if((r%2)==0) {
				rowOffset=(r/2)*width;
			} else {
				rowOffset=(r/2)*width;
			}
			for(int c=0;c<width;c++) {
				int pixel=buffer[rowOffset+c];
				pixels[i]=(255<<24)|(pixel<<16)|(pixel<<8)|pixel;
				i++;
			}
		}
		MemoryImageSource m=new MemoryImageSource(width,height,pixels,0,width);
		return Toolkit.getDefaultToolkit().createImage(m);
	}

	//
	// Narrow Angle Images and Thumbprint images are stored as an interlaced image;
	//
	private Image loadInterlacedImage(BufferedInputStream s,int width,int height) throws IOException {
		int size=width*height;
		byte[] buffer=new byte[size];
		int bytes=0;
		bytes+=s.read(buffer,bytes,size-bytes);
		int[] pixels=new int[size];
		for(int i=0;i<size;i++) {
			int pixel=buffer[i]&0xFF;
			pixels[i]=(255<<24)|(pixel<<16)|(pixel<<8)|pixel;
		}
		MemoryImageSource m=new MemoryImageSource(width,height,pixels,0,width);
		return Toolkit.getDefaultToolkit().createImage(m);
	}

	//
	// load a video image
	//
	private void loadVideo(BufferedInputStream s,int width,int height) throws IOException {
		images=new Image[3];
		s.skip(29123);
		images[0]=loadInterlacedImage(s,width,height);
		s.skip(28471);
		images[1]=loadInterlacedImage(s,width,height);
		s.skip(30436);
		images[2]=loadInterlacedImage(s,width,height);
	}

	private void loadVideo(BufferedInputStream s,long length,int width,int height) throws IOException {
		int imageCount=(int)length/(width*height);
		images=new Image[imageCount];
		for(int i=0;i<imageCount;i++) {
			images[i]=loadInterlacedImage(s,width,height);
		}
	}

	//
	// GridBagLayout constraints
	//
	private void constrain(Container container,Component component,
					int grid_x,int grid_y,
					int grid_width,int grid_height,
					int fill,int anchor,
					double weight_x,double weight_y,
					int top,int left,int bottom,int right ) {
		GridBagConstraints c=new GridBagConstraints( );
		c.gridx=grid_x;
		c.gridy=grid_y;
		c.gridwidth=grid_width;
		c.gridheight=grid_height;
		c.fill=fill;
		c.anchor=anchor;
		c.weightx=weight_x;
		c.weighty=weight_y;
		c.ipadx=0;
		c.ipady=0;
		c.insets=new Insets( top, left, bottom, right );
		((GridBagLayout)container.getLayout()).setConstraints( component,c );
		container.add( component );
	}

	//
	// it all starts here ...
	//
	public static void main(String[] args) {
		TMImage tmimage=new TMImage();
		tmimage.pack();
		tmimage.setVisible(true);
		if(args.length==1) {
			try {
				tmimage.load(args[0]);
			} catch (IOException e) {
				System.err.println("Error loading image file: "+e.getMessage());
			}
		}
	}

}



AMSAT Top AMSAT Home