/*

Converts gifs und jpgs to PixelTexture Format (VRML)
Konvertiert gifs und jpgs ins PixelTexture Format (VRML)


# Image-to-PixelTexture   Version 1.0.1
# Created by Roland Praehofer  rp@memeticdesign.de
# Created on: August,27th      Last Modified on: September,11th 11:42
# URL:http://www.memeticdesign.de/rp/image2vrml/image2vrml_java.html

*/


import java.io.*;
import java.awt.*;
import java.awt.Toolkit;
import java.awt.image.*;
import java.net.*;
import java.net.MalformedURLException;


public class Image2vrml extends Frame implements Runnable{

  Toolkit tk;
  MediaTracker mtrack;
  Image  img;
  
  final int GRAY = 1;
  final int GRAY_WITH_ALPHA = 2;
  final int RGB = 3;
  final int RGB_WITH_ALPHA = 4;

  String theFile;
  String theDir;
  Thread runMe;
  

  public static void main(String[] args)
  {


    Image2vrml i2v = new Image2vrml();
    
  
  }
  
  public Image2vrml()
  
  {
   
    
     setLayout(null);

     String thePath = askForFilePath();
     if (thePath == "") System.exit(0);
     
     getImageFromFile(thePath);
     
     setSize(img.getWidth(this),img.getHeight(this));
     setVisible(true);     
     
     String vrml = img2pix(img);
     
     
     saveVrmlFile(vrml);
     
     System.exit(0);
     

  
  }
  
  public void run()
  
  {
  
       try{
       
            mtrack.waitForID(0);
       
       }catch(Exception e){ }
       
       repaint();
  
  }
  
  
  public String askForFilePath()
  
  {
  
     FileDialog fd = new FileDialog(this,"Choose an gif or jpg image !");
     fd.setMode(FileDialog.LOAD);
     fd.setVisible(true);
     theFile = fd.getFile();
     theDir = fd.getDirectory();
     if(theDir != null && theDir.length() != 0 && theFile != null && theFile.length() != 0){
     
          return (theDir+theFile);
     
     }else{
     
     return "";
     
     }
     
     
  
  }
  
  public void getImageFromFile(String path)
  
  {
  
     
     tk=Toolkit.getDefaultToolkit();
     img = tk.getImage(path);
     
     mtrack = new MediaTracker(this);
     mtrack.addImage(img,0);
     runMe = new Thread(this);
     runMe.start();
     
     while(!mtrack.checkAll()){
      try{
          runMe.sleep(1000);
       }catch(Exception e){}
     }
          
     runMe.stop();
     
     return ;
     
  
  }
  
  
  
  public void paint(Graphics g)
  
  {
  
  
       g.drawImage(img,0,0,this);
  
  
  }
  
  
  public String img2pix(Image img2convert){
  
      
      
      int width = img2convert.getWidth(this);
      int height = img2convert.getHeight(this);
      
      PixelGrabber pg = new PixelGrabber(img, 0, 0, width, height, true);  
      try
      {
       boolean worked = pg.grabPixels();
       if(!worked)
       {
         System.out.println("Pixels couldn't be grabbed !");
       }
      }catch(InterruptedException e){}
      
      int[] pixels = (int[]) pg.getPixels();
  

      
      // Java counts from upper left pixel, VRML from lower left pixel,
      // so we have to do a conversion
      
      int currentRow = height;
      int firstOfRow = 0;
      int index = 0;
      ColorModel cm = pg.getColorModel(); 
      
      int nrOfPixels = width*height;
      
      String red[] = new String [nrOfPixels];
      String  green[] = new String [nrOfPixels];
      String  blue[] = new String [nrOfPixels];
      String  alpha[] = new String [nrOfPixels];

      int r,g,b,a;
            
      boolean graytest = true; 
      boolean alphatest = false;
      int count = 0;
      
      for(int h=height;h>0;h--){
      
           currentRow -= 1; // 'index' of current line
           firstOfRow = currentRow * width; //index of first pixel of current row
           

                
           for(int w=0;w<width;w++){ // start with the last line of pixels
           
                index = firstOfRow + w; // index for pixels[]
                
                r = cm.getRed(pixels[index]);
                g = cm.getGreen(pixels[index]);
                b = cm.getBlue(pixels[index]);
                a = cm.getAlpha(pixels[index]);
                
                // if at least one pixel has different rgb values, it cannot be grayscale
                
                if((r!= g) ||(g != b)||(r!= b)) graytest = false;
                if(a != 255) alphatest = true;
                
                alpha[count]   = Integer.toHexString(a);
                red[count]      = Integer.toHexString(r);
                green[count]  = Integer.toHexString(g);
                blue[count]    = Integer.toHexString(b);              
                
                if(alpha[count].length() == 1) alpha[count] = "0"+alpha[count];
                if(red[count].length() == 1) red[count] = "0"+red[count];
                if(green[count].length() == 1) green[count] = "0"+green[count];
                if(blue[count].length() == 1) blue[count] = "0"+blue[count];   
                
                count++;
                             
           }
      }     
      
       // assemble the values for the different modes
       
      StringBuffer pixData = new StringBuffer();
      int mode = RGB;
      
       // grayscale
      
       if(graytest && !alphatest) {
           mode = GRAY;
           for(int i=0;i<nrOfPixels;i++){
          
               pixData.append("0x"+red[i]+"\n");
          
          }
       }
       
      // grayscale with alpha
      
       if(graytest && alphatest) {
           mode = GRAY_WITH_ALPHA;
           for(int i=0;i<nrOfPixels;i++){
          
               pixData.append("0x"+red[i]+alpha[i]+"\n");
          
          }
       }
       
      // rgb
      
       if(!graytest && !alphatest) {
           mode = RGB;
           for(int i=0;i<nrOfPixels;i++){
          
               pixData.append("0x"+red[i]+green[i]+blue[i]+"\n");
          
          }
       }
       
      // rgb with alpha
      
       if(!graytest && alphatest) {
           mode = RGB_WITH_ALPHA;
           for(int i=0;i<nrOfPixels;i++){
          
               pixData.append("0x"+red[i]+green[i]+blue[i]+alpha[i]+"\n");
          
          }
       }
   
      StringBuffer vrml = new StringBuffer(); 
      
      vrml.append("#VRML V2.0 utf8\n");
      vrml.append("Transform{ scale "+(float) width/100+" "+(float) height/100 +" 1  children[\nShape{geometry IndexedFaceSet{creaseAngle 3.14 coord Coordinate{ point[-.5 -.5 0,.5 -.5 0,.5 .5 0,-.5 .5 0, ] } coordIndex[0 1 2 -1, 2 3 0 -1]   } \nappearance Appearance{material Material{diffuseColor 1 1 1}texture ");
      vrml.append("\nPixelTexture{image "+width+" "+height+" "+mode+"\n"+pixData+"}");
      vrml.append("\n}}]}");
      
      
      return vrml.toString();
  
  }
  
  public void saveVrmlFile(String vstring)
  
  {
  
     try{  
       File outFile = new File(theDir,(theFile+".wrl"));
       FileWriter fw = new FileWriter(outFile);
       PrintWriter pw = new PrintWriter(fw);
       pw.print(vstring);
       pw.flush();
       pw.close();
     }catch(IOException e){
       System.out.println("Save Error !");
     }
  
  }

}