Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 2 of 2

Thread: Asynchronous Imaging Problem

  1. #1
    Junior Member
    Join Date
    Apr 2011
    Location
    Carbondale, IL
    Posts
    4
    My Mood
    Stressed
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Asynchronous Imaging Problem

    Hi. I've been in development of a simple GUI that converts image files into patterns usable within the popular game Minecraft.

    The image files are read in, the ImagePixelate class sections up the image, and then the ColorAlgorithm class finds the nearest color in the palette available for each section of the image.

    The problem is that after the first pixel in each section, the image reads in black pixels for the rest of the section. I assume that this is due to the image not loading completely. I've been using a MediaTracker to help with this, but to no avail. Can anyone help me fix this problem?

    import java.awt.*;
    import java.awt.Image;
    import javax.swing.*;
    import java.awt.event.*;
    import java.io.*;
    import javax.swing.border.*;
    import javax.imageio.ImageIO;
    import java.awt.image.*;
     
    //----------------------------------------------------------
    //  ColorAlgorithm() - The algorithm by which the program determines
    //                     the closest color for each section of the image.
    //  Author - Drew Murphy
    //  April 14, 2011
    //----------------------------------------------------------
     
    public class ColorAlgorithm {
     
      private Color colorReturned;  
      private byte result;
     
      public ColorAlgorithm(int[] pixels) {
     
        Color[] palette = {
          new Color(182,50,45), //red
          new Color(222,207,42), //yellow
          new Color(38,50,151), //blue
          new Color(53,74,23), //green
          new Color(0,0,0), //black
          new Color(255,255,255), //white
          new Color(81,48,26), //brown
          new Color(234,125,51), //orange
          new Color(41,121,154), //cyan
          new Color(125,48,193), //purple
          new Color(68,68,68), //gray
          new Color(142,168,223), //lightblue
          new Color(223,152,171), //pink
          new Color(61,200,49), //aquagreen
          new Color(192,76,203), //magenta
          new Color(155,162,162) //lightgray
        };
     
        int[] colorBin = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
     
        //--------------------------------------------------
        // Determines RGB values of each pixel in the array
        //--------------------------------------------------
        for (int i=0; i < pixels.length; i+=25) {
          int c = pixels[i];
          int redValue = (c & 0x00ff0000) >> 16;
          int greenValue = (c & 0x0000ff00) >> 8;
          int blueValue = c & 0x000000ff;
     
          Color colorPixel = new Color(redValue,greenValue,blueValue);
          result = findNearestColor(colorPixel, palette);
     
          colorBin[result] += 1;
     
        }
     
        int maxIndex = 0;
     
        //---------------------------------------
        // Finds the bin with the maximum amount
        //---------------------------------------
        for (int i = 0; i < colorBin.length; i++) {
          if (colorBin[i] >= colorBin[maxIndex])
            maxIndex = i;
        }
     
        colorReturned = palette[maxIndex];
      }
     
      public Color getColor() {
        return colorReturned;
      }
     
      //--------------------------------------------------------------------------------------------
      // Uses straight line minimum distance algorithm to determine the closest color in the palette
      //--------------------------------------------------------------------------------------------
      private static byte findNearestColor(Color color, Color[] palette) {
        int maxDistanceSquared = (255*255) + (255*255) + (255*255) + 1;
        byte bestIndex = 0;
        for (byte i = 0; i < palette.length; i++) {
            int Rdiff = color.getRed() - palette[i].getRed();
            int Gdiff = color.getGreen() - palette[i].getGreen();
            int Bdiff = color.getBlue() - palette[i].getBlue();
     
            int distanceSquared = (Rdiff*Rdiff) + (Gdiff*Gdiff) + (Bdiff*Bdiff);    
            if (distanceSquared < maxDistanceSquared) {
                maxDistanceSquared = distanceSquared;
                bestIndex = i;
            }
        }
        return bestIndex;
    }
     
    }

    import java.awt.*;
    import java.awt.Image;
    import javax.swing.*;
    import java.awt.event.*;
    import java.io.*;
    import javax.swing.border.*;
    import javax.imageio.ImageIO;
    import java.awt.image.*;
     
    //----------------------------------------------------------
    //  ImagePixelate() - Sections the image and feeds the pixels
    //                    from each section into the algorithm.
    //  Author - Drew Murphy
    //  April 14, 2011
    //----------------------------------------------------------
     
    public class ImagePixelate {
      private Image renderedImage; //image returned to PixelFrame
      private Color[][] colorSchematic; //schematic determined from calling ColorAlgorithm
     
      //----------------
      // Constructor
      //----------------
      public ImagePixelate(Image toRender) {
        int height = -1;
        int width = -1;
     
        //--------------------
        // MediaTracker call
        //--------------------
        JLabel testCase = new JLabel();
        MediaTracker tracker = new MediaTracker(testCase);
     
        tracker.addImage(toRender,1);
     
        try{
          tracker.waitForAll();
          height = toRender.getHeight(null);
          width = toRender.getWidth(null);
        } catch (InterruptedException e) {
        }
     
        renderedImage = toRender;
     
        //------------------------------------------------------------------------------------------
        // Determining the size of each block given the user specified width of the image in blocks
        //------------------------------------------------------------------------------------------
        float ratio = (float) width / (float) height;
     
        int numColumns = 24;
        float rowCalc = (float) numColumns / ratio;
        int numRows = (int) rowCalc;
     
        colorSchematic = new Color[numColumns][numRows];
     
        int blockWidth = width / numColumns;
        int blockHeight = blockWidth;
     
        //------------------------------------------------------------------------------------------------
        // Get the pixels of each block, and then use the algorithm to determine the closest palette color
        //------------------------------------------------------------------------------------------------
        for (int x = 0; x < numColumns; x++) {
          for (int y = 0; y < numRows; y++) {
            int[] pixels = new int[blockWidth*blockHeight];
            PixelGrabber grabber = new PixelGrabber(toRender, x*blockWidth, y*blockHeight,
                                            blockWidth, blockHeight, pixels, 0, blockWidth);
     
            try {
              grabber.grabPixels();
            } catch (InterruptedException e) {}
     
            ColorAlgorithm currentSection = new ColorAlgorithm(pixels);
            colorSchematic[x][y] = currentSection.getColor();
          }
        }
        System.out.println("Conversion complete.");
      }
     
      public Image getRenderedImage() {
        return renderedImage;
      }
     
    }

    import java.awt.*;
    import java.awt.Image;
    import javax.swing.*;
    import java.awt.event.*;
    import java.io.*;
    import javax.swing.border.*;
     
     
    //----------------------------------------------------------
    //  PixelFrame() - Sets up the GUI for PixelCraft.
    //  Author - Drew Murphy
    //  April 14, 2011
    //----------------------------------------------------------
    public class PixelFrame{
      private JTextArea fileSelected;
      private JLabel image;
     
      public PixelFrame() {
     
        JFrame frame = new JFrame ("Pixelcraft");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
        frame.setSize(1000,600);
     
        JPanel settings = new JPanel();
        JPanel images = new JPanel();
        JPanel window = new JPanel();
     
        JPanel chooseFile = new JPanel();
        JPanel updatePanel = new JPanel();
        JPanel preferences = new JPanel();
     
        //--------------
        // ChooseFile panel
        //--------------
        JButton browse = new JButton ("Browse");
        browse.setBorder(BorderFactory.createLineBorder(Color.black,1));
        browse.addActionListener(new FileListener());
     
        fileSelected = new JTextArea ("C:\\");
        fileSelected.setBorder(BorderFactory.createLineBorder(Color.black, 1));
        fileSelected.setPreferredSize(new Dimension(200,18));
     
        chooseFile.add(fileSelected);
        chooseFile.add(browse);
     
        //-------------------
        // Preferences panel
        //-------------------
        preferences.setLayout(new BoxLayout(preferences, BoxLayout.Y_AXIS));
        preferences.setPreferredSize(new Dimension(100,500));
     
        preferences.setBackground(Color.white);
        preferences.setBorder(BorderFactory.createLineBorder(Color.black,1));
     
        JCheckBox red = new JCheckBox("Red Wool",true);
        JCheckBox yellow = new JCheckBox("Yellow Wool",true);
        JCheckBox blue = new JCheckBox("Blue Wool",true);
        JCheckBox green = new JCheckBox("Green Wool",true);
        JCheckBox black = new JCheckBox("Black Wool",true);
        JCheckBox white = new JCheckBox("White Wool",true);
        JCheckBox brown = new JCheckBox("Brown Wool",true);
        JCheckBox orange = new JCheckBox("Orange Wool",true);
        JCheckBox cyan = new JCheckBox("Cyan Wool",true);
        JCheckBox purple = new JCheckBox("Purple Wool",true);
        JCheckBox gray = new JCheckBox("Gray Wool",true);
        JCheckBox lightblue = new JCheckBox("Light Blue Wool",true);
        JCheckBox pink = new JCheckBox("Pink Wool",true);
        JCheckBox aquagreen = new JCheckBox("Aqua Green Wool",true);
        JCheckBox magenta = new JCheckBox("Magenta Wool",true);
        JCheckBox lightgray = new JCheckBox("Light Gray Wool",true);
     
        red.setBackground(Color.white);
        yellow.setBackground(Color.white);
        blue.setBackground(Color.white);
        green.setBackground(Color.white);
        black.setBackground(Color.white);
        white.setBackground(Color.white);
        brown.setBackground(Color.white);
        orange.setBackground(Color.white);
        cyan.setBackground(Color.white);
        purple.setBackground(Color.white);
        gray.setBackground(Color.white);
        lightblue.setBackground(Color.white);
        pink.setBackground(Color.white);
        aquagreen.setBackground(Color.white);
        magenta.setBackground(Color.white);
        lightgray.setBackground(Color.white);
     
        preferences.add(red);
        preferences.add(yellow);
        preferences.add(blue);
        preferences.add(green);
        preferences.add(black);
        preferences.add(white);
        preferences.add(brown);
        preferences.add(orange);
        preferences.add(cyan);
        preferences.add(purple);
        preferences.add(gray);
        preferences.add(lightblue);
        preferences.add(pink);
        preferences.add(aquagreen);
        preferences.add(magenta);
        preferences.add(lightgray);
     
        //-------------
        // UpdatePanel
        //-------------
        updatePanel.setLayout(new BorderLayout());
     
        JLabel blockdescrip = new JLabel("Width in blocks: ");
        blockdescrip.setBorder(BorderFactory.createEmptyBorder(8,8,8,8));
        blockdescrip.setPreferredSize(new Dimension(150,25));
     
        JTextArea blockwidth = new JTextArea();
        blockwidth.setPreferredSize(new Dimension(50,20));
        blockwidth.setBorder(BorderFactory.createLineBorder(Color.black,1));
     
        JButton create = new JButton("Create image!");
        create.setBackground(Color.cyan);
        create.setPreferredSize(new Dimension(150,25));
        create.addActionListener(new ButtonListener());
     
        updatePanel.add(blockdescrip,BorderLayout.WEST);
        updatePanel.add(blockwidth,BorderLayout.CENTER);
        updatePanel.add(create,BorderLayout.EAST);
     
        //-----------------
        //  Nested Panels
        //-----------------
        settings.setLayout(new BorderLayout());
        settings.add(chooseFile,BorderLayout.NORTH);
        settings.add(preferences,BorderLayout.CENTER);
        settings.add(updatePanel,BorderLayout.SOUTH);
     
        images.setPreferredSize(new Dimension(800,600));
        images.setBorder(BorderFactory.createEmptyBorder(8,8,8,8));
     
        image= new JLabel();
        images.add(image);
     
        window.setLayout(new BorderLayout());
        window.add(settings,BorderLayout.WEST);
        window.add(images,BorderLayout.EAST);
     
        frame.add(window);
        frame.pack();
        frame.setVisible(true);
     
      }
     
      //---------------
      // File Selection
      //---------------
      private class FileListener implements ActionListener{
        public void actionPerformed (ActionEvent event) {
          JFileChooser choose = new JFileChooser();
          int status = choose.showOpenDialog(null);
     
          if (status != JFileChooser.APPROVE_OPTION)
            fileSelected.setText("No File Chosen");
          else {
            File file = choose.getSelectedFile();
            fileSelected.setText(file.getAbsolutePath());
          }
     
     
        }
      }
     
      //--------------------------------------------------------
      // Runs the programs main function of pixelating the image
      //--------------------------------------------------------
      private class ButtonListener implements ActionListener{
        public void actionPerformed(ActionEvent event) {
          String fileName = fileSelected.getText();
          Image resizedPicture = Toolkit.getDefaultToolkit().getImage(fileName);
          ImageIcon picture = new ImageIcon(fileName);
     
          JLabel test = new JLabel();
          MediaTracker tracker = new MediaTracker(test);
     
          //--------------------------------------------
          // Scale picture to fit on-screen, if necessary.
          //--------------------------------------------
     
          if (resizedPicture.getWidth(null) > 800 || resizedPicture.getHeight(null) > 600) {
            if (resizedPicture.getWidth(null) > 800) {
              float ratio = 800 / (float)resizedPicture.getWidth(null);       
              double width = 800.0;
              float height = (float)resizedPicture.getHeight(null) * ratio;        
              resizedPicture = resizedPicture.getScaledInstance((int)width,(int)height,Image.SCALE_SMOOTH);
            }
     
     
            if (resizedPicture.getHeight(null) > 600) {
              float ratio = 600 / (float)resizedPicture.getHeight(null);          
              double height = 600.0;
              float width = (float)resizedPicture.getWidth(null) * ratio;          
              resizedPicture = resizedPicture.getScaledInstance((int)width,(int)height,Image.SCALE_SMOOTH);
            }
          }
     
         //-------------------------------------------------------------------------------------   
         // Makes sure the image is loaded completely before invoking the ImagePixelate() class
         //-------------------------------------------------------------------------------------  
     
          tracker.addImage(resizedPicture, 0);
     
          try{
            tracker.waitForAll();
          } catch (InterruptedException e) {}  
     
          //--------------------------------------------------
          // ImagePixelate call - Program's main function
          //--------------------------------------------------
             ImagePixelate renderedPicture = new ImagePixelate(resizedPicture);
             Image renderedFinal = renderedPicture.getRenderedImage();
     
             picture.setImage(renderedFinal);
             image.setIcon(picture);
        }
      }
    }

    import java.awt.*;
    import javax.swing.*;
    import java.awt.event.*;
    import java.io.*;
    import javax.swing.border.*;
     
    //----------------------------------------------------------
    //  PixelCraft() - Simple class to call a PixelFrame object.
    //  Author - Drew Murphy
    //  April 14, 2011
    //----------------------------------------------------------
     
    public class PixelCraft extends PixelFrame {
      public static void main(String[] args) {
        PixelFrame frame = new PixelFrame();
      }
    }
    Last edited by dr3wmurphy; April 14th, 2011 at 01:57 AM.


  2. #2
    Junior Member
    Join Date
    Apr 2011
    Location
    Carbondale, IL
    Posts
    4
    My Mood
    Stressed
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Asynchronous Imaging Problem

    Well, after fiddling with it myself and deciding that BufferedImage loading is a pain, I simplified it, and this is my result. The program is still unfinished, but ImagePixelate and ColorAlgorithm now function as intended.