2014-09-03 109 views
-2

我在加载的图像上收到NullPointerException。然而,当我使用JFrame渲染图像时,一切都很有效,我的目标是将每个像素加载到包含该像素的RBG颜色的ArrayList中。当我尝试使用getRGB(x,y)时,我收到一个NullPoint异常。我在代码的注释中标记了发生错误的地方。我将加载我的代码,感谢您的时间和帮助!LoadedImage上的Java BufferedImage空指针异常

public static void populateMapNode(BufferedImage image) 
    { 
     int width = image.getWidth(); 
     int height = image.getHeight(); 
     int pixel; 
     int i = 0, j= 0; 
     System.out.println("width = " + width); 
     System.out.println("height = " + height); 
     pixel = image.getRGB(j, i); //error occurs here 
     System.out.println("pixel = " + pixel); 
     MapNodes.add(new MapNode(new ArrayList<MapNode>(), new MapNode(), j, i, pixel, 0, 0, 0, 0, null)); 
     System.out.println("do i get here?"); 
     for (i = 0; i < height; i++) { 
      for (j = 0; j < width; j++) { 
       pixel = image.getRGB(j, i); 
       MapNodes.add(new MapNode(MapNode.neighbors, MapNode.neighbors.get(j-1), j, i, pixel, 0, 0, 0, 0, null)); 
      } 
      } 
    } 

    public static void loadMap() //if I just go to the JFrame the picture loads. 
    { 
     //Util.loadImage("AntWorld.png", null); 
     BufferedImage antMap = Util.loadImage("AntWorld.png", new Container()); 
     populateMapNode(antMap); 
     JFrame frame = new JFrame(); 
     frame.getContentPane().setLayout(new FlowLayout()); 
     frame.getContentPane().add(new JLabel(new ImageIcon(antMap))); 
     frame.pack(); 
     frame.setVisible(true); 
     //System.out.println(Util.manhattanDistance(MapNode.x, MapNode.y, MapNode.parent.x, MapNode.parent.y)); 
    } 

public static void main(String[] args) 
{ 
    loadMap(); 
} 

/*辅助类的Util对的LoadImage */

import java.awt.Container; 
import java.awt.MediaTracker; 
import java.awt.image.BufferedImage; 
import java.net.URL; 

import javax.imageio.ImageIO; 

public class Util 
{ 
    /** 
    * Loads a image file with the given path into a new bufferedImage. Blocks 
    * until the image has finished loading. widit is the component on which the 
    * images will eventually be drawn. 
    * 
    * @return A buffered image containing the loaded image. 
    */ 
    public static BufferedImage loadImage(String imagePath, Container widgit) 
    { 
    if (imagePath == null) return null; 

    if (widgit == null) 
    { 
     widgit = new Container(); 
    } 

    // Create a MediaTracker instance, to montior loading of images 
    MediaTracker tracker = new MediaTracker(widgit); 

    BufferedImage loadedImage = null; 
    URL fileURL = null; 

    try 
    { // System.out.println("imagePath="+imagePath); 

     imagePath = "resources/" + imagePath; 
     fileURL = new URL("file:" + imagePath); 

     loadedImage = ImageIO.read(fileURL); 

     // Register it with media tracker 
     tracker.addImage(loadedImage, 1); 
     tracker.waitForAll(); 
    } 
    catch (Exception e) 
    { 
     System.out.println("Cannot Open image: " + imagePath); 
     e.printStackTrace(); 
     System.exit(0); 
    } 
    return loadedImage; 
    } 

/****************堆栈跟踪*** ************************/

Exception in thread "main" java.lang.NullPointerException 
    at custom.MapNode.<init>(MapNode.java:32) 
    at custom.Demo.populateMapNode(Demo.java:56) 
    at custom.Demo.loadMap(Demo.java:72) 
    at custom.Demo.main(Demo.java:91) 

/*************** MapNode ********** ***********************/

package custom; 

import java.util.*; 
import java.io.*; 

public class MapNode implements Comparable <MapNode> 
{ 
    public static List<MapNode> neighbors = new ArrayList<MapNode>(); //Used for creating a path for an ant to follow 
    public static MapNode parent = null; 
    public static int x, y; //x and y coordinates for each map node (i.e. pixel) 
    private int pixelWeight; //the weight or cost of each pixel based off it's color 
          //this can also be modified to contain the color of food or water 
    private int hCost; // the heuristic cost from this node to another 
    public int gCost; // determines which node has a smaller weight based off the pixelWeight 
    private int fCost; 
    private int rCost; 
    private boolean isOccupied; //determines whether or not the node is occupied by food/ant/water/sea/nest 

    public MapNode(Object object, Object object2, int j, int i, int rgb, int k, //These match up to corresponding variables listed above. 
      int l, int m, int n, Object object3) 
    { 
     MapNode.neighbors = (List<MapNode>) object; 

     this.parent = (MapNode) object2; 
     this.x = j; 
     this.y = i; 
     this.pixelWeight = rgb; 
     this.hCost = k; 
     this.gCost = l; 
     this.fCost = m; 
     this.rCost = n; 
     this.isOccupied = (boolean) object3; 
     // TODO Auto-generated constructor stub 
    } 
    public MapNode() { 
     // TODO Auto-generated constructor stub 
    } 
    public MapNode(int x, int y) { 
     this.x = x; 
     this.y = y; 
     // TODO Auto-generated constructor stub 
    } 
    /* getter and setter land starts here */ 
    /* getter then setter/variable */ 
    public int getPixelWeight(){return pixelWeight;} 
    public void setPixelWeight(int pixelWeight){this.pixelWeight = pixelWeight;} 

    public int getHCost(){return hCost;} 
    public void setHCost(int hCost){this.hCost = hCost;} 

