我昨天使用BufferedImage Lib遇到了问题,我得到了一个
java.lang.ArrayIndexOutOfBoundsException:3
但仅限于图片“PNG”我从网上获取,但如果我在Paint中制作我自己的照片则一切正常。我试着查找问题,但不知道我错在哪里。
package grayandconvert;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.File;
import java.io.IOException;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
public class JavaCodeProject { // remain if needed Kim
private final String PATH = "C:\\New folder\\"; //
private final String graypath = PATH + "oZPX0bbg.png"; // filename for Grayscale pic
private final String imgpath = PATH + "oZPX0bb.png"; // filename for Orginal pic
private final String textpath =PATH + "filename.txt"; // filename for Output textfile
private final String imgtype = "png"; // image file type for Grascale "png" "jpg"
public static void main(String[] args)
{
JavaCodeProject main = new JavaCodeProject(); //new class for use of the metoth
main.grayscale();
main.convert();
}
public void convert()
{
try
{
BufferedImage image =ImageIO.read(new File(graypath)); // called the gray pic for image
int[] pixel; // int array named pixel
System.out.print(image.getHeight());
System.out.print(image.getWidth());
for (int y = 0; y < image.getHeight(); y++) // outer forloop to control Y axel image.getWidth
{
for (int x = 0; x < image.getWidth(); x++) //inner forloop to control X axel
{
pixel = image.getRaster().getPixel(x, y, new int[3]); // gets the RGB data from the buffer
if(pixel[0]< 255 && pixel[1]< 255 && pixel[2]< 255)
{
System.out.print(" Y");
writefile("Y");
}
else
{
System.out.print(" N");
writefile("N");
}
}
System.out.print(" L");
System.out.println("");
writefile("L");
}
System.out.print("S");
writefile("S");
}
catch (IOException e) // never used it but it needs to be here
{
}
}
public void writefile(String value)
{
String array = value; //named it array. i know right :P
File file = new File(textpath); //path for new file.txt
try
{
if (!file.exists()) // if file doesnt exists, then this will create it ;)
{
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile(),true);
try (BufferedWriter bw = new BufferedWriter(fw)) {
bw.write(array,0,array.length());
}
}
catch (IOException e) // if IO exceptions happens this outputs Stacktrace
{
}
}
public void grayscale()
{
BufferedImage img = null;
try
{
File f = new File(imgpath); //org pic
img = ImageIO.read(f);
}
catch(IOException e)
{
System.out.println(e);
}
for(int y = 0; y < img.getHeight(); y++)
{
for(int x = 0; x < img.getWidth(); x++)
{
int p = img.getRGB(x,y);
int a = (p>>24)&0xff;
int r = (p>>16)&0xff;
int g = (p>>8)&0xff;
int b = p&0xff;
//calculate average
int avg = (r+g+b)/3;
//replace RGB value with avg
p = (a<<24) | (avg<<16) | (avg<<8) | avg;
img.setRGB(x, y, p);
}
}
try
{
File f = new File(graypath); //gray pic
ImageIO.write(img,imgtype,f);
}
catch(IOException e)
{
System.out.println(e);
}
}
}
I get the error
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at java.awt.image.ComponentSampleModel.getPixel(ComponentSampleModel.java:750)
at java.awt.image.Raster.getPixel(Raster.java:1519)
at grayandconvert.JavaCodeProject.convert(JavaCodeProject.java:41)
at grayandconvert.JavaCodeProject.main(JavaCodeProject.java:23)
128128C:\Users\clipcomet\Desktop\JavaApplication10\nbproject\build-impl.xml:1051: The following error occurred while executing this line:
C:\Users\clipcomet\Desktop\JavaApplication10\nbproject\build-impl.xml:805: Java returned: 1
BUILD FAILED (total time: 1 second)
我刚刚开始编程,我知道即时通讯使用Lib我完全不知道但需要使用BufferedImage,忽略所有的错误代码我有人可以告诉我为什么我只在一些照片上得到错误
答案 0 :(得分:0)
在某些情况下,您获得异常的原因是,Raster.getPixel(x, y, pixel)
尝试将x,y处的像素的所有样本复制到pixel
数组中。如果你从网上下载随机图片,你无法控制你的光栅每像素有多少个样本,但是你将pixel
数组硬编码为3个元素。
从API doc(强调我的):
ArrayIndexOutOfBoundsException
- 如果坐标不在边界内,或如果iArray
太小而无法容纳输出。
最有可能的是,获得异常的图像有4个组件并且是RGBA(而Paint中的组件有3个组件,RGB)。您可能会通过创建一个更大的数组(即new int[4]
)来消除异常。
但是,解决问题的最佳方法是不要自己创建数组,而是将其留给getPixel
方法,如下所示:
int[] pixel = null;
for (y...) {
for (x...) {
pixel = raster.getPixel(x, y, pixel);
...
}
}
这也确保了分配只发生一次,这显然对性能有利。
也就是说,您仍需要处理随机图像可能没有每像素的预期采样数这一事实。如果您的输入为灰色或使用了颜色贴图(IndexColoModel
),那么它只会有一个样本(您的ArrayIndexOutOfBoundsExpcetion
和pixel[1]
数组会有pixel[2]
访问)。对于颜色映射的情况,样本值与您在屏幕上看到的RGB值无关(它只是查找表的索引)。
由于这些原因,您可能会发现使用BufferedImage.getRGB(x, y)
方法更简单,更直观,始终为您提供像素的ARGB值作为单个压缩的int样本,在sRGB色彩空间。