我在完成任务时遇到了一些困难。我会发表课程并解释。
import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;
import java.text.*;
/**
* A class that represents a picture. This class inherits from
* SimplePicture and allows the student to add functionality to
* the Picture class.
*
* Copyright Georgia Institute of Technology 2004-2005
* @author Barbara Ericson ericson@cc.gatech.edu
*/
public class Picture extends SimplePicture
{
///////////////////// constructors //////////////////////////////////
/**
* Constructor that takes no arguments
*/
public Picture ()
{
/* not needed but use it to show students the implicit call to super()
* child constructors always call a parent constructor
*/
super();
}
/**
* Constructor that takes a file name and creates the picture
* @param fileName the name of the file to create the picture from
*/
public Picture(String fileName)
{
// let the parent class handle this fileName
super(fileName);
}
/**
* Constructor that takes the width and height
* @param width the width of the desired picture
* @param height the height of the desired picture
*/
public Picture(int width, int height)
{
// let the parent class handle this width and height
super(width,height);
}
/**
* Constructor that takes a picture and creates a
* copy of that picture
*/
public Picture(Picture copyPicture)
{
// let the parent class do the copy
super(copyPicture);
}
////////////////////// methods ///////////////////////////////////////
/**
* Method to return a string with information about this picture.
* @return a string with information about the picture such as fileName,
* height and width.
*/
public String toString()
{
String output = "Picture, filename " + getFileName() +
" height " + getHeight()
+ " width " + getWidth();
return output;
}
/**
* Modified version of method from page 154 of the textbook for copying pictures
*/
public void copyPictureTo(Picture sourcePicture, int xStart, int yStart)
{
Pixel sourcePixel = null;
Pixel targetPixel = null;
//loop through the columns
try{
for (int sourceX = 0, targetX = xStart;
sourceX < sourcePicture.getWidth();
sourceX++, targetX++)
{
//loop through the rows
for (int sourceY = 0,
targetY = yStart;
sourceY < sourcePicture.getHeight();
sourceY++, targetY++)
{
sourcePixel = sourcePicture.getPixel(sourceX,sourceY);
targetPixel = this.getPixel(targetX,targetY);
targetPixel.setColor(sourcePixel.getColor());
}
}
}catch(IndexOutOfBoundsException ex){System.out.println("Either xStart or yStart is out of bounds");System.exit(0);}
}
//morphStage() method is located here.
public void morphStage(Picture startPicture, Picture endPicture, int numStages, int k)
{
Pixel[] pixelArrayStart = startPicture.getPixels();
Pixel[] pixelArrayEnd = endPicture.getPixels();
Pixel pixelObjEnd = null;
Pixel pixelObjStart = null;
Pixel pixelObjNew = null;
//Colour values for starting picture.
int startingRedValue = 0;
int startingGreenValue = 0;
int startingBlueValue = 0;
//Colour values for ending picture.
int endRedValue = 0;
int endGreenValue = 0;
int endBlueValue = 0;
//Colour values for intermediate pictures.
int redValue = 0;
int greenValue = 0;
int blueValue = 0;
//Loops through each entry int he first array, getting the RGB values
for (int i = 0; i < pixelArrayStart.length; i++)
{
//Loops through each entry in the second array, getting the RGB values
{
for (int j = 0; j < pixelArrayEnd.length; j++)
{
pixelObjEnd = pixelArrayEnd[j];
endRedValue = pixelObjEnd.getRed();
endGreenValue = pixelObjEnd.getGreen();
endBlueValue = pixelObjEnd.getBlue();
pixelObjStart = pixelArrayStart[i];
startingRedValue = pixelObjStart.getRed();
startingGreenValue = pixelObjStart.getGreen();
startingBlueValue = pixelObjStart.getBlue();
redValue = startingRedValue +((endRedValue - startingRedValue)/(numStages + 1))*k;
greenValue = startingGreenValue +((endGreenValue - startingGreenValue)/(numStages + 1))*k;
blueValue = startingBlueValue +((endBlueValue - startingBlueValue)/(numStages + 1))*k;
pixelObjNew.setRed(redValue);
pixelObjNew.setGreen(greenValue);
pixelObjNew.setBlue(blueValue);
}
}
}
}
}
// end of class Picture, put all new methods before this
想法是使用等式创建一系列中间图片,redValue = startingRedValue +((endRedValue - startingRedValue)/(numStages + 1))* k。
我不确定我是否正确编写代码,但想法是为第一张图片创建像素数组,获取RGB值,为第二张图片创建像素数组,获取RGB通过使用等式设置每个RGB值,然后创建一个新像素pixelObjNew。
代码编译得很好,但是当我尝试用两张图片运行它时,会出现错误。 (注意:TestMorphing是我为测试编写的类)
java.lang.NullPointerException
at Picture.morphStage(Picture.java:149)
at TestMorphing.main(TestMorphing.java:19)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:272)
这是对计算机科学课程的介绍,顺便说一句。
非常感谢!
编辑:这是像素类。
import java.awt.Color;
/**
* Class that references a pixel in a picture. A pixel has an x and y
* location in a picture. A pixel knows how to get and set the red,
* green, blue, and alpha values in the picture. A pixel also knows
* how to get and set the color using a Color object.
*
* Copyright Georgia Institute of Technology 2004
* @author Barb Ericson ericson@cc.gatech.edu
*/
public class Pixel
{
////////////////////////// fields ///////////////////////////////////
/** the digital picture this pixel belongs to */
private DigitalPicture picture;
/** the x location of this pixel in the picture (0,0) is top left */
private int x;
/** the y location of this pixel in the picture (0,0) is top left */
private int y;
////////////////////// constructors /////////////////////////////////
/**
* A constructor that take the x and y location for the pixel and
* the picture the pixel is coming from
* @param picture the picture that the pixel is in
* @param x the x location of the pixel in the picture
* @param y the y location of the pixel in the picture
*/
public Pixel(DigitalPicture picture, int x, int y)
{
// set the picture
this.picture = picture;
// set the x location
this.x = x;
// set the y location
this.y = y;
}
///////////////////////// methods //////////////////////////////
/**
* Method to get the x location of this pixel.
* @return the x location of the pixel in the picture
*/
public int getX() { return x; }
/**
* Method to get the y location of this pixel.
* @return the y location of the pixel in the picture
*/
public int getY() { return y; }
/**
* Method to get the amount of alpha (transparency) at this pixel.
* It will be from 0-255.
* @return the amount of alpha (transparency)
*/
public int getAlpha() {
/* get the value at the location from the picture as a 32 bit int
* with alpha, red, green, blue each taking 8 bits from left to right
*/
int value = picture.getBasicPixel(x,y);
// get the alpha value (starts at 25 so shift right 24)
// then and it with all 1's for the first 8 bits to keep
// end up with from 0 to 255
int alpha = (value >> 24) & 0xff;
return alpha;
}
/**
* Method to get the amount of red at this pixel. It will be
* from 0-255 with 0 being no red and 255 being as much red as
* you can have.
* @return the amount of red from 0 for none to 255 for max
*/
public int getRed() {
/* get the value at the location from the picture as a 32 bit int
* with alpha, red, green, blue each taking 8 bits from left to right
*/
int value = picture.getBasicPixel(x,y);
// get the red value (starts at 17 so shift right 16)
// then and it with all 1's for the first 8 bits to keep
// end up with from 0 to 255
int red = (value >> 16) & 0xff;
return red;
}
/**
* Method to get the red value from a pixel represented as an int
* @param value the color value as an int
* @return the amount of red
*/
public static int getRed(int value)
{
int red = (value >> 16) & 0xff;
return red;
}
/**
* Method to get the amount of green at this pixel. It will be
* from 0-255 with 0 being no green and 255 being as much green as
* you can have.
* @return the amount of green from 0 for none to 255 for max
*/
public int getGreen() {
/* get the value at the location from the picture as a 32 bit int
* with alpha, red, green, blue each taking 8 bits from left to right
*/
int value = picture.getBasicPixel(x,y);
// get the green value (starts at 9 so shift right 8)
int green = (value >> 8) & 0xff;
return green;
}
/**
* Method to get the green value from a pixel represented as an int
* @param value the color value as an int
* @return the amount of green
*/
public static int getGreen(int value)
{
int green = (value >> 8) & 0xff;
return green;
}
/**
* Method to get the amount of blue at this pixel. It will be
* from 0-255 with 0 being no blue and 255 being as much blue as
* you can have.
* @return the amount of blue from 0 for none to 255 for max
*/
public int getBlue() {
/* get the value at the location from the picture as a 32 bit int
* with alpha, red, green, blue each taking 8 bits from left to right
*/
int value = picture.getBasicPixel(x,y);
// get the blue value (starts at 0 so no shift required)
int blue = value & 0xff;
return blue;
}
/**
* Method to get the blue value from a pixel represented as an int
* @param value the color value as an int
* @return the amount of blue
*/
public static int getBlue(int value)
{
int blue = value & 0xff;
return blue;
}
/**
* Method to get a color object that represents the color at this pixel.
* @return a color object that represents the pixel color
*/
public Color getColor()
{
/* get the value at the location from the picture as a 32 bit int
* with alpha, red, green, blue each taking 8 bits from left to right
*/
int value = picture.getBasicPixel(x,y);
// get the red value (starts at 17 so shift right 16)
// then and it with all 1's for the first 8 bits to keep
// end up with from 0 to 255
int red = (value >> 16) & 0xff;
// get the green value (starts at 9 so shift right 8)
int green = (value >> 8) & 0xff;
// get the blue value (starts at 0 so no shift required)
int blue = value & 0xff;
return new Color(red,green,blue);
}
/**
* Method to set the pixel color to the passed in color object.
* @param newColor the new color to use
*/
public void setColor(Color newColor)
{
// set the red, green, and blue values
int red = newColor.getRed();
int green = newColor.getGreen();
int blue = newColor.getBlue();
// update the associated picture
updatePicture(this.getAlpha(),red,green,blue);
}
/**
* Method to update the picture based on the passed color
* values for this pixel
* @param alpha the alpha (transparency) at this pixel
* @param red the red value for the color at this pixel
* @param green the green value for the color at this pixel
* @param blue the blue value for the color at this pixel
*/
public void updatePicture(int alpha, int red, int green, int blue)
{
// create a 32 bit int with alpha, red, green blue from left to right
int value = (alpha << 24) + (red << 16) + (green << 8) + blue;
// update the picture with the int value
picture.setBasicPixel(x,y,value);
}
/**
* Method to correct a color value to be within 0 and 255
* @param the value to use
* @return a value within 0 and 255
*/
private static int correctValue(int value)
{
if (value < 0)
value = 0;
if (value > 255)
value = 255;
return value;
}
/**
* Method to set the red to a new red value
* @param value the new value to use
*/
public void setRed(int value)
{
// set the red value to the corrected value
int red = correctValue(value);
// update the pixel value in the picture
updatePicture(getAlpha(), red, getGreen(), getBlue());
}
/**
* Method to set the green to a new green value
* @param value the value to use
*/
public void setGreen(int value)
{
// set the green value to the corrected value
int green = correctValue(value);
// update the pixel value in the picture
updatePicture(getAlpha(), getRed(), green, getBlue());
}
/**
* Method to set the blue to a new blue value
* @param value the new value to use
*/
public void setBlue(int value)
{
// set the blue value to the corrected value
int blue = correctValue(value);
// update the pixel value in the picture
updatePicture(getAlpha(), getRed(), getGreen(), blue);
}
/**
* Method to set the alpha (transparency) to a new alpha value
* @param value the new value to use
*/
public void setAlpha(int value)
{
// make sure that the alpha is from 0 to 255
int alpha = correctValue(value);
// update the associated picture
updatePicture(alpha, getRed(), getGreen(), getBlue());
}
/**
* Method to get the distance between this pixel's color and the passed color
* @param testColor the color to compare to
* @return the distance between this pixel's color and the passed color
*/
public double colorDistance(Color testColor)
{
double redDistance = this.getRed() - testColor.getRed();
double greenDistance = this.getGreen() - testColor.getGreen();
double blueDistance = this.getBlue() - testColor.getBlue();
double distance = Math.sqrt(redDistance * redDistance +
greenDistance * greenDistance +
blueDistance * blueDistance);
return distance;
}
/**
* Method to compute the color distances between two color objects
* @param color1 a color object
* @param color2 a color object
* @return the distance between the two colors
*/
public static double colorDistance(Color color1,Color color2)
{
double redDistance = color1.getRed() - color2.getRed();
double greenDistance = color1.getGreen() - color2.getGreen();
double blueDistance = color1.getBlue() - color2.getBlue();
double distance = Math.sqrt(redDistance * redDistance +
greenDistance * greenDistance +
blueDistance * blueDistance);
return distance;
}
/**
* Method to get the average of the colors of this pixel
* @return the average of the red, green, and blue values
*/
public double getAverage()
{
double average = (getRed() + getGreen() + getBlue()) / 3.0;
return average;
}
/**
* Method to return a string with information about this pixel
* @return a string with information about this pixel
*/
public String toString()
{
return "Pixel red=" + getRed() + " green=" + getGreen() +
" blue=" + getBlue();
}
}
答案 0 :(得分:1)
您的问题似乎源于您尝试使用Pixel类型变量pixelObjNew,而它仍为null。您似乎正在使用第三方库,可能是您的Ga Tech类代码的一部分,而且我们不了解此代码将限制我们的能力帮助,但话虽如此,最重要的是您应首先分配有效在尝试使用它之前,实例化该变量的对象。这可能就像调用一样简单,
pixelObjNew = new Pixel();
或者它可能要复杂得多。检查您的图书馆的API,课堂笔记和示例代码,以了解您应该做什么。
解决NPE的关键点:
修改强>
在查看你的Pixel类时,似乎1)使用默认构造函数不会这样做,并且2)Pixel本身似乎没有意义,只有在它作为组件的Picture的上下文中才有意义。这也会向我建议你当前的变形方法可能是(强调可能)关闭。
我的猜测,请理解这是一个巨大的猜测,是你可能想要创建几个Picture对象,每个中间阶段一个,最后一个图片。然后你可以从每个图片中提取像素阵列并进行调整(线性?)。再次,这是一个愚蠢的疯狂的猜测。请谨慎使用此建议。
此外,我认为如果要进行线性变形,我不会嵌套for循环来进行变形。
答案 1 :(得分:0)
pixelObjNew
被初始化为null并且永远不会改变。所以pixelObjNew.setRed(redValue);
会抛出一个NPE。