    public int getFCost(){return fCost;} 
    public void setFCost(int fCost){this.fCost = fCost;} 

    public int getRCost(){return rCost;} 
    public void setRCost(int rCost){this.rCost = rCost;} 

    public boolean getIsOccupied(){return isOccupied;} 
    public void setIsOccupied(boolean isOccupied){this.isOccupied = isOccupied;} 

    /* end of getter and setter land */ 

    private int setHCost(MapNode end){return Math.abs(this.x - end.x) + Math.abs(this.y - end.y);} //finds heuristic cost from current node to destination 

    private int setGCost(int prevGCost, int prevValue) 
    { 
     if (prevValue > pixelWeight) return 1; 
     if (prevValue < pixelWeight) return 2; 
     return 1; 
    } 

    private int setRCost() 
    { 
     return 0; 
    } 

    public void setCosts(MapNode end, int prevGCost, int prevValue) 
    { 
     this.hCost = setHCost(end); 
     this.gCost = setGCost(prevGCost, prevValue); 
     this.rCost = setRCost(); 
     this.fCost = this.hCost + this.gCost + this.rCost; 
    } 

    public boolean isPassable() //this needs to modified to determine multiple forms of occupiedness descibed in variable 
    { 
     if (this.pixelWeight > 255) return false; 
     return true; 
    } 

    public boolean isAbove(MapNode a) //determines open nodes above the ant(or will this be a pixel?) 
    { 
     return (a.y - this.y == -1) && (a.x == this.x); 
    } 

    public boolean isBelow(MapNode a) //determines open nodes below the ant(or will this be a pixel?) 
    { 
     return (a.y - this.y == 1) && (a.x == this.x); 
    } 

    public boolean isLeft(MapNode a) 
    { 
     return (a.x - this.x == -1) && (a.y == this.y); //determines open nodes left of the ant(or will this be a pixel?) 
    } 

    public boolean isRight(MapNode a) //determines open nodes right of the ant(or will this be a pixel?) 
    { 
     return (a.x - this.x == 1) && (a.y == this.y); 
    } 

    public boolean isNE(MapNode a) //determines open nodes northeast of the ant(or will this be a pixel?) 
    { 
     return (a.x - this.x == 1) && (a.y - this.y == -1); 
    } 

    public boolean isSE(MapNode a) //determines open nodes southeast of the ant(or will this be a pixel?) 
    { 
     return (a.x - this.x == 1) && (a.y - this.y == 1); 
    } 

    public boolean isNW(MapNode a) //determines open nodes northwest of the ant(or will this be a pixel?) 
    { 
     return (a.x - this.x == -1) && (a.y - this.y == -1); 
    } 

    public boolean isSW(MapNode a) //determines open nodes southwest of the ant(or will this be a pixel?) 
    { 
     return (a.x - this.x == -1) && (a.y - this.y == 1); 
    } 

    public void SetNeighbors(List<MapNode> nodes) //determines the neighbors of the current MapNode, 
    {            //if MapNode is not passible then the node is not added to the neightbors list 
     int count = 0; 
     for (MapNode n : nodes) 
     { 
      if (n.isPassable()) 
      { 
       if (isAbove(n) || isBelow(n) || isLeft(n) || isRight(n) || 
        isNE(n) || isSE(n) || isNW(n) || isSW(n)) 
       { 
        count++; 
        this.neighbors.add(n); 
       } 
      } 
      if (count == 8) break; //8 directional nodes to look at 
     } 
    } 

    /* http://stackoverflow.com/questions/15175109/equals-method-in-java */ 
    @Override 
    public boolean equals(Object o) 
    { 
     if (!(o instanceof MapNode)) return false; 
     if (this.x == ((MapNode) o).x && this.y == ((MapNode) o).y) return true; 
     return false; 
    } 

    /* http://docs.oracle.com/javase/tutorial/collections/interfaces/order.html */ 
    public static Comparator<MapNode> CompareNodes = new Comparator<MapNode>() 
    { 
     @Override 
     public int compare(MapNode a, MapNode b) 
     { 
      // return (a.fCost > b.fCost ? 1 : (a.fCost == b.fCost ? 0 : 1)); 
      if (a.fCost > b.fCost) return +1; 
      else if (a.fCost < b.fCost) return -1; 
      else return 0; 
     } 
    }; 

    @Override 
    public int compareTo(MapNode o) { 
     // TODO Auto-generated method stub 
     return 0; 
    } 

} 
+1

当您使用'ImageIO'时,不需要使用'MediaTracker'。 'ImageIO'在图像完全实现之前不会返回(如果无法加载,将抛出'IOException' – MadProgrammer 2014-09-03 01:40:10

+0

'pixel = image.getRGB(j,i);'in'populateMapNode''不能因为堆栈跟踪清楚地表明'MapNode'构造函数(第32行)是错误点... – MadProgrammer 2014-09-03 01:41:15

+0

鉴于您发布的堆栈跟踪,错误位于MapNode的构造函数中,其源是没有给出,并发生在你指出发生错误的地方下面两行,我甚至不认为它与图像像素有关。你可以发布MapNode的源码吗? – 2014-09-03 01:41:24

回答

0

好了,你构造器MapNode与...

MapNodes.add(new MapNode(new ArrayList<MapNode>(), new MapNode(), j, i, pixel, 0, 0, 0, 0, null)); 

而且那么你在构造函数中做到这一点...

this.isOccupied = (boolean) object3; 

object3是构造函数的最后一个参数,对此您传递null

new MapNode(
    new ArrayList<MapNode>(), 
    new MapNode(), 
    j, 
    i, 
    pixel, 
    0, 
    0, 
    0, 
    0, 
    null // Look ma, I'm null!! 
)